diff --git a/.gitignore b/.gitignore index a4fb5ca6f6..a6cbd8cb92 100644 --- a/.gitignore +++ b/.gitignore @@ -115,15 +115,6 @@ Release/ /libs/esl/fs_ivrd /libs/esl/testclient /libs/esl/testserver -/libs/freetdm/detect_dtmf -/libs/freetdm/detect_tones -/libs/freetdm/testanalog -/libs/freetdm/testapp -/libs/freetdm/testcid -/libs/freetdm/testpri -/libs/freetdm/testr2 -/libs/freetdm/testsangomaboost -/libs/freetdm/testtones /libs/fsg729-*-installer /libs/g729/ /libs/libcodec2/compile diff --git a/bootstrap.sh b/bootstrap.sh index fa7e10ad88..b19a522044 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -10,7 +10,7 @@ BGJOB=false VERBOSE=false BASEDIR=`pwd`; LIBDIR=${BASEDIR}/libs; -SUBDIRS="apr libzrtp iksemel libdingaling srtp freetdm unimrcp fs"; +SUBDIRS="apr libzrtp iksemel libdingaling srtp unimrcp fs"; while getopts 'jhd:v' o; do case "$o" in diff --git a/build/modules.conf.in b/build/modules.conf.in index 14ad5dd080..b38900047b 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -168,7 +168,7 @@ xml_int/mod_xml_cdr xml_int/mod_xml_rpc xml_int/mod_xml_scgi -#../../libs/freetdm/mod_freetdm +#mod_freetdm|https://github.com/freeswitch/freetdm.git -b master ## Experimental Modules (don't cry if they're broken) #../../contrib/mod/xml_int/mod_xml_odbc diff --git a/configure.ac b/configure.ac index 5ea8e3921e..c6a634eb95 100644 --- a/configure.ac +++ b/configure.ac @@ -2124,7 +2124,6 @@ if test "$use_system_aprutil" != "yes"; then fi AC_CONFIG_SUBDIRS([libs/iksemel]) AC_CONFIG_SUBDIRS([libs/libdingaling]) -AC_CONFIG_SUBDIRS([libs/freetdm]) AC_CONFIG_SUBDIRS([libs/unimrcp]) if test "x${enable_zrtp}" = "xyes"; then AC_CONFIG_SUBDIRS([libs/libzrtp]) diff --git a/libs/.gitignore b/libs/.gitignore index 392aaffdbd..5a83438d92 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -85,12 +85,6 @@ opal /esl/Release/ /flite-*/ /freeradius-client-*/ -/freetdm/build/compile -/freetdm/COPYING -/freetdm/INSTALL -/freetdm/Makefile.in -/freetdm/msvc/Debug/ -/freetdm/msvc/Release/ /iksemel/build/compile /iksemel/doc/Makefile /iksemel/doc/Makefile.in diff --git a/libs/freetdm/.gitignore b/libs/freetdm/.gitignore deleted file mode 100644 index da2caa7d87..0000000000 --- a/libs/freetdm/.gitignore +++ /dev/null @@ -1,39 +0,0 @@ -*.o -*.lo -*.so -*.a -*.orig -*.rej -*.log - -Makefile -config.* -configure -libtool -aclocal.m4 -build/libtool.m4 -build/ltoptions.m4 -build/ltsugar.m4 -build/ltversion.m4 -build/lt~obsolete.m4 - -testanalog -testapp -testboost -testcid -testpri -testr2 -testsangomaboost -testtones - -!/msvc/testanalog/ -!/msvc/testboost/ - -!/sample/boost/Makefile -!/sample/dso/Makefile - -freetdm.2010.sdf -/mod_freetdm/Win32/ -/msvc/Win32/ -/src/ftmod/*/Win32/ -/src/ftmod/*/x64/ diff --git a/libs/freetdm/.update b/libs/freetdm/.update deleted file mode 100644 index b537cc4f2d..0000000000 --- a/libs/freetdm/.update +++ /dev/null @@ -1 +0,0 @@ -Fri Feb 3 11:55:29 PST 2012 diff --git a/libs/freetdm/AUTHORS b/libs/freetdm/AUTHORS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libs/freetdm/CMakeLists.txt b/libs/freetdm/CMakeLists.txt deleted file mode 100644 index 24cbf7c9eb..0000000000 --- a/libs/freetdm/CMakeLists.txt +++ /dev/null @@ -1,244 +0,0 @@ -# -# cmake file that generate build files for freetdm. -# this automatically includes the tests and also -# mod_freetdm -# -# Arnaldo M Pereira -# -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(freetdm) - -ADD_SUBDIRECTORY(sample) -ADD_SUBDIRECTORY(mod_freetdm) - -# includes -SET(freetdm_INCLUDES - ${PROJECT_SOURCE_DIR}/src/include - ${PROJECT_SOURCE_DIR}/src/isdn/include - ${PROJECT_SOURCE_DIR}/src/include/private - ${PROJECT_SOURCE_DIR}/src/ftmod/ftmod_sangoma_boost -) -INCLUDE_DIRECTORIES(${freetdm_INCLUDES}) -LINK_DIRECTORIES(${freetdm_BINARY_DIR}) - -# optional includes -IF(DEFINED SNGSS7) - SET(freetdm_INCLUDES ${freetdm_INCLUDES} /usr/include/sng_ss7) -ENDIF(DEFINED SNGSS7) - -IF(DEFINED SNGISDN) - SET(freetdm_INCLUDES ${freetdm_INCLUDES} /usr/include/sng_isdn) -ENDIF(DEFINED SNGISDN) - -# definitions / CFLAGS -ADD_DEFINITIONS(-DFTDM_CONFIG_DIR="/FIXME" -DFTDM_MOD_DIR="/FIXME") -IF(DEFINED WIN32) - ADD_DEFINITIONS(-DFREETDM_EXPORTS -DTELETONE_EXPORTS -DMOD_EXPORTS -DDLL_EXPORTS) -ENDIF(DEFINED WIN32) -IF(DEFINED SNGISDN) - SET(freetdm_INCLUDES ${freetdm_INCLUDES} /usr/include/sng_isdn) -ENDIF(DEFINED SNGISDN) - -# lib sources -SET(freetdm_SOURCES - ${PROJECT_SOURCE_DIR}/src/hashtable.c - ${PROJECT_SOURCE_DIR}/src/hashtable_itr.c - ${PROJECT_SOURCE_DIR}/src/ftdm_io.c - ${PROJECT_SOURCE_DIR}/src/ftdm_queue.c - ${PROJECT_SOURCE_DIR}/src/ftdm_sched.c - ${PROJECT_SOURCE_DIR}/src/ftdm_call_utils.c - ${PROJECT_SOURCE_DIR}/src/ftdm_config.c - ${PROJECT_SOURCE_DIR}/src/ftdm_callerid.c - ${PROJECT_SOURCE_DIR}/src/fsk.c - ${PROJECT_SOURCE_DIR}/src/uart.c - ${PROJECT_SOURCE_DIR}/src/g711.c - ${PROJECT_SOURCE_DIR}/src/libteletone_detect.c - ${PROJECT_SOURCE_DIR}/src/libteletone_generate.c - ${PROJECT_SOURCE_DIR}/src/ftdm_buffer.c - ${PROJECT_SOURCE_DIR}/src/ftdm_threadmutex.c - ${PROJECT_SOURCE_DIR}/src/ftdm_dso.c - ${PROJECT_SOURCE_DIR}/src/ftdm_cpu_monitor.c -) - -# libfreetdm.so -ADD_LIBRARY(${PROJECT_NAME} SHARED ${freetdm_SOURCES}) - -IF(NOT DEFINED WIN32) - TARGET_LINK_LIBRARIES(${PROJECT_NAME} m pthread dl) -ENDIF(NOT DEFINED WIN32) - -REMOVE_DEFINITIONS(-DLL_EXPORTS) - -# tools & tests -IF(NOT DEFINED WIN32) - FOREACH(TOOL testtones testpri testr2 testapp testcid) - ADD_EXECUTABLE(${TOOL} ${PROJECT_SOURCE_DIR}/src/${TOOL}.c) - TARGET_LINK_LIBRARIES(${TOOL} -l${PROJECT_NAME}) - ADD_DEPENDENCIES(${TOOL} ${PROJECT_NAME}) - ENDFOREACH(TOOL) - - ADD_EXECUTABLE(detect_dtmf - ${PROJECT_SOURCE_DIR}/src/detect_dtmf.c - ${PROJECT_SOURCE_DIR}/src/libteletone_detect.c - ) - TARGET_LINK_LIBRARIES(detect_dtmf ${PROJECT_NAME}) - ADD_DEPENDENCIES(detect_dtmf ${PROJECT_NAME}) - - ADD_EXECUTABLE(detect_tones - ${PROJECT_SOURCE_DIR}/src/detect_tones.c - ${PROJECT_SOURCE_DIR}/src/libteletone_detect.c - ) - TARGET_LINK_LIBRARIES(detect_tones ${PROJECT_NAME}) - ADD_DEPENDENCIES(detect_tones ${PROJECT_NAME}) - - ADD_EXECUTABLE(testanalog - ${PROJECT_SOURCE_DIR}/src/testanalog.c - ) - TARGET_LINK_LIBRARIES(testanalog -l${PROJECT_NAME}) - ADD_DEPENDENCIES(testanalog ${PROJECT_NAME}) - - # optional tests/tools - IF(HAVE_SCTP) - ADD_EXECUTABLE(testboost src/testboost.c) - TARGET_LINK_LIBRARIES(testboost ${PROJECT_NAME}) - ENDIF(HAVE_SCTP) -ELSE(NOT DEFINED WIN32) - MESSAGE(WARNING "Not building tools/tests on WIN32 yet.") -ENDIF(NOT DEFINED WIN32) - -# -# ftmod modules -# -SET(ftmod_DIR ${PROJECT_SOURCE_DIR}/src/ftmod) - -IF(DEFINED WIN32) - SET(ftmod_ADDITIONAL_SOURCES - ${PROJECT_SOURCE_DIR}/src/ftdm_io.c - ${PROJECT_SOURCE_DIR}/src/ftdm_config.c - ${PROJECT_SOURCE_DIR}/src/ftdm_queue.c - ${PROJECT_SOURCE_DIR}/src/g711.c - ) - SET(module_list skel analog analog_em) -ELSE(DEFINED WIN32) - SET(module_list skel analog analog_em zt) -ENDIF(DEFINED WIN32) - -# build default modules -FOREACH(module ${module_list}) - ADD_LIBRARY(ftmod_${module} MODULE ${ftmod_DIR}/ftmod_${module}/ftmod_${module}.c ${ftmod_ADDITIONAL_SOURCES}) - TARGET_LINK_LIBRARIES(ftmod_${module} ${PROJECT_NAME}) -ENDFOREACH(module) - -# build isdn ftmod -IF(DEFINED BUILD_FTMOD_ISDN) - SET(ftmod_isdn_SOURCES - ${PROJECT_SOURCE_DIR}/src/isdn/EuroISDNStateNT.c - ${PROJECT_SOURCE_DIR}/src/isdn/EuroISDNStateTE.c - ${PROJECT_SOURCE_DIR}/src/isdn/mfifo.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q921.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q931api.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q931.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q931ie.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q931mes.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q931StateNT.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q931StateTE.c - ${PROJECT_SOURCE_DIR}/src/isdn/nationalmes.c - ${PROJECT_SOURCE_DIR}/src/isdn/nationalStateNT.c - ${PROJECT_SOURCE_DIR}/src/isdn/nationalStateTE.c - ${PROJECT_SOURCE_DIR}/src/isdn/DMSmes.c - ${PROJECT_SOURCE_DIR}/src/isdn/DMSStateNT.c - ${PROJECT_SOURCE_DIR}/src/isdn/DMSStateTE.c - ${PROJECT_SOURCE_DIR}/src/isdn/5ESSmes.c - ${PROJECT_SOURCE_DIR}/src/isdn/5ESSStateNT.c - ${PROJECT_SOURCE_DIR}/src/isdn/5ESSStateTE.c - ${PROJECT_SOURCE_DIR}/src/isdn/Q932mes.c - ${ftmod_DIR}/ftmod_isdn/ftmod_isdn.c - ) - IF(NOT DEFINED WIN32) - ADD_DEFINITIONS(-D_GNU_SOURCE) - ENDIF(NOT DEFINED WIN32) - ADD_LIBRARY(ftmod_isdn MODULE ${ftmod_isdn_SOURCES}) - TARGET_LINK_LIBRARIES(ftmod_isdn ${PROJECT_NAME}) -ENDIF(DEFINED BUILD_FTMOD_ISDN) - -# from now on, optionals -IF(DEFINED LIBSANGOMA) - ADD_LIBRARY(ftmod_wanpipe MODULE ${ftmod_DIR}/ftmod_wanpipe/ftmod_wanpipe.c) - IF(DEFINED WIN32) - MESSAGE(WARNING "FIXME: look for wanpipe headers on win32") - ELSE(DEFINED WIN32) - ADD_DEFINITIONS(-D__LINUX__) - INCLUDE_DIRECTORIES(/usr/include/wanpipe) - ENDIF(DEFINED WIN32) - TARGET_LINK_LIBRARIES(ftmod_wanpipe sangoma ${PROJECT_NAME}) -ENDIF(DEFINED LIBSANGOMA) - -IF(DEFINED HAVE_SCTP) - ADD_LIBRARY(ftmod_sangoma_boost MODULE - ${ftmod_DIR}/ftmod_sangoma_boost/sangoma_boost_client.c - ${ftmod_DIR}/ftmod_sangoma_boost/ftmod_sangoma_boost.c - ) - TARGET_LINK_LIBRARIES(ftmod_sangoma_boost ${PROJECT_NAME}) -ENDIF(DEFINED HAVE_SCTP) - -IF(DEFINED LIBPRI) - ADD_LIBRARY(ftmod_libpri MODULE - ${ftmod_DIR}/ftmod_libpri/libpri_client.c - ${ftmod_DIR}/ftmod_libpri/ftmod_libpri.c - ) - TARGET_LINK_LIBRARIES(ftmod_libpri ${PROJECT_NAME}) -ENDIF(DEFINED LIBPRI) - -IF(DEFINED PRITAP) - ADD_LIBRARY(ftmod_pritap MODULE - ${ftmod_DIR}/ftmod_pritap/pritap_client.c - ${ftmod_DIR}/ftmod_pritap/ftmod_pritap.c - ) - TARGET_LINK_LIBRARIES(ftmod_pritap ${PROJECT_NAME} pri) -ENDIF(DEFINED PRITAP) - -IF(DEFINED SNGSS7) - ADD_LIBRARY(ftmod_sangoma_ss7 MODULE - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c - ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c - ) - IF(NOT DEFINED WIN32) - ADD_DEFINITIONS(-D_GNU_SOURCE) - ENDIF(NOT DEFINED WIN32) - TARGET_LINK_LIBRARIES(ftmod_sangoma_ss7 ${PROJECT_NAME} sng_ss7) -ENDIF(DEFINED SNGSS7) - -IF(DEFINED SNGISDN) - ADD_LIBRARY(ftmod_sangoma_isdn MODULE - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c - ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c - ) - IF(NOT DEFINED WIN32) - ADD_DEFINITIONS(-D_GNU_SOURCE) - ENDIF(NOT DEFINED WIN32) - TARGET_LINK_LIBRARIES(ftmod_sangoma_isdn ${PROJECT_NAME} sng_isdn) -ENDIF(DEFINED SNGISDN) - -IF(DEFINED OPENR2) - ADD_LIBRARY(ftmod_r2 MODULE ${ftmod_DIR}/ftmod_r2/ftmod_r2.c) - TARGET_LINK_LIBRARIES(ftmod_r2 ${PROJECT_NAME} openr2) -ENDIF(DEFINED OPENR2) diff --git a/libs/freetdm/ChangeLog b/libs/freetdm/ChangeLog deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am deleted file mode 100644 index f6211e58e8..0000000000 --- a/libs/freetdm/Makefile.am +++ /dev/null @@ -1,290 +0,0 @@ -# Copyright (c) 2007-2014, Anthony Minessale II -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# * Neither the name of the original author; nor the names of any contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -ACLOCAL_AMFLAGS = -I build -AUTOMAKE_OPTIONS = foreign - -SRC = src - -moddir = @modinstdir@ -libdir = @libdir@ -library_includedir = $(prefix)/include - -INCS = -I$(FT_SRCDIR)/$(SRC)/include -I$(FT_SRCDIR)/$(SRC)/include/private - -# we needed to separate CFLAGS in FTDM_COMPAT_CFLAGS and FTDM_CFLAGS due to -c99 which causes problems with wanpipe headers -FTDM_COMPAT_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_COMPAT_CFLAGS@ @DEFS@ -FTDM_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_CFLAGS@ @DEFS@ -COMPILE = $(CC) $(FTDM_CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(COMPILE) -LINK = $(LIBTOOL) --mode=link --tag=CC $(CC) $(FTDM_CFLAGS) $(LDFLAGS) -o $@ - - -# -# GNU pkgconfig file -# -EXTRA_DIST = freetdm.pc.in - -pkgconfigdir = @pkgconfigdir@ -pkgconfig_DATA = freetdm.pc - - -# -# libfreetdm -# -libfreetdm_la_SOURCES = \ - $(SRC)/hashtable.c \ - $(SRC)/hashtable_itr.c \ - $(SRC)/ftdm_io.c \ - $(SRC)/ftdm_state.c \ - $(SRC)/ftdm_queue.c \ - $(SRC)/ftdm_sched.c \ - $(SRC)/ftdm_call_utils.c \ - $(SRC)/ftdm_variables.c \ - $(SRC)/ftdm_config.c \ - $(SRC)/ftdm_callerid.c \ - $(SRC)/fsk.c \ - $(SRC)/uart.c \ - $(SRC)/g711.c \ - $(SRC)/libteletone_detect.c \ - $(SRC)/libteletone_generate.c \ - $(SRC)/ftdm_buffer.c \ - $(SRC)/ftdm_threadmutex.c \ - $(SRC)/ftdm_dso.c \ - $(SRC)/ftdm_cpu_monitor.c \ - $(SRC)/ftdm_backtrace.c - -library_include_HEADERS = \ - $(SRC)/include/freetdm.h \ - $(SRC)/include/ftdm_declare.h \ - $(SRC)/include/ftdm_threadmutex.h \ - $(SRC)/include/ftdm_os.h \ - $(SRC)/include/ftdm_call_utils.h \ - $(SRC)/include/ftdm_dso.h - -lib_LTLIBRARIES = libfreetdm.la -libfreetdm_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -libfreetdm_la_LDFLAGS = -version-info 1:0:0 $(AM_LDFLAGS) -libfreetdm_la_LIBADD = $(LIBS) - -core: libfreetdm.la -core-install: install-libLTLIBRARIES - -# -# tools & test programs -# -noinst_PROGRAMS = testtones detect_tones detect_dtmf testpri testr2 testanalog testapp testcid - -testapp_SOURCES = $(SRC)/testapp.c -testapp_LDADD = libfreetdm.la -testapp_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -testcid_SOURCES = $(SRC)/testcid.c -testcid_LDADD = libfreetdm.la -testcid_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -testtones_SOURCES = $(SRC)/testtones.c -testtones_LDADD = libfreetdm.la -testtones_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -detect_tones_SOURCES = $(SRC)/detect_tones.c -detect_tones_LDADD = libfreetdm.la -detect_tones_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -detect_dtmf_SOURCES = $(SRC)/detect_dtmf.c -detect_dtmf_LDADD = libfreetdm.la -detect_dtmf_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -#testisdn_SOURCES = $(SRC)/testisdn.c -#testisdn_LDADD = libfreetdm.la -#testisdn_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -testpri_SOURCES = $(SRC)/testpri.c -testpri_LDADD = libfreetdm.la -testpri_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -testr2_SOURCES = $(SRC)/testr2.c -testr2_LDADD = libfreetdm.la -testr2_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -testanalog_SOURCES = $(SRC)/testanalog.c -testanalog_LDADD = libfreetdm.la -testanalog_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) - -# -# ftmod modules -# -mod_LTLIBRARIES = ftmod_zt.la ftmod_skel.la ftmod_analog.la ftmod_analog_em.la - -ftmod_zt_la_SOURCES = $(SRC)/ftmod/ftmod_zt/ftmod_zt.c -ftmod_zt_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -ftmod_zt_la_LDFLAGS = -shared -module -avoid-version -ftmod_zt_la_LIBADD = libfreetdm.la - -ftmod_skel_la_SOURCES = $(SRC)/ftmod/ftmod_skel/ftmod_skel.c -ftmod_skel_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -ftmod_skel_la_LDFLAGS = -shared -module -avoid-version -ftmod_skel_la_LIBADD = libfreetdm.la - -ftmod_analog_la_SOURCES = $(SRC)/ftmod/ftmod_analog/ftmod_analog.c -ftmod_analog_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -ftmod_analog_la_LDFLAGS = -shared -module -avoid-version -ftmod_analog_la_LIBADD = libfreetdm.la - -ftmod_analog_em_la_SOURCES = $(SRC)/ftmod/ftmod_analog_em/ftmod_analog_em.c -ftmod_analog_em_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -ftmod_analog_em_la_LDFLAGS = -shared -module -avoid-version -ftmod_analog_em_la_LIBADD = libfreetdm.la - -if HAVE_LIBSANGOMA -mod_LTLIBRARIES += ftmod_wanpipe.la -ftmod_wanpipe_la_SOURCES = $(SRC)/ftmod/ftmod_wanpipe/ftmod_wanpipe.c -# some structures within Wanpipe drivers are not c99 compatible, so we need to compile ftmod_wanpipe -# without c99 flags, use FTDM_COMPAT_CFLAGS instead -ftmod_wanpipe_la_CFLAGS = $(FTDM_COMPAT_CFLAGS) $(AM_CFLAGS) -D__LINUX__ -I/usr/include/wanpipe -ftmod_wanpipe_la_LDFLAGS = -shared -module -avoid-version -ftmod_wanpipe_la_LIBADD = libfreetdm.la -lsangoma -endif - -if HAVE_LIBISDN -mod_LTLIBRARIES += ftmod_isdn.la -ftmod_isdn_la_SOURCES = $(SRC)/ftmod/ftmod_isdn/ftmod_isdn.c -ftmod_isdn_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -D_GNU_SOURCE $(LIBISDN_CPPFLAGS) $(PCAP_CPPFLAGS) -ftmod_isdn_la_LDFLAGS = -shared -module -avoid-version $(LIBISDN_LDFLAGS) $(PCAP_LDFLAGS) -ftmod_isdn_la_LIBADD = libfreetdm.la $(LIBISDN_LIBS) $(PCAP_LIBS) -endif - -if HAVE_LIBPRI -mod_LTLIBRARIES += ftmod_libpri.la -ftmod_libpri_la_SOURCES = $(SRC)/ftmod/ftmod_libpri/ftmod_libpri.c $(SRC)/ftmod/ftmod_libpri/lpwrap_pri.c -ftmod_libpri_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) $(LIBPRI_CPPFLAGS) -ftmod_libpri_la_LDFLAGS = -shared -module -avoid-version $(LIBPRI_LDFLAGS) -ftmod_libpri_la_LIBADD = libfreetdm.la $(LIBPRI_LIBS) -endif - -if HAVE_PRITAP -mod_LTLIBRARIES += ftmod_pritap.la -ftmod_pritap_la_SOURCES = $(SRC)/ftmod/ftmod_pritap/ftmod_pritap.c -ftmod_pritap_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -ftmod_pritap_la_LDFLAGS = -shared -module -avoid-version -ftmod_pritap_la_LIBADD = libfreetdm.la -lpri -endif - -if HAVE_SNG_SS7 -mod_LTLIBRARIES += ftmod_sangoma_ss7.la -ftmod_sangoma_ss7_la_SOURCES = \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c - -ftmod_sangoma_ss7_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -D_GNU_SOURCE -ftmod_sangoma_ss7_la_LDFLAGS = -shared -module -avoid-version -ftmod_sangoma_ss7_la_LIBADD = libfreetdm.la -lsng_ss7 -endif - -if HAVE_SNG_ISDN -mod_LTLIBRARIES += ftmod_sangoma_isdn.la -ftmod_sangoma_isdn_la_SOURCES = \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_transfer.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c \ - $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c - -ftmod_sangoma_isdn_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -D_GNU_SOURCE -ftmod_sangoma_isdn_la_LDFLAGS = -shared -module -avoid-version -ftmod_sangoma_isdn_la_LIBADD = libfreetdm.la -lsng_isdn -endif - -if HAVE_OPENR2 -mod_LTLIBRARIES += ftmod_r2.la -ftmod_r2_la_SOURCES = $(SRC)/ftmod/ftmod_r2/ftmod_r2.c $(SRC)/ftmod/ftmod_r2/ftmod_r2_io_mf_lib.c -ftmod_r2_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -ftmod_r2_la_LDFLAGS = -shared -module -avoid-version -ftmod_r2_la_LIBADD = libfreetdm.la -lopenr2 -endif - -if HAVE_WAT -mod_LTLIBRARIES += ftmod_gsm.la -ftmod_gsm_la_SOURCES = $(SRC)/ftmod/ftmod_gsm/ftmod_gsm.c -ftmod_gsm_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -ftmod_gsm_la_LDFLAGS = -shared -module -avoid-version -ftmod_gsm_la_LIBADD = libfreetdm.la -lwat -endif - -if HAVE_MISDN -mod_LTLIBRARIES += ftmod_misdn.la -ftmod_misdn_la_SOURCES = $(SRC)/ftmod/ftmod_misdn/ftmod_misdn.c -ftmod_misdn_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) $(MISDN_CFLAGS) -D_GNU_SOURCE -ftmod_misdn_la_LDFLAGS = -shared -module -avoid-version -ftmod_misdn_la_LIBADD = libfreetdm.la -endif - -dox doxygen: - doxygen $(FT_SRCDIR)/docs/Doxygen.conf - -mod_freetdm/mod_freetdm.so: libfreetdm.la mod_freetdm/mod_freetdm.c - $(MAKE) -C mod_freetdm - -mod_freetdm: mod_freetdm/mod_freetdm.so - -mod_freetdm-install: mod_freetdm - $(MAKE) -C mod_freetdm install - -mod_freetdm-clean: - @if [ -f mod_freetdm/mod_freetdm.so ] ; then \ - $(MAKE) -C mod_freetdm clean ; \ - fi - -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(prefix) - $(mkinstalldirs) $(DESTDIR)@confdir@ - @[ -f "$(DESTDIR)@confdir@/freetdm.conf" ] || ( cp conf/*.conf $(DESTDIR)@confdir@) - @echo FreeTDM Installed diff --git a/libs/freetdm/NEWS b/libs/freetdm/NEWS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libs/freetdm/README b/libs/freetdm/README deleted file mode 100644 index 4ca13d19c9..0000000000 --- a/libs/freetdm/README +++ /dev/null @@ -1,3 +0,0 @@ -FreeTDM -http://wiki.freeswitch.org/wiki/FreeTDM - diff --git a/libs/freetdm/TODO b/libs/freetdm/TODO deleted file mode 100644 index 6b4cf71f5f..0000000000 --- a/libs/freetdm/TODO +++ /dev/null @@ -1,22 +0,0 @@ -== Interface inconsistency == -- enum_id member of ftdm_event_t is inconsistent. Most of the time is just for OOB events, the only other - type of event as of now is FTDM_EVENT_DTMF and is not using the enum_id member. I think we can get rid - of the FTDM_EVENT_DTMF and create ftdm_dtmf_event_t type instead of reusing ftdm_event_t - then ftdm_event_t would be renamed to ftdm_oob_event_t and the enum_id renamed to type, then ftdm_span_next_event() - will only return OOB events - -- Deprecate last_error members. - It requires a lot of discipline to set the last_error string for every failure. - It does not add much value to the user either, most of the errors are criptic and - cannot be shown to end users, we already provide extensive logging for problem - troubleshooting. - -- Implement threaded IO. - Currently IO modules only work on-demand, where the user (ie, FreeSWITCH) drives the read/write - of media. If the user stops reading, some functions are not possible - (DTMF detection or Hangup tone detection). It would be useful to implement a FreeTDM mode - where the media is driven by a group of threads that are always reading (and possibly writing) - then when the user does ftdm_channel_read(), the media would be read from the buffers filled - by the media thread and not from the underlying IO device, this gives a chance to FreeTDM to - still perform hangup detection or other media services even if the application is not reading. - diff --git a/libs/freetdm/acinclude.m4 b/libs/freetdm/acinclude.m4 deleted file mode 100644 index 097278b6ef..0000000000 --- a/libs/freetdm/acinclude.m4 +++ /dev/null @@ -1,2 +0,0 @@ -m4_include([build/ax_compiler_vendor.m4]) -m4_include([build/libpcap.m4]) diff --git a/libs/freetdm/bootstrap b/libs/freetdm/bootstrap deleted file mode 100755 index 247d396da5..0000000000 --- a/libs/freetdm/bootstrap +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -autoheader -libtoolize --force --copy -aclocal -automake -f --copy --add-missing -autoconf diff --git a/libs/freetdm/build/ax_compiler_vendor.m4 b/libs/freetdm/build/ax_compiler_vendor.m4 deleted file mode 100644 index a24a58da0f..0000000000 --- a/libs/freetdm/build/ax_compiler_vendor.m4 +++ /dev/null @@ -1,15 +0,0 @@ -AC_DEFUN([AX_COMPILER_VENDOR], -[ -AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, - [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown - # note: don't check for gcc first since some other compilers define __GNUC__ - for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do - vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ -#if !($vencpp) - thisisanerror; -#endif -])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break]) - done - ]) -]) diff --git a/libs/freetdm/build/libpcap.m4 b/libs/freetdm/build/libpcap.m4 deleted file mode 100644 index ea7581e69b..0000000000 --- a/libs/freetdm/build/libpcap.m4 +++ /dev/null @@ -1,150 +0,0 @@ -dnl libpcap.m4--PCAP libraries and includes -dnl Derrick Brashear -dnl from KTH krb and Arla -dnl $Id: libpcap.m4,v 1.4 2006/01/20 20:21:09 snsimon Exp $ -dnl 2010/10/31 (stkn): -dnl rename: PCAP_INC_FLAGS -> PCAP_CPPFLAGS -dnl rename: PCAP_LIB_FLAGS -> PCAP_LDFLAGS (-L flags only) -dnl add: PCAP_LIBS (libs only) - -AC_DEFUN([PCAP_INC_WHERE1], [ -ac_cv_found_pcap_inc=no -if test -f "$1/pcap.h" ; then - ac_cv_found_pcap_inc=yes -fi -]) - -AC_DEFUN([PCAP_INC_WHERE], [ - for i in $1; do - AC_MSG_CHECKING(for pcap header in $i) - PCAP_INC_WHERE1($i) - if test "$ac_cv_found_pcap_inc" = "yes"; then - ac_cv_pcap_where_inc=$i - AC_MSG_RESULT(found) - break - else - AC_MSG_RESULT(no found) - fi - done -]) - -AC_DEFUN([PCAP_LIB_WHERE1], [ -saved_LIBS=$LIBS -LIBS="$saved_LIBS -L$1 -lpcap" -AC_TRY_LINK(, -[pcap_lookupdev("");], -[ac_cv_found_pcap_lib=yes], -ac_cv_found_pcap_lib=no) -LIBS=$saved_LIBS -]) - -AC_DEFUN([TEST_LIBPATH], [ -changequote(<<, >>) -define(<>, translit(ac_cv_found_$2_lib, <<- *>>, <<__p>>)) -changequote([, ]) -if test "$AC_CV_FOUND" = "yes"; then - if test \! -r "$1/lib$2.a" -a \! -r "$1/lib$2.so" -a \! -r "$1/lib$2.sl" -a \! -r "$1/lib$2.dylib"; then - AC_CV_FOUND=no - fi -fi -]) - - -AC_DEFUN([PCAP_LIB_WHERE], [ - for i in $1; do - AC_MSG_CHECKING(for pcap library in $i) - PCAP_LIB_WHERE1($i) - TEST_LIBPATH($i, pcap) - if test "$ac_cv_found_pcap_lib" = "yes" ; then - ac_cv_pcap_where_lib=$i - AC_MSG_RESULT(found) - break - else - AC_MSG_RESULT(no found) - fi - done -]) - -AC_DEFUN([FIND_LIB_SUBDIR], -[dnl -AC_ARG_WITH([lib-subdir], AC_HELP_STRING([--with-lib-subdir=DIR],[Find libraries in DIR instead of lib])) -AC_CHECK_SIZEOF(long) -AC_CACHE_CHECK([what directory libraries are found in], [ac_cv_cmu_lib_subdir], -[test "X$with_lib_subdir" = "Xyes" && with_lib_subdir= -test "X$with_lib_subdir" = "Xno" && with_lib_subdir= - if test "X$with_lib_subdir" = "X" ; then - ac_cv_cmu_lib_subdir=lib - if test $ac_cv_sizeof_long -eq 4 ; then - test -d /usr/lib32 && ac_cv_cmu_lib_subdir=lib32 - test -r /usr/lib/libpcap.so && ac_cv_cmu_lib_subdir=lib - fi - if test $ac_cv_sizeof_long -eq 8 ; then - test -d /usr/lib64 && ac_cv_cmu_lib_subdir=lib64 - fi - else - ac_cv_cmu_lib_subdir=$with_lib_subdir - fi]) - AC_SUBST(LIB_SUBDIR, $ac_cv_cmu_lib_subdir) - ]) - - -AC_DEFUN([AX_LIB_PCAP], [ -AC_REQUIRE([FIND_LIB_SUBDIR]) -AC_ARG_WITH(pcap, - [ --with-pcap=PREFIX Compile with PCAP support], - [if test "X$with_pcap" = "X"; then - with_pcap=yes - fi]) -AC_ARG_WITH(pcap-lib, - [ --with-pcap-lib=dir use pcap libraries in dir], - [if test "$withval" = "yes" -o "$withval" = "no"; then - AC_MSG_ERROR([No argument for --with-pcap-lib]) - fi]) -AC_ARG_WITH(pcap-include, - [ --with-pcap-include=dir use pcap headers in dir], - [if test "$withval" = "yes" -o "$withval" = "no"; then - AC_MSG_ERROR([No argument for --with-pcap-include]) - fi]) - - if test "X$with_pcap" != "X"; then - if test "$with_pcap" != "yes"; then - ac_cv_pcap_where_lib=$with_pcap - ac_cv_pcap_where_inc=$with_pcap/include - fi - fi - - if test "X$with_pcap_lib" != "X"; then - ac_cv_pcap_where_lib=$with_pcap_lib - fi - if test "X$ac_cv_pcap_where_lib" = "X"; then - PCAP_LIB_WHERE(/usr/$LIB_SUBDIR /usr/local/$LIB_SUBDIR) - fi - - if test "X$with_pcap_include" != "X"; then - ac_cv_pcap_where_inc=$with_pcap_include - fi - if test "X$ac_cv_pcap_where_inc" = "X"; then - PCAP_INC_WHERE(/usr/ng/include /usr/include /usr/local/include) - fi - - AC_MSG_CHECKING(whether to include pcap) - if test "X$ac_cv_pcap_where_lib" != "X" -a "X$ac_cv_pcap_where_inc" != "X"; then - ac_cv_found_pcap=yes - AC_MSG_RESULT(yes) - PCAP_INC_DIR=$ac_cv_pcap_where_inc - PCAP_LIB_DIR=$ac_cv_pcap_where_lib - PCAP_CPPFLAGS="-I${PCAP_INC_DIR}" - PCAP_LDFLAGS="-L${PCAP_LIB_DIR}" - PCAP_LIBS="-lpcap" - AC_SUBST(PCAP_INC_DIR) - AC_SUBST(PCAP_LIB_DIR) - AC_SUBST(PCAP_CPPFLAGS) - AC_SUBST(PCAP_LDFLAGS) - AC_SUBST(PCAP_LIBS) - AC_DEFINE([HAVE_LIBPCAP],[1],[libpcap]) - else - ac_cv_found_pcap=no - AC_MSG_RESULT(no) - fi - ]) - diff --git a/libs/freetdm/conf/freetdm.conf b/libs/freetdm/conf/freetdm.conf deleted file mode 100644 index 0d53992979..0000000000 --- a/libs/freetdm/conf/freetdm.conf +++ /dev/null @@ -1,82 +0,0 @@ -; !! THIS IS A SAMPLE CONFIGURATION ONLY !! - -; refer to http://wiki.freeswitch.org/wiki/FreeTDM for further documentation - -[general] -; whether to launch a thread for CPU usage monitoring -cpu_monitor => no - -; How often (in milliseconds) monitor CPU usage -cpu_monitoring_interval => 1000 - -; At what CPU percentage raise a CPU alarm -cpu_set_alarm_threshold => 80 - -; At what CPU percentage stop the CPU alarm -cpu_clear_alarm_threshold => 70 - -; Which action to take when the CPU alarm is raised -; it can be warn and/or reject calls -; cpu_alarm_action => warn,reject -cpu_alarm_action => warn - -; Where to dump DTMF debug files (see per span debugdtmf=yes option) -debugdtmf_directory=/full/path/to/dtmf/directory - -; spans are defined with [span ] -; the span type can either be zt, wanpipe or pika -; the span name can be any unique string -[span wanpipe myWanpipe] - -; valid trunk types are: FXO, FXS, EM, E1, T1, J1, BRI, BRI_PTMP -trunk_type => FXS - -; add FXS channels from 3 to 4 at wanpipe span 1 to this freetdm span -fxs-channel => 1:3-4 - -; IO stats. Defaults to yes, you can print the stats with ftdm iostats print -; This feature depends on the span IO type, currently only Wanpipe spans support it -; This may cause a warning to be printed once in a while if audio is not provided fast enough -; and causes the driver to transmit an idle frame (when there is no data provided by the application) -iostats => yes - -[span wanpipe myWanpipe2] -trunk_type => FXO -; This number will be used as DNIS for FXO devices -fxo-channel => 1:1-2 - -[span zt myZaptelSpan] -number => 9999 -fxs-channel => 1 - -[span zt mySecondZaptelSpan] -; This number will be used as DNIS for FXO devices -number => 2 -fxo-channel => 3 - -; MFC-R2 typical span configuration - -; MFC-R2 with wanpipe (Sangoma) -[span wanpipe myWanpipeSpan] -trunk_type => E1 -cas-channel => 1-15:1101 -cas-channel => 17-31:1101 - -; MFC-R2 with Zaptel/DAHDI -[span zt myWanpipeSpan] -trunk_type => E1 -cas-channel => 1-15:1101 -cas-channel => 17-31:1101 - -; generic channel parameters -; this parameters are accepted by any type of span/channel -; remember that for generic channel parameters only channels -; below the parameter within the span will be affected - -; Channel audio gain -; rxgain => 0.0 -; txgain => 0.0 - -; Whether to perform media dumps for DTMF debugging -; debugdtmf => yes - diff --git a/libs/freetdm/conf/freetdm.conf.xml b/libs/freetdm/conf/freetdm.conf.xml deleted file mode 100644 index 0b006dc704..0000000000 --- a/libs/freetdm/conf/freetdm.conf.xml +++ /dev/null @@ -1,633 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/conf/pika.conf b/libs/freetdm/conf/pika.conf deleted file mode 100644 index 01629fd08e..0000000000 --- a/libs/freetdm/conf/pika.conf +++ /dev/null @@ -1,43 +0,0 @@ -; you dont need this file unless you use PIKA boards - -; each category is a config profile -; to apply the profile append it to a channel def in -; freetdm.conf with @ -; e.g. -; [span pika] -; name => pika -; number => pika -; fxs-channel => 1:0:1-12@default - -[default] -; region is na or eu -;region => na -;rx-gain => 0.00 -;rx-agc-enabled => false -;rx-agc-targetPower => -15.00 -;rx-agc-minGain => -6.00 -;rx-agc-maxGain => 18.00 -;rx-agc-attackRate => 170 -;rx-agc-decayRate => 750 -;rx-agc-speechThreshold => -36.00 -;rx-vad-enabled => false -;rx-vad-activationThreshold => -40.00 -;rx-vad-activationDebounceTime => 72 -;rx-vad-deactivationThreshold => -40.00 -;rx-vad-deactivationDebounceTime => 984 -;rx-vad-preSpeechBufferSize => 240 -;tx-gain => 0.00 -;tx-agc-enabled => true -;tx-agc-targetPower => -15.00 -;tx-agc-minGain => -6.00 -;tx-agc-maxGain => 18.00 -;tx-agc-attackRate => 170 -;tx-agc-decayRate => 750 -;tx-agc-speechThreshold => -36.00 -;ec-enabled => false -;ec-doubleTalkerThreshold => -6.00 -;ec-speechPresentThreshold => -40.00 -;ec-echoSuppressionThreshold => -18.00 -;ec-echoSuppressionEnabled => true -;ec-comfortNoiseEnabled => true -;ec-adaptationModeEnabled => true diff --git a/libs/freetdm/conf/tones.conf b/libs/freetdm/conf/tones.conf deleted file mode 100644 index 9bb0b43e92..0000000000 --- a/libs/freetdm/conf/tones.conf +++ /dev/null @@ -1,142 +0,0 @@ -[us] -generate-dial => v=-7;%(1000,0,350,440) -detect-dial => 350,440 - -generate-ring => v=-7;%(2000,4000,440,480) -detect-ring => 440,480 - -generate-busy => v=-7;%(500,500,480,620) -detect-busy => 480,620 - -generate-attn => v=0;%(100,100,1400,2060,2450,2600) -detect-attn => 1400,2060,2450,2600 - -generate-callwaiting-sas => v=0;%(300,0,440) -detect-callwaiting-sas => 440 - -generate-callwaiting-cas => v=0;%(80,0,2750,2130) -detect-callwaiting-cas => 2750,2130 - -detect-fail1 => 913.8 -detect-fail2 => 1370.6 -detect-fail3 => 1776.7 - - -[sg] -generate-dial => v=-7;%(1000,0,425) -detect-dial => 425 - -generate-ring => v=-7;%(2000,4000,425) -detect-ring => 425 - -generate-busy => v=-7;%(750,750,425) -detect-busy => 425 - -generate-attn => v=0;%(100,100,1400,2060,2450,2600) -detect-attn => 1400,2060,2450,2600 - -generate-callwaiting-sas => v=0;%(300,0,440) -detect-callwaiting-sas => 440 - -generate-callwaiting-cas => v=0;%(80,0,2750,2130) -detect-callwaiting-cas => 2750,2130 - -detect-fail1 => 913.8 -detect-fail2 => 1370.6 -detect-fail3 => 1776.7 - - -[ru] -generate-dial => v=-7;%(1000,425) -detect-dial => 0 - -generate-ring => v=-7;%(800,5000,425,0) -detect-ring => 425,0 - -generate-busy => v=-7;%(350,350,425,0) -detect-busy => 425,0 - -generate-attn => v=0;%(100,100,1400,2060,2450,2600) -detect-attn => 1400,2060,2450,2600 - -generate-callwaiting-sas => v=0;%(300,0,440) -detect-callwaiting-sas => 440,480 - -generate-callwaiting-cas => v=0;%(80,0,2750,2130) -detect-callwaiting-cas => 2750,2130 - -detect-fail1 => 913.8 -detect-fail2 => 1370.6 -detect-fail3 => 1776.7 - - -[in] -generate-dial => v=-7;%(1000,0,375,425) -detect-dial => 375,425 - -generate-ring => v=-7;%(2000,4000,440,480) -detect-ring => 440,480 - -generate-busy => v=-7;%(500,500,480,620) -detect-busy => 480,620 - -generate-attn => v=0;%(100,100,1400,2060,2450,2600) -detect-attn => 1400,2060,2450,2600 - -generate-callwaiting-sas => v=0;%(300,0,440) -detect-callwaiting-sas => 440 - -generate-callwaiting-cas => v=0;%(80,0,2750,2130) -detect-callwaiting-cas => 2750,2130 - -detect-fail1 => 913.8 -detect-fail2 => 1370.6 -detect-fail3 => 776.7 - - -[th] -generate-dial => v=-7;%(1000,0,400,400) -detect-dial => 400,400 - -generate-ring => v=-7;%(2000,4000,400,400) -detect-ring => 400,400 - -generate-busy => v=-7;%(500,500,480,620) -detect-busy => 480,620 - -generate-attn => v=0;%(100,100,1400,2060,2450,2600) -detect-attn => 1400,2060,2450,2600 - -generate-callwaiting-sas => v=0;%(300,0,440) -detect-callwaiting-sas => 440 - -generate-callwaiting-cas => v=0;%(80,0,2750,2130) -detect-callwaiting-cas => 2750,2130 - -detect-fail1 => 913.8 -detect-fail2 => 1370.6 -detect-fail3 => 1776.7 - - -[au] -generate-dial => v=-7;%(1000,0,413,438) -detect-dial => 413,438 - -generate-ring => v=-7;%(400,200,413,438);%(400,2000,413,438) -detect-ring => 413,438 - -generate-busy => v=-7;%(375,375,425) -detect-busy => 425 - -generate-attn => v=0;%(100,100,1400,2060,2450,2600) -detect-attn => 1400,2060,2450,2600 - -generate-callwaiting-sas => v=0;%(300,0,440) -detect-callwaiting-sas => 440 - -generate-callwaiting-cas => v=0;%(80,0,2750,2130) -detect-callwaiting-cas => 2750,2130 - -detect-fail1 => 913.8 -detect-fail2 => 1370.6 -detect-fail3 => 776.7 diff --git a/libs/freetdm/conf/wanpipe.conf b/libs/freetdm/conf/wanpipe.conf deleted file mode 100644 index 3784eaf17a..0000000000 --- a/libs/freetdm/conf/wanpipe.conf +++ /dev/null @@ -1,13 +0,0 @@ -[defaults] -; User space interval at which data will be delivered -codec_ms => 20 - -; wink and flash interval -wink_ms => 150 -flash_ms => 750 - -; size of the driver queue of elements of MTU size -; typical case is 10 elements of 80 bytes each (10ms of ulaw/alaw) -; don't mess with this if you don't know what you're doing -; txqueue_size => 10 -; rxqueue_size => 10 diff --git a/libs/freetdm/conf/zt.conf b/libs/freetdm/conf/zt.conf deleted file mode 100644 index a060a40315..0000000000 --- a/libs/freetdm/conf/zt.conf +++ /dev/null @@ -1,8 +0,0 @@ -[defaults] -codec_ms => 20 -wink_ms => 150 -flash_ms => 750 -echo_cancel_level => 64 -rxgain => 0.0 -txgain => 0.0 - diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac deleted file mode 100644 index e6aad59e52..0000000000 --- a/libs/freetdm/configure.ac +++ /dev/null @@ -1,480 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ([2.59]) -AC_INIT([freetdm], [0.1], [bugs@freeswitch.org]) -AC_CONFIG_SRCDIR([src/ftdm_io.c]) - -AC_CONFIG_AUX_DIR([build]) -AC_CONFIG_MACRO_DIR([build]) -AM_INIT_AUTOMAKE - -# >=automake-1.11 -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# override some default libtool behavior and invoke AC_PROG_LIBTOOL -# (see http://lists.gnu.org/archive/html/libtool/2007-03/msg00000.html) -m4_defun([_LT_AC_LANG_F77_CONFIG], [:]) -m4_defun([_LT_AC_LANG_GCJ_CONFIG], [:]) -m4_defun([_LT_AC_LANG_RC_CONFIG], [:]) - -# Checks for programs. -AC_PROG_CC -AC_PROG_MAKE_SET -AM_PROG_CC_C_O -AC_PROG_LIBTOOL -AC_PROG_INSTALL - -# NOTE: pkg-config is used to detect libisdn -m4_ifdef([PKG_PROG_PKG_CONFIG], - [PKG_PROG_PKG_CONFIG], - [AC_MSG_WARN([pkg-config missing (required for libisdn detection)])] -) - -AX_COMPILER_VENDOR - -# AC_PREFIX_DEFAULT does not get expanded until too late so we need -# to do this to use prefix in this script -AC_PREFIX_DEFAULT([/usr/local/freetdm]) -if test "x${prefix}" = "xNONE" ; then - prefix='/usr/local/freetdm' -fi - -# Absolute source/build directory -FT_SRCDIR=`(cd $srcdir && pwd)` -ft_builddir=`pwd` -AC_SUBST([FT_SRCDIR]) -AC_SUBST([ft_builddir]) - -if test "$sysconfdir" = "\${prefix}/etc" ; then - confdir="$prefix/conf" -else - confdir="$sysconfdir" -fi - -AC_SUBST([confdir]) - -DEFAULT_INCLUDES="-I. -I./src/include -I\$(srcdir)" -AC_SUBST([DEFAULT_INCLUDES]) - -# Where to install the modules -AC_ARG_WITH([modinstdir], - [AS_HELP_STRING([--with-modinstdir=DIR], [Install modules into this location (default: ${prefix}/mod)])], - [case "${withval}" in - no|yes) AC_MSG_ERROR([Invalid value \"${withval}\", option requires a valid path]) ;; - *) modinstdir="${withval}" ;; - esac], - [modinstdir="${prefix}/mod"] -) -AC_SUBST([modinstdir]) - -# freetdm.pc pkgconfig file -AC_ARG_WITH([pkgconfigdir], - [AS_HELP_STRING([--with-pkgconfigdir=DIR], [Installation directory for pkgconfig file (default: ${libdir}/pkgconfig)])], - [case "${withval}" in - yes|no) AC_MSG_ERROR([Invalid value ${withval} for option --with-pkgconfigdir]) ;; - *) pkgconfigdir="${withval}" ;; - esac - ], - [pkgconfigdir="${libdir}/pkgconfig"] -) -AC_SUBST([pkgconfigdir]) - -AC_ARG_ENABLE([enable_64], - [AS_HELP_STRING([--enable-64], [Enable 64bit compilation])], - [enable_64="${enableval}"], - [enable_64="no"] -) - -case "${ax_cv_c_compiler_vendor}" in -gnu) - COMP_VENDOR_CFLAGS="-ffast-math -Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -O0" - ;; -sun) - COMP_VENDOR_CFLAGS="-xc99=all -mt -xCC -xvpara" - if test "$enable_64" != "no" ; then - COMP_VENDOR_CFLAGS="-m64 $COMP_VENDOR_CFLAGS" - fi - ;; -*) - COMP_VENDOR_COMPAT_CFLAGS="-Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" - COMP_VENDOR_CFLAGS="-std=c99 $COMP_VENDOR_COMPAT_CFLAGS" - ;; -esac -AC_SUBST([COMP_VENDOR_COMPAT_CFLAGS]) -AC_SUBST([COMP_VENDOR_CFLAGS]) - - -# Enable debugging -AC_ARG_ENABLE([debug], - [AC_HELP_STRING([--enable-debug], [build with debug information])], - [enable_debug="${enableval}"], - [enable_debug="yes"] -) -if test "${enable_debug}" != "no"; then - AC_DEFINE([DEBUG], [], [Enable extra debugging.]) - - if test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then - COMP_VENDOR_CFLAGS="$COMP_VENDOR_CFLAGS -g -ggdb" - fi -fi -AC_SUBST([COMP_VENDOR_CFLAGS]) - -AC_CHECK_LIB([dl], [dlopen]) -AC_CHECK_LIB([pthread], [pthread_create]) -AC_CHECK_LIB([m], [cos]) - -AC_CHECK_HEADERS([netdb.h sys/select.h execinfo.h]) - -AC_CHECK_FUNC([gethostbyname_r], - [], [AC_CHECK_LIB([nsl], [gethostbyname_r])] -) -if test "$ac_cv_func_gethostbyname_r" = "yes" -o "$ac_cv_lib_nsl_gethostbyname_r" = "yes" -then - AC_MSG_CHECKING([whether gethostbyname_r requires five arguments]) - - ac_cv_func_gethostbyname_r_five_args="no" - - AC_TRY_COMPILE([#include ], - [char *name; - struct hostent *he, *res; - char buffer[2048]; - int buflen = 2048; - (void)gethostbyname_r(name, he, buffer, buflen, &res)], - [ac_cv_func_gethostbyname_r_five_args="yes" - AC_DEFINE([HAVE_GETHOSTBYNAME_R_FIVE], [1], [gethostbyname_r has five arguments])] - ) - - AC_MSG_RESULT([$ac_cv_func_gethostbyname_r_five_args]) - AC_DEFINE([HAVE_GETHOSTBYNAME_R], [1], [threadsafe gethostbyname]) -fi - -## -## Modules and optional features -## -AC_MSG_RESULT([${as_nl}<<>> Modules and optional features]) - -## -# pritap (TODO: add checks) -# -HAVE_PRITAP="no" -AC_ARG_WITH([pritap], - [AS_HELP_STRING([--with-pritap], [Install ftmod_pritap])], - [case "${withval}" in - no) enable_pritap="no" ;; - *) enable_pritap="yes" ;; - esac], - [enable_pritap="no"] -) -HAVE_PRITAP="${enable_pritap}" -AM_CONDITIONAL([HAVE_PRITAP],[test "${enable_pritap}" = "yes"]) - -## -# OpenR2 stack -# -HAVE_OPENR2="no" -AC_CHECK_LIB([openr2], [openr2_context_set_io_type], [HAVE_OPENR2="yes"]) -AC_MSG_RESULT([checking whether to build ftmod_r2... ${HAVE_OPENR2}]) -AM_CONDITIONAL([HAVE_OPENR2], [test "${HAVE_OPENR2}" = "yes"]) - -## -# WAT GSM stack -# -HAVE_WAT="no" -AC_CHECK_LIB([wat], [wat_version], [HAVE_WAT="yes"]) -AC_MSG_RESULT([checking whether to build ftmod_wat... ${HAVE_WAT}]) -AM_CONDITIONAL([HAVE_WAT], [test "${HAVE_WAT}" = "yes"]) - -## -# Digium libpri (TODO: add checks) -# -HAVE_LIBPRI="no" -AC_ARG_WITH([libpri], - [AS_HELP_STRING([--with-libpri@<:@=PREFIX@:>@], [Install ftmod_libpri])], - [case "${withval}" in - no|yes) with_libpri="${withval}" ;; - *) AS_IF([test -d "${withval}"], - [with_libpri="${withval}"], - [AC_MSG_ERROR([Invalid argument for --with-libpri, \"${withval}\" is not a directory])] - ) ;; - esac], - [with_libpri="no"] -) -if test "x${with_libpri}" != "xno" -then - save_LIBS="${LIBS}" - save_CPPFLAGS="${CPPFLAGS}" - save_LDFLAGS="${LDFLAGS}" - - LIBPRI_CPPFLAGS="" - LIBPRI_LDFLAGS="" - - AC_MSG_RESULT([${as_nl}<<>> Digium libpri]) - - AS_IF([test "x${with_libpri}" != "xyes"], - [LIBPRI_CPPFLAGS="-I${with_libpri}/include" - LIBPRI_LDFLAGS="-L${with_libpri}/lib"], - ) - - LDFLAGS="${save_LDFLAGS} ${LIBPRI_LDFLAGS}" - CPPFLAGS="${save_CPPFLAGS} ${LIBPRI_CPPFLAGS}" - LIBS="${LIBS} -lpri" - - AC_MSG_CHECKING([whether libpri is usable]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [#include ], - [const char *version = pri_get_version(); - (void)version;] - )], - [AC_MSG_RESULT([yes]) - HAVE_LIBPRI="yes"], - [AC_MSG_RESULT([no]) - AC_MSG_ERROR([libpri not found or unusable (see config.log for details)])] - ) - - AC_MSG_CHECKING([whether libpri is too old]) - AC_PREPROC_IFELSE( - [AC_LANG_PROGRAM( - [#include ], - [#if !defined(PRI_IO_FUNCS) - #error "libpri is lacking PRI_IO_FUNCS" - #elif !defined(PRI_NEW_SET_API) - #error "libpri is lacking PRI_NEW_SET_API" - #endif] - )], - [AC_MSG_RESULT([no])], - [AC_MSG_RESULT([yes]) - AC_MSG_ERROR([Your version of libpri is too old (pre 1.2), please update!])] - ) - - AC_MSG_CHECKING([whether libpri has BRI support]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [extern void pri_new_bri_cb(void);], - [pri_new_bri_cb();] - )], - [AC_DEFINE([HAVE_LIBPRI_BRI], [1], [libpri has BRI support]) - AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no]) - AC_MSG_NOTICE([You will need libpri-1.4.12_beta1 or newer for BRI support])] - ) - - AC_MSG_CHECKING([whether libpri has AOC event support]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [extern void pri_aoc_events_enable(void);], - [pri_aoc_events_enable();] - )], - [AC_DEFINE([HAVE_LIBPRI_AOC], [1], [libpri has AOC event support]) - AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no]) - AC_MSG_NOTICE([You will need libpri-1.4.12_beta1 or newer for AOC event support])] - ) - - - AC_MSG_CHECKING([whether libpri has pri_maintenance_service()]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [extern int pri_maintenance_service(void);], - [pri_maintenance_service();] - )], - [AC_DEFINE([HAVE_LIBPRI_MAINT_SERVICE], [1], [libpri has pri_maintenance_service()]) - AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no]) - AC_MSG_NOTICE([You will need libpri-1.4.11 or newer for the ftdm libpri maintenance set of commands])] - ) - - # libpri is available, set variables for Makefile(.am) - AC_SUBST([LIBPRI_LIBS], [-lpri]) - AC_SUBST([LIBPRI_LDFLAGS]) - AC_SUBST([LIBPRI_CPPFLAGS]) - - LIBS="${save_LIBS}" - LDFLAGS="${save_LDFLAGS}" - CPPFLAGS="${save_CPPFLAGS}" -fi -AM_CONDITIONAL([HAVE_LIBPRI],[test "x${HAVE_LIBPRI}" = "xyes"]) - -## -# Sangoma Wanpipe -# -HAVE_LIBSANGOMA="no" -AC_MSG_RESULT([${as_nl}<<>> Sangoma Wanpipe]) -AC_CHECK_LIB([sangoma], [sangoma_span_chan_toif], [HAVE_LIBSANGOMA="yes"]) -AC_MSG_RESULT([checking whether to build ftmod_wanpipe... ${HAVE_LIBSANGOMA}]) -AM_CONDITIONAL([HAVE_LIBSANGOMA], [test "${HAVE_LIBSANGOMA}" = "yes"]) - -## -# Sangoma ISDN stack -# -HAVE_SNG_ISDN="no" -AC_MSG_RESULT([${as_nl}<<>> Sangoma ISDN stack]) -AC_CHECK_LIB([sng_isdn], [sng_isdn_init], [HAVE_SNG_ISDN="yes"]) -AC_MSG_RESULT([checking whether to build ftmod_sangoma_isdn... ${HAVE_SNG_ISDN}]) -AM_CONDITIONAL([HAVE_SNG_ISDN], [test "${HAVE_SNG_ISDN}" = "yes"]) - -if test "${HAVE_SNG_ISDN}" = "yes"; then - if test "${build}" = "${host}" - then - case "${host}" in - x86_64-*) - # X86_64 machines need additional flags when compiling against libsng_isdn - CFLAGS="$CFLAGS -DBIT_64 -DALIGN_64BIT" - ;; - esac - fi -fi - -## -# Sangoma SS7 stack -# -HAVE_SNG_SS7="no" -AC_MSG_RESULT([${as_nl}<<>> Sangoma SS7 stack]) -AC_CHECK_LIB([sng_ss7], [sng_isup_init_gen], [HAVE_SNG_SS7="yes"]) -AC_MSG_RESULT([checking whether to build ftmod_sangoma_ss7... ${HAVE_SNG_SS7}]) -AM_CONDITIONAL([HAVE_SNG_SS7], [test "${HAVE_SNG_SS7}" = "yes"]) - -if test "${HAVE_SNG_SS7}" = "yes"; then - if test "${build}" = "${host}" - then - case "${host}" in - x86_64-*) - # X86_64 machines need additional flags when compiling against libsng_isdn - CFLAGS="$CFLAGS -DBIT_64 -DALIGN_64BIT" - ;; - esac - fi -fi - - -## -# zlib (required for Sangoma SS7 Transparent IAM) -# -HAVE_ZLIB="no" -AC_MSG_RESULT([${as_nl}<<>> zlib]) -AC_CHECK_LIB([z], [compress], [HAVE_ZLIB="yes"]) -AC_MSG_RESULT([checking whether zlib is installed... ${HAVE_ZLIB}]) -AM_CONDITIONAL([HAVE_ZLIB], [test "{HAVE_ZLIB]" = "yes"]) -if test "${HAVE_ZLIB}" = "yes"; then - CFLAGS="$CFLAGS -DHAVE_ZLIB" -fi - -## -# libisdn -# -HAVE_LIBISDN="no" -AC_ARG_WITH([libisdn], - [AS_HELP_STRING([--with-libisdn], [Install ftmod_isdn (libisdn stack)])], - [case "${withval}" in - no) with_libisdn="no" ;; - *) with_libisdn="yes" ;; - esac - ], - [with_libisdn="no"] -) -if test "${with_libisdn}" != "no" -then - AC_MSG_RESULT([${as_nl}<<>> ftmod_isdn (libisdn stack)]) - m4_ifdef([PKG_CHECK_MODULES], - [PKG_CHECK_MODULES([libisdn], - [libisdn >= 0.0.1], - [AC_MSG_CHECKING([libisdn version]) - LIBISDN_VERSION="`${PKG_CONFIG} --modversion libisdn`" - if test -z "${LIBISDN_VERSION}"; then - AC_MSG_ERROR([Failed to retrieve libisdn version]) - fi - AC_MSG_RESULT([${LIBISDN_VERSION}]) - - # check features - AC_MSG_CHECKING([for new experimental API]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [#include - #if !LIBISDN_FEATURE(API2) - #error "libisdn API v2 not available" - #endif - ], - [;] - )], - [AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no])] - ) - - HAVE_LIBISDN="yes" - AC_DEFINE([HAVE_LIBISDN], [1], [libisdn support]) - AC_SUBST([LIBISDN_CFLAGS], [${libisdn_CFLAGS}]) - AC_SUBST([LIBISDN_CPPFLAGS],[${libisdn_CPPFLAGS}]) - AC_SUBST([LIBISDN_LDFLAGS], [${libisdn_LDFLAGS}]) - AC_SUBST([LIBISDN_LIBS], [${libisdn_LIBS}]) - AC_SUBST([LIBISDN_VERSION]) - ], - [AC_MSG_ERROR([Need libisdn-0.0.1 or higher])] - ) - AX_LIB_PCAP], - [AC_MSG_WARN([pkg-config missing (required for libisdn detection)])] - ) -fi -AM_CONDITIONAL([HAVE_LIBISDN], [test "${HAVE_LIBISDN}" = "yes"]) - - -## -# mISDN dependencies -# -HAVE_MISDN="no" -AC_ARG_WITH([misdn], - [AS_HELP_STRING([--with-misdn], [Install ftmod_misdn (mISDN I/O plugin)])], - [case "${withval}" in - no|yes) with_misdn="${withval}" ;; - *) AC_MSG_ERROR([Invalid value \"${with_misdn}\" for --with-misdn option]) ;; - esac], - [with_misdn="auto"] -) -AS_IF([test "${with_misdn}" != "no"], - [AC_MSG_RESULT([${as_nl}<<>> ftmod_misdn (Linux mISDN I/O plugin)]) - AC_CHECK_HEADER([mISDN/mISDNif.h], - [HAVE_MISDN="yes" - AC_CHECK_LIB([rt], [clock_gettime])], - [AS_IF([test "${with_misdn}" = "yes"], - [AC_MSG_ERROR([mISDN/mISDNif.h not found])], - [AC_MSG_NOTICE([mISDN/mISDNif.h not found])] - )], - [#include ] - )] -) -AM_CONDITIONAL([HAVE_MISDN], [test "${HAVE_MISDN}" = "yes"]) - - -AC_MSG_RESULT([${as_nl}<<>> Creating output files]) -AC_CONFIG_FILES([ - Makefile - freetdm.pc - mod_freetdm/Makefile -]) -AC_OUTPUT - -# -# summary screen -# -AC_MSG_RESULT([ -============================ FreeTDM configuration ============================ - -+ Modules - - Signalling: - ftmod_analog....................... yes - ftmod_analog_em.................... yes - ftmod_isdn......................... ${HAVE_LIBISDN} - ftmod_libpri....................... ${HAVE_LIBPRI} - ftmod_sangoma_isdn................. ${HAVE_SNG_ISDN} - ftmod_sangoma_ss7.................. ${HAVE_SNG_SS7} - ftmod_r2........................... ${HAVE_OPENR2} - ftmod_gsm.......................... ${HAVE_WAT} - ftmod_pritap....................... ${HAVE_PRITAP} - I/O: - ftmod_zt........................... yes - ftmod_wanpipe...................... ${HAVE_LIBSANGOMA} - ftmod_misdn........................ ${HAVE_MISDN} - -=============================================================================== -]) diff --git a/libs/freetdm/configure.gnu b/libs/freetdm/configure.gnu deleted file mode 100755 index d00cd18473..0000000000 --- a/libs/freetdm/configure.gnu +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -srcpath=$(dirname $0 2>/dev/null ) || srcpath="." -$srcpath/configure "$@" --with-pic diff --git a/libs/freetdm/cyginstall.sh b/libs/freetdm/cyginstall.sh deleted file mode 100755 index e7953675b6..0000000000 --- a/libs/freetdm/cyginstall.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# this script must be run from freetdm root dir and it is assuming -# FreeSWITCH is trunk is located at ../../ -fsdir=../.. -set -x -cp Debug/mod/*.dll $fsdir/Debug/mod/ -cp mod_freetdm/Debug/*.pdb $fsdir/Debug/mod/ -cp Debug/freetdm.dll $fsdir/Debug/ -cp Debug/ftmod_*.dll $fsdir/Debug/mod/ -cp Debug/*.pdb $fsdir/Debug/mod/ -#cp Debug/testsangomaboost.exe $fsdir/Debug/ -echo "FRIENDLY REMINDER: RECOMPILE ftmod_wanpipe WHENEVER YOU INSTALL NEW DRIVERS" -set +x - diff --git a/libs/freetdm/docs/Doxygen.conf b/libs/freetdm/docs/Doxygen.conf deleted file mode 100644 index 1f69952879..0000000000 --- a/libs/freetdm/docs/Doxygen.conf +++ /dev/null @@ -1,265 +0,0 @@ -# Doxyfile 1.4.6 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = FreeTDM -PROJECT_NUMBER = -OUTPUT_DIRECTORY = docs/ -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = YES -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -IGNORE_PREFIX = ftdm_ FTDM_ Q921 Q931 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = YES -HIDE_UNDOC_MEMBERS = YES -HIDE_UNDOC_CLASSES = YES -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = NO -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = YES -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = src/include/freetdm.h - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py -RECURSIVE = NO -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = YES -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -USE_HTAGS = YES -VERBATIM_HEADERS = NO -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 1 -IGNORE_PREFIX = ftdm_ -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = freetdm.chm -HHC_LOCATION = -GENERATE_CHI = YES -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = NO -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = *.h -PREDEFINED = FT_DECLARE(x)=x \ - FT_MOD_DECLARE(x)=x \ - DoxyDefine(x)=x - -EXPAND_AS_DEFINED = NO -SKIP_FUNCTION_MACROS = NO -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = YES -TEMPLATE_RELATIONS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = YES -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = jpg -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/libs/freetdm/docs/PRI-BRI-Debug.pdf b/libs/freetdm/docs/PRI-BRI-Debug.pdf deleted file mode 100755 index 53386b1b52..0000000000 Binary files a/libs/freetdm/docs/PRI-BRI-Debug.pdf and /dev/null differ diff --git a/libs/freetdm/docs/async.txt b/libs/freetdm/docs/async.txt deleted file mode 100644 index c5d706ecba..0000000000 --- a/libs/freetdm/docs/async.txt +++ /dev/null @@ -1,15 +0,0 @@ -APIs that result in an event when the API returns FTDM_SUCCESS - -ftdm_channel_call_answer() -ftdm_channel_call_indicate() -ftdm_channel_call_transfer() - FTDM_SIGEVENT_INDICATION_COMPLETED - *note that FTDM_SIGEVENT_INDICATION_COMPLETED has associated data to indicate the result of the indication - *note this event is only delivered on non-blocking channels - -ftdm_call_place - FTDM_SIGEVENT_DIALING - -ftdm_channel_call_hangup - FTDM_SIGEVENT_RELEASED - diff --git a/libs/freetdm/docs/ftdm-open-issues.txt b/libs/freetdm/docs/ftdm-open-issues.txt deleted file mode 100644 index 8088c85bd0..0000000000 --- a/libs/freetdm/docs/ftdm-open-issues.txt +++ /dev/null @@ -1,76 +0,0 @@ -== This is an email sent to stkn responding to his post http://stkn.techmage.de/archives/200 == - -1. FreeTDM open channels immediately. - -Yes, this seems to come from the early days of Freetdm where probably the analog modules were implemented first and was dragged incorrectly to ISDN. -The open API also sets the flag in use so others cannot use it. We should decouple this open and reserve operations. Does not seem very hard to do, -I'll take a look at it on my way back to Toronto this week or earlier if possible, I'll create a git branch for it and send you the url for peer review. -Feel free to do the opposite if you are in a hurry. - -2. FreeTDM does not completely close the channel on hangup. - -As long as the signaling module calls ftdm_channel_close() the fio->close API will be called where the IO module is responsible -for turning off ec or any other operations to leave the channel unused/idle (not really closed). There was indeed a bug where ftdm_zt module -was not properly closing the channel, if that is what you mean, then it means that was already fixed by you with your audio mode turn off patch. - -Now, a more lengthy response ... - -When we, Sangoma, took over freetdm and renamed it to freetdm, it was not just a name change, many API cleanups were done so API users cannot access - -the internal data structures and cannot explicitly move between channel states. Also, some order on the state transitions has been put into place. - -We've tried to keep backwards compatibility though, so old modules may not follow all of the conventions. Some unwritten conventions are: - -1. Signaling modules are responsible for calling ftdm_channel_close() when done with the channel. In fact, signaling modules should not - call ftdm_channel_done unless they really know what they're doing. ftdm_channel_close will call ftdm_channel_done anyways. - -2. When remote end hangs up a call, signaling module should go to TERMINATING state and send SIGEVENT_STOP to the user. The signaling stack - should not acknowledge the hangup until the user implicitly moves us to HANGUP (via ftdm_channel_call_hangup()). There is a core timer - that will ensure we move from TERMINATING to HANGUP if the user does not moves us fast enough (arbitrarely 3000ms), although that is considered - a bug in the user application (at some point we saw that in FreeSWITCH) and we complain loudly when that happens. - -3. Signaling modules should leave the channel with NO pending states once they unlock it. This means, whenever you have a message to process - you must lock the channel, check its current state (the user may have already changed the state to something else), process any pending - state set by the user, then process your message and if required move the channel to a new state and process that state before releasing the lock. - There is a chance of a deadlock due to the callbacks we use to notify users of messages if we call those callbacks with the channel lock held and - that is why new signaling modules should use the FTDM_SPAN_USE_SIGNALS_QUEUE to defer the notification to the user when the ftdm_channel_t is not - locked calling ftdm_span_trigger_signals() at the end of their processing loop which delivers the callback notifications to users. - -Having said that, there is a major architectural change coming, probably early 2011, and I'd like to have your input. - -== Decoupling calls from IO channels == - -We've also found that the concept of a channel and a call are unnecesarily coupled together in FreeTDM. I've never asked Anthony the reasoning -for this, but it seems the API was meant to be used with, or without calls. That is, a user should be able to just 'open' a channel and start -reading and writing raw data without ever launching one of the provided signaling stacks on top, may be just because the user is using their -own signaling stack and just needs freetdm as an I/O API. In fact, signaling modules work like this (but there are defects there). -The problem is, as you have noticed, the way ftdm_channel_open_xx APIs has been implemented is abusing this concept. - -Problems with current implementation. - -1. Exclusive channel is the only way we can request channels to the ISDN network. There is no room to change the channel later on easily. -2. Multi-rate calls cannot be done. We need to associate multiple B-channels to a single call. -3. Low-bit-rate calls (not sure what is the proper name for them) where a single B-channel can feed media to multiple calls with a low bit-rate - codec (I know of at least one request from a big company for this to support some Q.SIG stuff for Eurocontrol). - - -What do we need? - -I think there should be only one open() API that wraps calls around fio->open(), the other current open_xx functions that do hunting, should -be eliminated and some extra arguments provided to ftdm_channel_call_place to provide information about the channel where we would like to -place the call or group hunting information and the API would return immediately providing a ftdm_call_t reference pointer that can be used -to further track the status of that call, or in the case where a channel exclusivity was requested and we know for a fact is not available, -just return failure. At that point there is no I/O channel involved yet. Eventually after the signaling stack hunts the channel and -negotiaties its availability with the network, an I/O channel can be attached to that call, or even attach multiple channels (for the case -of multi rate calls?). - -This involves heavy changes. The state machine should be moved out of the ftdm_channel_t structure along with probably some other members -and stuffed into a new ftdm_call_t structure. Signaling modules would have to be updated to run their state machines with this call -structure and then at some point attach IO channels to the call. There would be 2 type of read/write APIs, one low level ftdm_channel_read -which receives an ftdm_channel_t as parameter and an ftdm_call_read() which receives an ftdm_call_t as parameter, for the case of multi-rate -calls or low-bit-rate multiplexed calls in the same B-channel this API would return just the media corresponding to that call already -demultiplexed or concatenated, or whatever needs to be done with the media from the multiple low-level IO channels. - -This is fairly disruptive, but I believe should be done sooner or later. - - diff --git a/libs/freetdm/docs/glare.txt b/libs/freetdm/docs/glare.txt deleted file mode 100644 index 0753db817f..0000000000 --- a/libs/freetdm/docs/glare.txt +++ /dev/null @@ -1,25 +0,0 @@ -Glare is a PITA. - -Although configuration of ISDN links can be done to minimize glare, we also must have a clear policy -on how the FreeTDM API is supposed to behave on glare across signaling modules. - -There is a well-known race in the FreeTDM API since the beginning. When a user wants to place a call with -the old APIs: - -1. ftdm_channel_open_xx (to hunt the channel by group, span or select a channel individually) -2. ftdm_channel_call_place() to place the actual call. - -Since the user has no access to channel locking, between opening a channel and placing a call, an incoming call could be -received. Therefore things can get complicated and that is why you should STOP USING those 2 deprecated functions. - -The replacement is ftdm_call_place(). - -ftdm_call_place receives the information required to hunt the channel and place the call. - -If glare is detected after placing the call and the signaling stack decides to drop the local call, a regular -SIGEVENT_STOP will be sent with the hangup cause FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL. - -ftdm_call_place may return FTDM_BREAK if glare is detected while placing the call, in such cases you can try -calling ftdm_call_place again to hunt another channel. - - diff --git a/libs/freetdm/docs/io_modules.txt b/libs/freetdm/docs/io_modules.txt deleted file mode 100644 index a164bbb249..0000000000 --- a/libs/freetdm/docs/io_modules.txt +++ /dev/null @@ -1,13 +0,0 @@ -Last Updated: Jan 19, 2011 - -== BACKGROUND == - -The IO module provides an abstracted IO interface to FreeTDM. - -== SHUTDOWN == -Upon global shutdown, for each channel FIO_CLOSE_FUNCTION will be called. -When FIO_CLOSE_FUNCTION is called, all waiters on this channel shall be signalled. -If FIO_WAIT_FUNCTION is called on a function that has already been closed, this function shall return FTDM_TIMEOUT without blocking. -FIO_CHANNEL_DESTROY will eventually be called, and IO module is responsible for clearing all internal states and free allocated memory upon channel destroy. - - diff --git a/libs/freetdm/docs/locking.txt b/libs/freetdm/docs/locking.txt deleted file mode 100644 index 851d045b41..0000000000 --- a/libs/freetdm/docs/locking.txt +++ /dev/null @@ -1,125 +0,0 @@ -Last Updated: Fri 30 Dec, 2010 - -== Background == - -FreeTDM is a threaded library. As such, locking considerations must be taken when using it and when writing code inside the library. - -At the moment locks are not exposed to users. This means API users cannot acquire a lock on a channel or span structure. There is no -need for users to lock channels or spans since all their interactions with those structures should be done thru the FreeTDM API which -can (and in most cases must) internally lock on their behalf. - -Internally, locking can be done either by the core or the signaling modules. To better understand the locking considerations we must -understand first the threading model of FreeTDM. - -== Threading Model == - -At startup, when the user calls ftdm_global_init(), just one timing thread is created to dispatch internal timers. If you write -a signaling module or any other code using the scheduling API, you can choose to run your schedule in this timing thread or in -a thread of your choice. This is the only thread launched at initialization. - -If the application decides to use ftdm_global_configuration(), which reads freetdm.conf to create the spans and channels data -structures, then possibly another thread will be launched for CPU usage monitoring (only if enabled in the configuration cpu_monitor=yes -This thread sole purpose is to check the CPU and raise an alarm if reaches a configurable threshold, the alarm then is checked to avoid -placing or receiving further calls. - -At this point FreeTDM has initialized and configured its channels input output configuration. - -The user is then supposed to configure the signaling via ftdm_configure_span_signaling() and then start the signaling work -using ftdm_span_start(). This will typically launch at least 1 thread per span. Some signaling modules (actually just the analog one) -launches another thread per channel when receiving a call. The rest of the signaling modules currently launch only one thread per -span and the signaling for all channels within the span is handled in that thread. We call that thread 'the signaling thread'. - -At this point the user can start placing calls using the FreeTDM call API ftdm_channel_call_place(). Any of the possible threads in -which the user calls the FreeTDM API is called 'the user thread', depending on the application thread model (the application using FreeTDM) -this user thread may be different each time or the same all the time, we cannot make any assumptions. In the case of FreeSWITCH, the most -common user of FreeTDM, the user thread is most of the cases a thread for each new call leg. - -At this point we have identified 4 types of threads. - -1. The timing thread (the core thread that triggers timers). - Its responsibility is simply check for timers that were scheduled and trigger them when the time comes. This means that if you decide - to use the scheduling API in freerun mode (where you use the core timer thread) you callbacks will be executed in this global thread - and you MUST not block at all since there might be other events waiting. - -2. The CPU thread (we don't really care about this one as it does not interact with channels or spans). - -3. The signaling thread. - There is one thread of this per span. This thread takes care of reading signaling specific messages from the network (ISDN network, etc) and - changing the channel call state accordingly and processing state changes caused by user API calls (like ftdm_channel_call_hangup for example). - -4. The user thread. - This is a thread in which the user decides to execute FreeTDM APIs, in some cases it might even be the same than the signaling thread (because - most SIGEVENT notifications are delivered by the signaling thread, however we are advicing users to not use FreeTDM unsafe APIs from the - thread where they receive SIGEVENT notifications as some APIs may block for a few milliseconds, effectively blocking the whole signaling thread - that is servicing a span. - -== Application Locking == - -Users of the FreeTDM API will typically have locking of their own for their own application-specific data structures (in the case of FreeSWITCH, the -session lock for example). Other application-specific locks may be involved. - -== DeadLocks == - -As soon as we think of application locks, and we mix them with the FreeTDM internal locks, the possibility of deadlocks arise. - -A typical deadlock scenario when 2 locks are involved is: - -- User Thread - - Signaling Thread - -1. Application locks applock. 1. A network message is received for a channel. - -2. Aplication invokes a FreeTDM call API (ie: ftdm_channel_call_hangup()). 2. The involved channel is locked. - -3. The FreeTDM API attempts to acquire the channel lock and stalls because 3. The message processing results in a notification - the signaling thread just acquired it. to be delivered to the user via the callback function - provided for that purpose. The callback is then called. - -4. The thread is now deadlocked because the signaling thread will never 4. The application callback attempts to acquire its application - release the channel lock. lock but deadlocks because the user thread already has it. - -To avoid this signaling modules should not deliver signals to the user while holding the channel lock. An easy way to avoid this is -to not deliver signals while processing a state change, but rather defer them until the channel lock is released. Most new signaling modules -accomplish this by setting the span flag FTDM_SPAN_USE_SIGNALS_QUEUE, this flag tells the core to enqueue signals (ie FTDM_SIGEVENT_START) -when ftdm_span_send_signal() is called and not deliver them until ftdm_span_trigger_signals() is called, which is done by the signaling module -in its signaling thread when no channel lock is being held. - -== State changes while locking == - -Only 2 types of threads should be performing state changes. - -User threads. -The user thread is a random thread that was crated by the API user. We do not know what threading model users of FreeTDM will follow -and therefore cannot make assumptions about it. The user should be free to call FreeTDM APIs from any thread, except threads that -are under our control, like the signaling threads. Although it may work in most situations, is discouraged for users to try -to use FreeTDM APIs from the signaling thread, that is, the thread where the signaling callback provided during configuration -is called (the callback where FTDM_SIGEVENT_XXX signals are delivered). - -A user thread may request state changes implicitly through calls to FreeTDM API's. The idea of state changes is internal to freetdm -and should not be exposed to users of the API (except for debugging purposes, like the ftdm_channel_get_state, ftdm_channel_get_state_str etc) - -This is an example of the API's that implicitly request a state change. - -ftdm_channel_call_answer() - -Signaling modules should guarantee that upon releasing a lock on a channel, any state changes will be already processed and -not deferred to other threads, otherwise that leads to a situation where a state change requested by the signaling module is pending -to be serviced by another signaling module thread but a user thread wins the channel lock and attempts to perform a state change which will -fail because another state change is pending (and user threads are not meant to process signaling states). - -ONLY one signaling thread per channel should try to perform state changes and processing of the states, -otherwise complexity arises and is not worth it! - -At some point before we stablished this policies we could have 3 different threads doing state changes. - -1. A user random thread could implcitly try to change the state in response to a call API. -2. The ftmod signaling thread could try to change the state in response to other state changes. -3. The lower level signaling stack threads could try to change the state in response to stack events. - -As a result, lower level signaling stack thread could set a state and then let the signaling thread to -process it, but when unlocking the channel, the user thread may win the lock over the signaling thread and -may try to set a state change of its own and fail (due to the unprocessed state change)! - -The rule is, the signaling module should never unlock a channel with states pending to process this way the user, -when acquiring a channel lock (inside ftdm_channel_call_answer for example) it will always find a consistent state -for the channel and not in the middle of state processing. - - diff --git a/libs/freetdm/docs/sigstatus.txt b/libs/freetdm/docs/sigstatus.txt deleted file mode 100644 index 10561bfb5b..0000000000 --- a/libs/freetdm/docs/sigstatus.txt +++ /dev/null @@ -1,59 +0,0 @@ -FreeTDM can both notify and set signaling status changes in the different protocols thru a unified interface. More -specific details on the C data types and function prototypes are found in freetdm.h - -The API provides the following functions and data types to do it: - -The signaling status in any channel/span is represented thru ftdm_signaling_status_t - - /* The signaling link is down (no d-chans up in the span/group, MFC-R2 bit pattern unidentified) */ - FTDM_SIG_STATE_DOWN, - /* The signaling link is suspended (MFC-R2 bit pattern blocked, PRI maintenance, ss7 blocked?) */ - FTDM_SIG_STATE_SUSPENDED, - /* The signaling link is ready and calls can be placed (ie: d-chan up, MFC-R2 both rx and tx in IDLE) */ - FTDM_SIG_STATE_UP, - /* Invalid status */ - FTDM_SIG_STATE_INVALID - -Changes in the signaling status are notified to the user using the standard callback notification function provided -during configuration using the sigevent type FTDM_SIGEVENT_SIGSTATUS_CHANGED which is sent when the line status changes. - -On startup the signalling status default is FTDM_SIG_STATE_DOWN, and no notification is provided until the state change, -so applications must assume the status is down unless told otherwise. - -When ftdm_span_start is called, the signaling stack takes care of attempting to bring the status to UP -but it will ultimately depend on the other side too. - -== Setting the signaling status == - -Users can set the signaling status on a given channel/span thru FreeTDM the following API functions: - -ftdm_channel_set_sig_status -ftdm_span_set_sig_status - -If the user calls ftdm_channel_set_sig_status(chan, FTDM_SIG_STATE_SUSPENDED), the signaling stack will try to set -the status of the line to the one requested, if successful, it will result in a SIGEVENT_SIGSTATUS_CHANGED notification -being sent with status FTDM_SIG_STATE_SUSPENDED. - -** MFC-R2 Signaling Notes ** -For MFC-R2, calling ftdm_span_start() results in setting the tx CAS bits to IDLE. However, if the rx bits are in BLOCKED state -the signaling status will be reported as SUSPENDED. - -If the user calls ftdm_channel_set_sig_status(chan, SUSPENDED), the tx CAS bits will be set to BLOCKED and, if, the current rx bits -are IDLE then a SIGEVENT_SIGSTATUS_CHANGED with state SUSPENDED will be sent. If the rx bits are already in blocked then no further -SIGEVENT_SIGSTATUS_CHANGED notification is needed (because it was already sent when the rx bits were initially detected as BLOCKED). - -If the user calls ftdm_channel_set_sig_status(chan, UP), the tx CAS bits will be set to IDLE and, if, the current rx bits -are IDLE, then SIGEVENT_SIGSTATUS_CHANGED with state UP will be sent. If the rx bits are BLOCKED, then no notification is -sent at all until the rx bits change. - -Bottom line is, for MFC-R2, SIGEVENT_SIGSTATUS_CHANGED UP is only sent to the user when both the rx and tx bits are in IDLE, and -SIGEVENT_SIGSTATUS_CHANGED SUSPENDED is only sent to the user when any of the rx or tx bits are in BLOCKED. - -== Getting the signaling status == -Users can get the signaling status on a given channel/span thru FreeTDM the following API functions: - -ftdm_channel_get_sig_status -ftdm_span_get_sig_status - -The line status returned should be the same as the last time a SIGEVENT_SIGSTATUS_CHANGED was reported. - diff --git a/libs/freetdm/docs/ss7-native-bridge.txt b/libs/freetdm/docs/ss7-native-bridge.txt deleted file mode 100644 index d44b067b0a..0000000000 --- a/libs/freetdm/docs/ss7-native-bridge.txt +++ /dev/null @@ -1,43 +0,0 @@ -SS7 Native Bridge - -Native bridge is enabled on 2 conditions: - -* The SIP header FreeTDM-TransUUID is set in the originating leg and matches a freetdm channel -* The variable freetdm_native_sigbridge is true and the originating leg is also a freetdm channel - -Some coding rules apply to this feature: - -- Each channel is responsible for clearning its own peer_data and event queue - at the end of the call (when moving to DOWN state) - -- Each channel dequeues messages only from its own queue and enqueues messages - in the peer's queue, with the only exception being messages received before - the bridge is stablished (IAM for sure and possible SAM messages) because - if the bridge is not yet stablished the messages must be queued by the channel - in its own queue temporarily until the bridge is ready - -- When the bridge is ready it is the responsibility of the incoming channel to - move the messages that stored temporarily in its own queue to the bridged peer queue - -- During hangup, each channel is responsible for moving itself to DOWN. The procedure - however differs slightly depending on the hangup conditions - - If the user requests hangup (ie, FreeSWITCH) the request will be noted by setting the - FTDM_CHANNEL_USER_HANGUP flag but will not be processed yet because call control is - driven only by the link messages (so no hangup from ESL or command line allowed) - - When REL message comes, the channel receiving it must move to TERMINATING state and: - - - If the user has not hangup yet (FTDM_CHANNEL_USER_HANGUP flag not set) then - notify the user via SIGEVENT_STOP and wait for the user to move to HANGUP - state by calling ftdm_channel_call_hangup() before sending RLC - - - If the user did hangup already (FTDM_CHANNEL_USER_HANGUP flag is set) then - skip user notification and move to HANGUP state directly where the RLC message - will be sent - -- On HANGUP state the RLC is sent and the channel is moved to DOWN, final state - The peer channel will forward the REL message and wait for RLC from the network, when - RLC is received the channel can move straight to DOWN itself because the peer channel - is completing its own shutdown procedure when it received the REL message - diff --git a/libs/freetdm/docs/variables.txt b/libs/freetdm/docs/variables.txt deleted file mode 100644 index cb518e14d8..0000000000 --- a/libs/freetdm/docs/variables.txt +++ /dev/null @@ -1,122 +0,0 @@ -Using FreeTDM Variables - -1. User application sending variables or raw buffer to FreeTDM -============================================================== - -The User can include a ftdm_usrmsg_t before sending an event to freetdm. - -example #1a - Making an outbound call: --------------------------------------- - -To make an outbound call: - ftdm_usrmsg_t usrmsg; - memset(&usrmsg, 0, sizeof(usrmsg)); - - /* Attach variable to usrmsg */ - ftdm_usrmsg_add_var(&usrmsg, "isdn.prog_ind.descr", "inband-info-available"); - - ftdm_channel_call_place_ex(ftdmchan, &usrmsg); - -example #1b - Adding a variable: --------------------------------- -When using ftmod_sangoma_isdn, user want to specify progress indicator inside PROCEED message. - - - ftdm_usrmsg_t usrmsg; - memset(&usrmsg, 0, sizeof(usrmsg)); - - /* Attach variable to usrmsg */ - ftdm_usrmsg_add_var(&usrmsg, "isdn.prog_ind.descr", "inband-info-available"); - - /* Request FreeTDM to send a PROCEED msg */ - ftdm_channel_call_indicate_ex(ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED, &usrmsg); - - -example #2 - Setting raw data: --------------------------------------------------------- - -When using ftmod_sangoma_isdn, user wants to transmit a custom Facility IE, inside a FACILITY message. - - ftdm_usrmsg_t usrmsg; - - uint8_t *my_facility_ie = ftdm_calloc(1, 200); /*memory has to be allocated using ftdm_calloc !! */ - unsigned my_facility_ie_len = 0; - - memset(&usrmsg, 0, sizeof(usrmsg)); - - /* Fill my_facility_ie with custom data here */ - my_facility_ie[my_facility_ie_len++] = 0x1C; /* Q.931 Facility IE ID */ - my_facility_ie[my_facility_ie_len++] = 0x03; /* Length of facility IE */ - my_facility_ie[my_facility_ie_len++] = 0x01; - my_facility_ie[my_facility_ie_len++] = 0x02; - my_facility_ie[my_facility_ie_len++] = 0x03; - - ftdm_usrmsg_set_raw_data(&usrmsg, my_facility_ie, my_facility_ie_len); - - ftdm_channel_call_indicate_ex(ftdmchan, FTDM_CHANNEL_INDICATE_FACILITY, &usrmsg); - - /* FreeTDM will automatically free my_facility_ie */ - - -2. User application receiving variables and raw buffer from FreeTDM -================================================================== - -example #1 - print all variables received from FreeTDM ------------------------------------------------------- - - /* Inside event call-back function */ - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - const char *var_name = NULL; - const char *var_value = NULL; - - /* Read all variables attached to this event */ - iter = ftdm_sigmsg_get_var_iterator(sigmsg, iter); - for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { - ftdm_get_current_var(curr, &var_name, &var_value); - fprintf("Call Variable: %s=%s\n", var_name, var_value); - } - ftdm_iterator_free(iter); - - -example #2 - accessing a specific variable ------------------------------------------- - - /* Inside event call-back function */ - char *string = NULL; - string = ftdm_sigmsg_get_var(sigmsg, "isdn.prog_ind.descr"); - if (string && *string) { - fprintf("Progress indicator:%s\n", string); - } - - -example #3a - accessing raw data -------------------------------- - - /* Inside event call-back function */ - ftdm_size_t len; - uint8_t *mydata; - if (ftdm_sigmsg_get_raw_data(sigmsg, (void**)&mydata, &len) == FTDM_SUCCESS) { - /* raw data is available, do something with mydata here */ - } - /* Once this function returns, raw data will be free'd inside FreeTDM */ - - -example #3b - accessing raw data -------------------------------- - - /* Inside event call-back function */ - ftdm_size_t len; - uint8_t *mydata; - if (ftdm_sigmsg_get_raw_data_detached(sigmsg, (void**)&mydata, &len) == FTDM_SUCCESS) { - /* raw data is available, do something with mydata here */ - - } - - : - : - : - - /* User owns raw data and is responsible for free'ing it*/ - ftdm_safe_free(mydata); - diff --git a/libs/freetdm/freetdm.2008.sln b/libs/freetdm/freetdm.2008.sln deleted file mode 100644 index 4bf2c795a6..0000000000 --- a/libs/freetdm/freetdm.2008.sln +++ /dev/null @@ -1,155 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetdm", "msvc\freetdm.2008.vcproj", "{93B8812C-3EC4-4F78-8970-FFBFC99E167D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testanalog", "msvc\testanalog\testanalog.2008.vcproj", "{BB833648-BAFF-4BE2-94DB-F8BB043C588C}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testisdn", "msvc\testisdn\testisdn.2008.vcproj", "{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_freetdm", "mod_freetdm\mod_freetdm.2008.vcproj", "{FE3540C5-3303-46E0-A69E-D92F775687F1}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog", "src\ftmod\ftmod_analog\ftmod_analog.2008.vcproj", "{37C94798-6E33-4B4F-8EE0-C72A7DC91157}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog_em", "src\ftmod\ftmod_analog_em\ftmod_analog_em.2008.vcproj", "{B3F49375-2834-4937-9D8C-4AC2EC911010}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_isdn", "src\ftmod\ftmod_isdn\ftmod_isdn.2008.vcproj", "{729344A5-D5E9-434D-8EE8-AF8C6C795D15}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_pika", "src\ftmod\ftmod_pika\ftmod_pika.2008.vcproj", "{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_wanpipe", "src\ftmod\ftmod_wanpipe\ftmod_wanpipe.2008.vcproj", "{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_sangoma_isdn", "src\ftmod\ftmod_sangoma_isdn\ftmod_sangoma_isdn.2008.vcproj", "{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_r2", "src\ftmod\ftmod_r2\ftmod_r2.2008.vcproj", "{08C3EA27-A51D-47F8-B47D-B189C649CF30}" - ProjectSection(ProjectDependencies) = postProject - {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.ActiveCfg = Debug|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.Build.0 = Debug|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.ActiveCfg = Debug|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.Build.0 = Debug|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.ActiveCfg = Release|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.Build.0 = Release|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.ActiveCfg = Release|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.Build.0 = Release|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.ActiveCfg = Debug|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.Build.0 = Debug|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.ActiveCfg = Debug|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.Build.0 = Debug|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.ActiveCfg = Release|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.Build.0 = Release|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.ActiveCfg = Release|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.Build.0 = Release|x64 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|x64.ActiveCfg = Debug|x64 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.ActiveCfg = Release|Win32 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|x64.ActiveCfg = Release|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.ActiveCfg = Debug|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.Build.0 = Debug|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.ActiveCfg = Debug|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.Build.0 = Debug|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.ActiveCfg = Release|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.Build.0 = Release|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.ActiveCfg = Release|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.Build.0 = Release|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.ActiveCfg = Debug|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.Build.0 = Debug|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.ActiveCfg = Debug|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.Build.0 = Debug|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.ActiveCfg = Release|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.Build.0 = Release|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.ActiveCfg = Release|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.Build.0 = Release|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.ActiveCfg = Debug|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.Build.0 = Debug|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.ActiveCfg = Debug|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.Build.0 = Debug|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.ActiveCfg = Release|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.Build.0 = Release|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.ActiveCfg = Release|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.Build.0 = Release|x64 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.ActiveCfg = Debug|Win32 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|x64.ActiveCfg = Debug|x64 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.ActiveCfg = Release|Win32 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|x64.ActiveCfg = Release|x64 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|Win32.ActiveCfg = Debug|Win32 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|x64.ActiveCfg = Debug|x64 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|Win32.ActiveCfg = Release|Win32 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|x64.ActiveCfg = Release|x64 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.Build.0 = Debug|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|x64.ActiveCfg = Debug|x64 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|x64.ActiveCfg = Release|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.ActiveCfg = Debug|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.ActiveCfg = Debug|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.Build.0 = Debug|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.ActiveCfg = Release|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.Build.0 = Release|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.ActiveCfg = Release|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.Build.0 = Release|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.ActiveCfg = Debug|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.ActiveCfg = Debug|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.Build.0 = Debug|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.ActiveCfg = Release|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.Build.0 = Release|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.ActiveCfg = Release|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.Build.0 = Release|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.ActiveCfg = Debug|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.ActiveCfg = Debug|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.Build.0 = Debug|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.ActiveCfg = Release|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.Build.0 = Release|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/libs/freetdm/freetdm.2010.sln b/libs/freetdm/freetdm.2010.sln deleted file mode 100644 index b6259e5960..0000000000 --- a/libs/freetdm/freetdm.2010.sln +++ /dev/null @@ -1,127 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetdm", "msvc\freetdm.2010.vcxproj", "{93B8812C-3EC4-4F78-8970-FFBFC99E167D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testanalog", "msvc\testanalog\testanalog.2010.vcxproj", "{BB833648-BAFF-4BE2-94DB-F8BB043C588C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testisdn", "msvc\testisdn\testisdn.2010.vcxproj", "{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_freetdm", "mod_freetdm\mod_freetdm.2010.vcxproj", "{FE3540C5-3303-46E0-A69E-D92F775687F1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog", "src\ftmod\ftmod_analog\ftmod_analog.2010.vcxproj", "{37C94798-6E33-4B4F-8EE0-C72A7DC91157}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog_em", "src\ftmod\ftmod_analog_em\ftmod_analog_em.2010.vcxproj", "{B3F49375-2834-4937-9D8C-4AC2EC911010}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_isdn", "src\ftmod\ftmod_isdn\ftmod_isdn.2010.vcxproj", "{729344A5-D5E9-434D-8EE8-AF8C6C795D15}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_pika", "src\ftmod\ftmod_pika\ftmod_pika.2010.vcxproj", "{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_wanpipe", "src\ftmod\ftmod_wanpipe\ftmod_wanpipe.2010.vcxproj", "{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_sangoma_isdn", "src\ftmod\ftmod_sangoma_isdn\ftmod_sangoma_isdn.2010.vcxproj", "{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_r2", "src\ftmod\ftmod_r2\ftmod_r2.2010.vcxproj", "{08C3EA27-A51D-47F8-B47D-B189C649CF30}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.ActiveCfg = Debug|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.Build.0 = Debug|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.ActiveCfg = Debug|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.Build.0 = Debug|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.ActiveCfg = Release|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.Build.0 = Release|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.ActiveCfg = Release|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.Build.0 = Release|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.ActiveCfg = Debug|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.Build.0 = Debug|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.ActiveCfg = Debug|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.Build.0 = Debug|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.ActiveCfg = Release|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.Build.0 = Release|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.ActiveCfg = Release|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.Build.0 = Release|x64 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|x64.ActiveCfg = Debug|x64 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.ActiveCfg = Release|Win32 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|x64.ActiveCfg = Release|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.ActiveCfg = Debug|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.Build.0 = Debug|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.ActiveCfg = Debug|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.Build.0 = Debug|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.ActiveCfg = Release|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.Build.0 = Release|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.ActiveCfg = Release|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.Build.0 = Release|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.ActiveCfg = Debug|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.Build.0 = Debug|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.ActiveCfg = Debug|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.Build.0 = Debug|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.ActiveCfg = Release|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.Build.0 = Release|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.ActiveCfg = Release|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.Build.0 = Release|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.ActiveCfg = Debug|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.Build.0 = Debug|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.ActiveCfg = Debug|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.Build.0 = Debug|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.ActiveCfg = Release|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.Build.0 = Release|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.ActiveCfg = Release|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.Build.0 = Release|x64 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.ActiveCfg = Debug|Win32 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|x64.ActiveCfg = Debug|x64 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.ActiveCfg = Release|Win32 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|x64.ActiveCfg = Release|x64 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|Win32.ActiveCfg = Debug|Win32 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|x64.ActiveCfg = Debug|x64 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|Win32.ActiveCfg = Release|Win32 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|x64.ActiveCfg = Release|x64 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.Build.0 = Debug|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|x64.ActiveCfg = Debug|x64 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|x64.ActiveCfg = Release|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.ActiveCfg = Debug|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.Build.0 = Debug|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.ActiveCfg = Debug|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.Build.0 = Debug|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.ActiveCfg = Release|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.Build.0 = Release|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.ActiveCfg = Release|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.Build.0 = Release|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.ActiveCfg = Debug|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.Build.0 = Debug|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.ActiveCfg = Debug|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.Build.0 = Debug|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.ActiveCfg = Release|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.Build.0 = Release|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.ActiveCfg = Release|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.Build.0 = Release|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.ActiveCfg = Debug|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.Build.0 = Debug|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.ActiveCfg = Debug|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.Build.0 = Debug|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.ActiveCfg = Release|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.Build.0 = Release|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/libs/freetdm/freetdm.2012.sln b/libs/freetdm/freetdm.2012.sln deleted file mode 100644 index 1d4c335a8d..0000000000 --- a/libs/freetdm/freetdm.2012.sln +++ /dev/null @@ -1,127 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2012 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetdm", "msvc\freetdm.2012.vcxproj", "{93B8812C-3EC4-4F78-8970-FFBFC99E167D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testanalog", "msvc\testanalog\testanalog.2012.vcxproj", "{BB833648-BAFF-4BE2-94DB-F8BB043C588C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testisdn", "msvc\testisdn\testisdn.2012.vcxproj", "{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_freetdm", "mod_freetdm\mod_freetdm.2012.vcxproj", "{FE3540C5-3303-46E0-A69E-D92F775687F1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog", "src\ftmod\ftmod_analog\ftmod_analog.2012.vcxproj", "{37C94798-6E33-4B4F-8EE0-C72A7DC91157}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog_em", "src\ftmod\ftmod_analog_em\ftmod_analog_em.2012.vcxproj", "{B3F49375-2834-4937-9D8C-4AC2EC911010}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_isdn", "src\ftmod\ftmod_isdn\ftmod_isdn.2012.vcxproj", "{729344A5-D5E9-434D-8EE8-AF8C6C795D15}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_pika", "src\ftmod\ftmod_pika\ftmod_pika.2012.vcxproj", "{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_wanpipe", "src\ftmod\ftmod_wanpipe\ftmod_wanpipe.2012.vcxproj", "{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_sangoma_isdn", "src\ftmod\ftmod_sangoma_isdn\ftmod_sangoma_isdn.2012.vcxproj", "{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_r2", "src\ftmod\ftmod_r2\ftmod_r2.2012.vcxproj", "{08C3EA27-A51D-47F8-B47D-B189C649CF30}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.ActiveCfg = Debug|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.Build.0 = Debug|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.ActiveCfg = Debug|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.Build.0 = Debug|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.ActiveCfg = Release|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.Build.0 = Release|Win32 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.ActiveCfg = Release|x64 - {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.Build.0 = Release|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.ActiveCfg = Debug|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.Build.0 = Debug|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.ActiveCfg = Debug|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.Build.0 = Debug|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.ActiveCfg = Release|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.Build.0 = Release|Win32 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.ActiveCfg = Release|x64 - {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.Build.0 = Release|x64 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|x64.ActiveCfg = Debug|x64 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.ActiveCfg = Release|Win32 - {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|x64.ActiveCfg = Release|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.ActiveCfg = Debug|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.Build.0 = Debug|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.ActiveCfg = Debug|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.Build.0 = Debug|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.ActiveCfg = Release|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.Build.0 = Release|Win32 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.ActiveCfg = Release|x64 - {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.Build.0 = Release|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.ActiveCfg = Debug|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.Build.0 = Debug|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.ActiveCfg = Debug|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.Build.0 = Debug|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.ActiveCfg = Release|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.Build.0 = Release|Win32 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.ActiveCfg = Release|x64 - {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.Build.0 = Release|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.ActiveCfg = Debug|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.Build.0 = Debug|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.ActiveCfg = Debug|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.Build.0 = Debug|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.ActiveCfg = Release|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.Build.0 = Release|Win32 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.ActiveCfg = Release|x64 - {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.Build.0 = Release|x64 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.ActiveCfg = Debug|Win32 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|x64.ActiveCfg = Debug|x64 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.ActiveCfg = Release|Win32 - {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|x64.ActiveCfg = Release|x64 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|Win32.ActiveCfg = Debug|Win32 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|x64.ActiveCfg = Debug|x64 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|Win32.ActiveCfg = Release|Win32 - {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|x64.ActiveCfg = Release|x64 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.Build.0 = Debug|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|x64.ActiveCfg = Debug|x64 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32 - {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|x64.ActiveCfg = Release|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.ActiveCfg = Debug|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.Build.0 = Debug|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.ActiveCfg = Debug|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.Build.0 = Debug|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.ActiveCfg = Release|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.Build.0 = Release|Win32 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.ActiveCfg = Release|x64 - {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.Build.0 = Release|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.ActiveCfg = Debug|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.Build.0 = Debug|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.ActiveCfg = Debug|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.Build.0 = Debug|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.ActiveCfg = Release|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.Build.0 = Release|Win32 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.ActiveCfg = Release|x64 - {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.Build.0 = Release|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.ActiveCfg = Debug|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.Build.0 = Debug|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.ActiveCfg = Debug|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.Build.0 = Debug|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.ActiveCfg = Release|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.Build.0 = Release|Win32 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64 - {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32 - {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/libs/freetdm/freetdm.pc.in b/libs/freetdm/freetdm.pc.in deleted file mode 100644 index 0b563f9840..0000000000 --- a/libs/freetdm/freetdm.pc.in +++ /dev/null @@ -1,18 +0,0 @@ -# -# FreeTDM pkg-config file -# -prefix=@prefix@ -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include -modulesdir=@modinstdir@ - -Name: FreeTDM -Description: -Version: @PACKAGE_VERSION@ -URL: http://www.openzap.org/ -Requires: -Conflicts: -Libs: -L${libdir} -lfreetdm -Libs.private: -lm -Cflags: -I${includedir} diff --git a/libs/freetdm/mkrelease.sh b/libs/freetdm/mkrelease.sh deleted file mode 100755 index b079158541..0000000000 --- a/libs/freetdm/mkrelease.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash -INSTALLPREFIX="/usr/local/freetdm" -VERSION="" -NODOCS="NO" - -for i in $* -do - case $i in - --version=*) - VERSION=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` - ;; - --prefix=*) - INSTALLPREFIX=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` - ;; - --nodocs) - NODOCS="YES" - ;; - *) - # unknown option - echo "Unknown option $i" - exit - ;; - esac -done - -if [ "x$VERSION" = "x" ] -then - echo "Provide a version number with --version=" - exit 1 -fi - -arch=$(uname -m) - -# defs -LIBSNG_ISDN_URL=ftp://ftp.sangoma.com/linux/libsng_isdn -LIBSNG_ISDN_NAME=libsng_isdn-7-current -LIBSNG_SS7_URL=ftp://ftp.sangoma.com/linux/libsng_ss7 -LIBSNG_SS7_NAME=libsng_ss7-3-current -LIBSNG_ISDN_DIR="$LIBSNG_ISDN_NAME.$arch" -LIBSNG_SS7_DIR="$LIBSNG_SS7_NAME.$arch" - -# download and decompress a tarball -# $1 = prefix_url, such as ftp://ftp.sangoma.com/foo/bar -# $2 = package name, such as libsng_isdn-7.0.0.x86_64 -function download() { - wget $1/$2.tgz - if [ $? = 0 ] - then - tardir=$(tar -tf $2.tgz | head -n1 | sed 's,\/,,g') - tar -xvzf $2.tgz || echo "FAILED to decompress $2.tgz" - if [ "$tardir" != "$2" ] - then - mv $tardir $2 || echo "FAILED to move $tardir to $2" - fi - echo "SUCCESSFULLY downloaded $2" - else - echo "FAILED to download $1/$2.tgz" - fi -} - -# download and build libsng-ss7 -fullname="$LIBSNG_ISDN_NAME.$arch" -if [ -d $fullname ] -then - echo "skipping isdn download since $fullname directory already exists ... remove if you want this step to be performed" -else - download $LIBSNG_ISDN_URL $fullname -fi - -cd $LIBSNG_ISDN_DIR -make DESTDIR=$INSTALLPREFIX install || echo "Failed to build libsng-isdn" -cd .. - -# download and build libsng-ss7 -fullname="$LIBSNG_SS7_NAME.$arch" -if [ -d $fullname ] -then - echo "skipping ss7 download since $fullname directory already exists ... remove if you want this step to be performed" -else - download $LIBSNG_SS7_URL $fullname -fi - -cd $LIBSNG_SS7_DIR -make DESTDIR=$INSTALLPREFIX install || echo "Failed to build libsng-ss7" -cd .. - -if [ ! -d $INSTALLPREFIX ] -then - mkdir -p $INSTALLPREFIX || exit 1 -fi - -if [ ! -d $INSTALLPREFIX/bin-releases ] -then - mkdir -p $INSTALLPREFIX/bin-releases || exit 1 -fi - -# attempt to compile freetdm -echo "Build freetdm and mod_freetdm now..." -make all mod_freetdm || exit 1 -echo "freetdm built OK" - -major=$(echo "$VERSION" | cut -d. -f1) -minor=$(echo "$VERSION" | cut -d. -f2) -micro=$(echo "$VERSION" | cut -d. -f3) -release="freetdm-$VERSION" - -# ABI compatibility check -if [ -x /usr/local/bin/ftdm_abi_check.py ]; then - /usr/local/bin/ftdm_abi_check.py --release_path=$(pwd) --archive_path=$INSTALLPREFIX/bin-releases --version=$VERSION - - if [ $? -ne 0 ]; then - echo "ABI compabitility test failed, not creating release. Either increment the major version number or fix the interface." - exit 1 - fi -else - echo -ne "\n\nWARNING: /usr/local/bin/ftdm_abi_check.py not found, skipping ABI compatibility test\n\n" -fi - -if [ $NODOCS = "NO" ] -then - make dox || exit 1 -fi - -echo "Creating $release ($major.$minor.$micro) at $INSTALLPREFIX/$release (directory will be removed if exists already) ... " - -mkdir -p $INSTALLPREFIX/$release $INSTALLPREFIX/bin-releases/$major/$release - -cp -r ./* $INSTALLPREFIX/bin-releases/$major/$release -cp -r ./.libs $INSTALLPREFIX/bin-releases/$major/$release - -make clean -make mod_freetdm-clean - -cp -r ./* $INSTALLPREFIX/$release - -# copy ABI compatibility reports to release -if [ -d compat_reports ]; then - mv ./compat_reports $INSTALLPREFIX/$release -fi - -rm -rf $INSTALLPREFIX/$release/{$LIBSNG_ISDN_DIR,$LIBSNG_SS7_DIR,*.tgz} -rm -rf $INSTALLPREFIX/bin-releases/$major/$release/{$LIBSNG_ISDN_DIR,$LIBSNG_SS7_DIR,*.tgz} - -tar -C $INSTALLPREFIX -czf $INSTALLPREFIX/$release.tar.gz $release/ diff --git a/libs/freetdm/mod_freetdm/CMakeLists.txt b/libs/freetdm/mod_freetdm/CMakeLists.txt deleted file mode 100644 index 25847e713f..0000000000 --- a/libs/freetdm/mod_freetdm/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# -# Arnaldo M Pereira -# -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(mod_freetdm) - -IF(NOT DEFINED WIN32) - ADD_DEFINITIONS(-g -O2 -ffast-math -Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -O0 -g -ggdb -DPACKAGE_NAME=\"freetdm\" -DPACKAGE_TARNAME=\"freetdm\" -DPACKAGE_VERSION=\"pre-alpha\" -DPACKAGE_STRING=\"freetdm\ pre-alpha\" -DPACKAGE_BUGREPORT=\"bugs@freeswitch.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"libfreetdm\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_LIBDL=1 -DHAVE_LIBPTHREAD=1 -DHAVE_LIBM=1 -DSIZEOF_LONG=8 -DHAVE_NETINET_SCTP_H=1 -DHAVE_NETDB_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_GETHOSTBYNAME_R=1) # -DDEBUG=/\*\*/) -ENDIF(NOT DEFINED WIN32) - -# includes -SET(mod_freetdm_INCLUDES - ${PROJECT_SOURCE_DIR}/../src/include - ${PROJECT_SOURCE_DIR}/../src/isdn/include - ${PROJECT_SOURCE_DIR}/../../libteletone/src - ${PROJECT_SOURCE_DIR}/../../../src/include -) -INCLUDE_DIRECTORIES(${mod_freetdm_INCLUDES}) - -LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/..) -ADD_LIBRARY(${PROJECT_NAME} SHARED mod_freetdm.c) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} freetdm -fPIC -Werror -fvisibility=hidden) - -IF(DEFINED WIN32) - SET(EXT lib) -ELSE(DEFINED WIN32) - SET(EXT so) -ENDIF(DEFINED WIN32) - -ADD_CUSTOM_COMMAND(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E rename lib${PROJECT_NAME}.${EXT} ${PROJECT_NAME}.${EXT} -) diff --git a/libs/freetdm/mod_freetdm/Makefile.in b/libs/freetdm/mod_freetdm/Makefile.in deleted file mode 100644 index 33ca03b440..0000000000 --- a/libs/freetdm/mod_freetdm/Makefile.in +++ /dev/null @@ -1,24 +0,0 @@ -FT_CFLAGS=@CFLAGS@ @COMP_VENDOR_CFLAGS@ @DEFS@ - -BASE=../../.. -FT_DIR=.. -VERBOSE=1 -FTLA=$(FT_DIR)/libfreetdm.la -LOCAL_OBJS=tdm.o -LOCAL_CFLAGS=-I$(FT_DIR)/src/include -I$(FT_DIR)/src/isdn/include $(FT_CFLAGS) -LOCAL_LDFLAGS=-L$(FT_DIR) -lfreetdm -include $(BASE)/build/modmake.rules - -local_depend: $(FTLA) - -$(FTLA): $(FT_DIR)/.update - cd $(FT_DIR) && $(MAKE) - -local_install: - cd $(FT_DIR) && $(MAKE) install - [ -f $(DESTDIR)@confdir@/autoload_configs/freetdm.conf.xml ] || cp -f $(FT_DIR)/conf/freetdm.conf.xml $(DESTDIR)@confdir@/autoload_configs - -local_clean: - cd $(FT_DIR) && $(MAKE) clean - - diff --git a/libs/freetdm/mod_freetdm/clean.sh b/libs/freetdm/mod_freetdm/clean.sh deleted file mode 100755 index 7e531ac7ff..0000000000 --- a/libs/freetdm/mod_freetdm/clean.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -rm -rf mod_freetdm.so -rm -rf .libs/mod_freetdm.so -rm -rf mod_freetdm.o -rm -rf .libs/mod_freetdm.o -rm -rf mod_freetdm.lo diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2008.vcproj b/libs/freetdm/mod_freetdm/mod_freetdm.2008.vcproj deleted file mode 100644 index 3fdd92af05..0000000000 --- a/libs/freetdm/mod_freetdm/mod_freetdm.2008.vcproj +++ /dev/null @@ -1,369 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters deleted file mode 100644 index 92ac5ead47..0000000000 --- a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c deleted file mode 100644 index 5126a3690a..0000000000 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ /dev/null @@ -1,5715 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * Moises Silva - * David Yat Sin - * James Zhang - * Gideon Sadan - * - * mod_freetdm.c -- FreeTDM Endpoint Module - * - */ -#include -#include "freetdm.h" - -//#define BACKTRACE_DEBUG - -#define FREETDM_LIMIT_REALM "__freetdm" -#define FREETDM_VAR_PREFIX "freetdm_" -#define FREETDM_VAR_PREFIX_LEN (sizeof(FREETDM_VAR_PREFIX)-1) - -/* How many consecutive IO errors before giving up */ -#define FTDM_MAX_READ_WRITE_ERRORS 10 - -#define get_ss7_config_node(_cfg, _confname) _get_ss7_config_node(cfg, confname, "ISUP") - -SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load); -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown); -SWITCH_MODULE_DEFINITION(mod_freetdm, mod_freetdm_load, mod_freetdm_shutdown, NULL); - -switch_endpoint_interface_t *freetdm_endpoint_interface; - -static switch_memory_pool_t *module_pool = NULL; - -typedef enum { - ANALOG_OPTION_NONE = 0, - ANALOG_OPTION_3WAY = (1 << 0), - ANALOG_OPTION_CALL_SWAP = (1 << 1) -} analog_option_t; - -typedef enum { - FTDM_LIMIT_RESET_ON_TIMEOUT = 0, - FTDM_LIMIT_RESET_ON_ANSWER = 1 -} limit_reset_event_t; - -typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_DTMF = (1 << 1), - TFLAG_CODEC = (1 << 2), - TFLAG_BREAK = (1 << 3), - TFLAG_HOLD = (1 << 4), - TFLAG_DEAD = (1 << 5), - TFLAG_TRANSFER = (1 << 6), -} TFLAGS; - -static struct { - int debug; - char *dialplan; - char *codec_string; - char *codec_order[SWITCH_MAX_CODECS]; - int codec_order_last; - char *codec_rates_string; - char *codec_rates[SWITCH_MAX_CODECS]; - int codec_rates_last; - unsigned int flags; - int fd; - int calls; - char hold_music[256]; - switch_mutex_t *mutex; - analog_option_t analog_options; - switch_hash_t *ss7_configs; - int sip_headers; - uint8_t crash_on_assert; - uint8_t fail_on_error; - uint8_t config_error; -} globals; - -/* private data attached to each fs session */ -struct private_object { - unsigned int flags; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_frame_t read_frame; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_frame_t cng_frame; - unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_core_session_t *session; - switch_caller_profile_t *caller_profile; - unsigned int codec; - unsigned int codecs; - unsigned short samprate; - switch_mutex_t *mutex; - switch_mutex_t *flag_mutex; - ftdm_channel_t *ftdmchan; - uint32_t write_error; - uint32_t read_error; - char network_peer_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1]; -}; - -/* private data attached to FTDM channels (only FXS for now) */ -typedef struct chan_pvt { - unsigned int flags; -} chan_pvt_t; - -typedef struct private_object private_t; - -struct span_config { - ftdm_span_t *span; - char dialplan[80]; - char context[80]; - char dial_regex[256]; - char fail_dial_regex[256]; - char hold_music[256]; - char type[256]; - analog_option_t analog_options; - const char *limit_backend; - int limit_calls; - int limit_seconds; - limit_reset_event_t limit_reset_event; - /* digital codec and digital sampling rate are used to configure the codec - * when bearer capability is set to unrestricted digital */ - const char *digital_codec; - int digital_sampling_rate; - chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN]; -}; - -static struct span_config SPAN_CONFIG[FTDM_MAX_SPANS_INTERFACE] = {{0}}; - -static switch_status_t channel_on_init(switch_core_session_t *session); -static switch_status_t channel_on_hangup(switch_core_session_t *session); -static switch_status_t channel_on_destroy(switch_core_session_t *session); -static switch_status_t channel_on_routing(switch_core_session_t *session); -static switch_status_t channel_on_exchange_media(switch_core_session_t *session); -static switch_status_t channel_on_soft_execute(switch_core_session_t *session); -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, - switch_memory_pool_t **pool, - switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); -static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name); -ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp); -void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream); -void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream); -#if 0 -void ctdm_init(switch_loadable_module_interface_t *module_interface); -#endif - -static switch_core_session_t *ftdm_channel_get_session(ftdm_channel_t *channel, int32_t id) -{ - switch_core_session_t *session = NULL; - const char *token = ftdm_channel_get_token(channel, id); - - if (!zstr(token)) { - if (!(session = switch_core_session_locate(token))) { - ftdm_channel_clear_token(channel, token); - } - } - - return session; -} - -static const char *ftdm_channel_get_uuid(ftdm_channel_t *channel, int32_t id) -{ - return ftdm_channel_get_token(channel, id); -} - -static void stop_hold(switch_core_session_t *session_a, const char *uuid) -{ - switch_core_session_t *session; - switch_channel_t *channel, *channel_a; - - if (!uuid) { - return; - } - - if ((session = switch_core_session_locate(uuid))) { - channel = switch_core_session_get_channel(session); - - if (switch_channel_test_flag(channel, CF_HOLD)) { - channel_a = switch_core_session_get_channel(session_a); - switch_ivr_unhold(session); - switch_channel_clear_flag(channel_a, CF_SUSPEND); - switch_channel_clear_flag(channel_a, CF_HOLD); - } else { - switch_channel_stop_broadcast(channel); - switch_channel_wait_for_flag(channel, CF_BROADCAST, SWITCH_FALSE, 2000, NULL); - } - - switch_core_session_rwunlock(session); - } -} - -static void start_hold(ftdm_channel_t *ftdmchan, switch_core_session_t *session_a, const char *uuid, const char *stream) -{ - switch_core_session_t *session; - switch_channel_t *channel, *channel_a; - int32_t spanid = 0; - - if (!uuid) { - return; - } - - spanid = ftdm_channel_get_span_id(ftdmchan); - if ((session = switch_core_session_locate(uuid))) { - channel = switch_core_session_get_channel(session); - if (zstr(stream)) { - if (!strcasecmp(globals.hold_music, "indicate_hold")) { - stream = "indicate_hold"; - } - if (!strcasecmp(SPAN_CONFIG[spanid].hold_music, "indicate_hold")) { - stream = "indicate_hold"; - } - } - - if (zstr(stream)) { - stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE); - } - - if (zstr(stream)) { - stream = SPAN_CONFIG[spanid].hold_music; - } - - if (zstr(stream)) { - stream = globals.hold_music; - } - - if (zstr(stream) && !(stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE))) { - stream = globals.hold_music; - } - - if (!zstr(stream)) { - if (!strcasecmp(stream, "indicate_hold")) { - channel_a = switch_core_session_get_channel(session_a); - switch_ivr_hold_uuid(uuid, NULL, 0); - switch_channel_set_flag(channel_a, CF_SUSPEND); - switch_channel_set_flag(channel_a, CF_HOLD); - } else { - switch_ivr_broadcast(switch_core_session_get_uuid(session), stream, SMF_ECHO_ALEG | SMF_LOOP); - } - } - - switch_core_session_rwunlock(session); - } -} - - -static void cycle_foreground(ftdm_channel_t *ftdmchan, int flash, const char *bcast) { - uint32_t i = 0; - switch_core_session_t *session; - switch_channel_t *channel; - private_t *tech_pvt; - uint32_t tokencnt = ftdm_channel_get_token_count(ftdmchan); - - for (i = 0; i < tokencnt; i++) { - if ((session = ftdm_channel_get_session(ftdmchan, i))) { - const char *buuid; - tech_pvt = switch_core_session_get_private(session); - channel = switch_core_session_get_channel(session); - buuid = switch_channel_get_partner_uuid(channel); - - if (tokencnt == 1 && flash) { - if (switch_test_flag(tech_pvt, TFLAG_HOLD)) { - stop_hold(session, buuid); - switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); - } else { - start_hold(ftdmchan, session, buuid, bcast); - switch_set_flag_locked(tech_pvt, TFLAG_HOLD); - } - } else if (i) { - start_hold(ftdmchan, session, buuid, bcast); - switch_set_flag_locked(tech_pvt, TFLAG_HOLD); - } else { - stop_hold(session, buuid); - switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); - if (!switch_channel_test_flag(channel, CF_ANSWERED)) { - switch_channel_mark_answered(channel); - } - } - switch_core_session_rwunlock(session); - } - } -} - -static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data) -{ - const char *dname = NULL; - uint32_t interval = 0, srate = 8000; - uint32_t span_id; - ftdm_codec_t codec; - - tech_pvt->ftdmchan = ftdmchan; - tech_pvt->read_frame.data = tech_pvt->databuf; - tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); - tech_pvt->cng_frame.data = tech_pvt->cng_databuf; - tech_pvt->cng_frame.buflen = sizeof(tech_pvt->cng_databuf); - tech_pvt->cng_frame.flags = SFF_CNG; - tech_pvt->cng_frame.codec = &tech_pvt->read_codec; - memset(tech_pvt->cng_frame.data, 255, tech_pvt->cng_frame.buflen); - switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - switch_core_session_set_private(session, tech_pvt); - tech_pvt->session = session; - - if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n"); - return SWITCH_STATUS_GENERR; - } - - span_id = ftdm_channel_get_span_id(ftdmchan); - if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED - && SPAN_CONFIG[span_id].digital_codec) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initializing digital call with codec %s at %dhz.\n", - SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate); - dname = SPAN_CONFIG[span_id].digital_codec; - srate = SPAN_CONFIG[span_id].digital_sampling_rate; - goto init_codecs; - } - - if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CODEC, &codec)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n"); - return SWITCH_STATUS_GENERR; - } - - switch (codec) { - case FTDM_CODEC_ULAW: - { - dname = "PCMU"; - } - break; - case FTDM_CODEC_ALAW: - { - dname = "PCMA"; - } - break; - case FTDM_CODEC_SLIN: - { - dname = "L16"; - } - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec); - return SWITCH_STATUS_GENERR; - } - } - -init_codecs: - - if (switch_core_codec_init(&tech_pvt->read_codec, - dname, - NULL, - NULL, - srate, - interval, - 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n"); - return SWITCH_STATUS_GENERR; - } else { - if (switch_core_codec_init(&tech_pvt->write_codec, - dname, - NULL, - NULL, - srate, - interval, - 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n"); - switch_core_codec_destroy(&tech_pvt->read_codec); - return SWITCH_STATUS_GENERR; - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set codec %s %dms\n", dname, interval); - switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec); - switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec); - switch_set_flag_locked(tech_pvt, TFLAG_CODEC); - tech_pvt->read_frame.codec = &tech_pvt->read_codec; - switch_set_flag_locked(tech_pvt, TFLAG_IO); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel; - private_t *tech_pvt = NULL; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_SUCCESS; - } - - /* Move channel's state machine to ROUTING */ - switch_channel_set_state(channel, CS_ROUTING); - switch_mutex_lock(globals.mutex); - globals.calls++; - switch_mutex_unlock(globals.mutex); - - //switch_channel_set_flag(channel, CF_ACCEPT_CNG); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_routing(switch_core_session_t *session) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch_assert(tech_pvt->ftdmchan != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel)); - - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED); - } - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_execute(switch_core_session_t *session) -{ - - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - switch_assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - switch_assert(tech_pvt != NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel)); - - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_destroy(switch_core_session_t *session) -{ - private_t *tech_pvt = NULL; - - if ((tech_pvt = switch_core_session_get_private(session))) { - - if (tech_pvt->read_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (tech_pvt->write_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - - switch_core_session_unset_read_codec(session); - switch_core_session_unset_write_codec(session); - - } - - return SWITCH_STATUS_SUCCESS; -} - -#ifdef BACKTRACE_DEBUG -struct debug_trace_priv { - const char *name; - int span_id; - int chan_id; -}; - -static void debug_trace(const int tid, const void *addr, const char *symbol, void *priv) -{ - struct debug_trace_priv *data = priv; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n", - data->span_id, data->chan_id, tid, data->name, symbol); -} -#endif - -static switch_status_t channel_on_hangup(switch_core_session_t *session) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - ftdm_chan_type_t chantype; - const char *name = NULL; - int span_id = 0; - int chan_id = 0; - uint32_t t = 0; - uint32_t tokencnt; - char *uuid = NULL; - const char *token = NULL; - uint8_t uuid_found = 0; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - /* ignore any further I/O requests, we're hanging up already! */ - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - - name = switch_channel_get_name(channel); - - span_id = tech_pvt->ftdmchan ? ftdm_channel_get_span_id(tech_pvt->ftdmchan) : 0; - chan_id = tech_pvt->ftdmchan ? ftdm_channel_get_id(tech_pvt->ftdmchan) : 0; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP ENTER\n", span_id, chan_id, name); - - /* First verify this call has a device attached */ - if (!tech_pvt->ftdmchan) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s does not have any ftdmchan attached\n", name); - goto end; - } - - /* Now verify the device is still attached to this call :-) - * Sometimes the FS core takes too long (more than 3 seconds) in calling - * channel_on_hangup() and the FreeTDM core decides to take the brute - * force approach and hangup and detach themselves from the call. Later - * when FS finally comes around, we might end up hanging up the device - * attached to another call, this verification avoids that. */ - uuid = switch_core_session_get_uuid(session); - tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan); - for (t = 0; t < tokencnt; t++) { - token = ftdm_channel_get_token(tech_pvt->ftdmchan, t); - if (!zstr(token) && !strcasecmp(uuid, token)) { - uuid_found = 1; - break; - } - } - - if (!uuid_found) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Device [%d:%d] is no longer attached to %s\n", span_id, chan_id, name); - goto end; - } - -#ifdef BACKTRACE_DEBUG - { - struct debug_trace_priv trace_data; - trace_data.name = name; - trace_data.span_id = span_id; - trace_data.chan_id = chan_id; - ftdm_backtrace_walk(&debug_trace, &trace_data); - } -#endif - - ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session)); - - chantype = ftdm_channel_get_type(tech_pvt->ftdmchan); - switch (chantype) { - case FTDM_CHAN_TYPE_FXO: - case FTDM_CHAN_TYPE_EM: - { - ftdm_channel_call_hangup(tech_pvt->ftdmchan); - } - break; - case FTDM_CHAN_TYPE_FXS: - { - tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan); - if (!ftdm_channel_call_check_busy(tech_pvt->ftdmchan) && !ftdm_channel_call_check_done(tech_pvt->ftdmchan)) { - if (tokencnt) { - cycle_foreground(tech_pvt->ftdmchan, 0, NULL); - } else { - ftdm_channel_call_hangup(tech_pvt->ftdmchan); - } - } - } - break; - case FTDM_CHAN_TYPE_CAS: - case FTDM_CHAN_TYPE_B: - { - const char *var = NULL; - switch_call_cause_t ccause = switch_channel_get_cause_q850(channel); - ftdm_call_cause_t hcause; - if (ccause < 1 || ccause > 127) { - hcause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; - } else { - hcause = (ftdm_call_cause_t)ccause; - } - var = switch_channel_get_variable(channel, "ss7_rel_loc"); - if (var) { - ftdm_usrmsg_t usrmsg; - memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t)); - ftdm_usrmsg_add_var(&usrmsg, "ss7_rel_loc", var); - ftdm_channel_call_hangup_with_cause_ex(tech_pvt->ftdmchan, hcause, &usrmsg); - } else { - ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause); - } - } - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unhandled channel type %d for channel %s\n", chantype, switch_channel_get_name(channel)); - } - break; - } - - end: - - switch_mutex_lock(globals.mutex); - globals.calls--; - if (globals.calls < 0) { - globals.calls = 0; - } - switch_mutex_unlock(globals.mutex); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP EXIT\n", span_id, chan_id, name); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - switch (sig) { - case SWITCH_SIG_KILL: - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - switch_set_flag_locked(tech_pvt, TFLAG_DEAD); - break; - case SWITCH_SIG_BREAK: - switch_set_flag_locked(tech_pvt, TFLAG_BREAK); - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_exchange_media(switch_core_session_t *session) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL EXCHANGE_MEDIA\n"); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_soft_execute(switch_core_session_t *session) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL SOFT_EXECUTE\n"); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) -{ - private_t *tech_pvt = NULL; - char tmp[2] = ""; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - tmp[0] = dtmf->digit; - ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_SEND_DTMF, tmp); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - ftdm_size_t len; - ftdm_wait_flag_t wflags = FTDM_READ; - char dtmf[128] = ""; - ftdm_status_t status; - int total_to; - int chunk, do_break = 0; - uint32_t span_id, chan_id; - const char *name = NULL; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - name = switch_channel_get_name(channel); - if (!tech_pvt->ftdmchan) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name); - return SWITCH_STATUS_FALSE; - } - - span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan); - chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan); - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id); - return SWITCH_STATUS_FALSE; - } - - /* Digium Cards sometimes timeout several times in a row here. - Yes, we support digium cards, ain't we nice....... - 6 double length intervals should compensate */ - chunk = ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 2; - total_to = chunk * 6; - - top: - - if (switch_channel_test_flag(channel, CF_SUSPEND)) { - do_break = 1; - } - - if (switch_test_flag(tech_pvt, TFLAG_BREAK)) { - switch_clear_flag_locked(tech_pvt, TFLAG_BREAK); - do_break = 1; - } - - if (switch_test_flag(tech_pvt, TFLAG_HOLD) || do_break) { - switch_yield(ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 1000); - tech_pvt->cng_frame.datalen = ftdm_channel_get_io_packet_len(tech_pvt->ftdmchan); - tech_pvt->cng_frame.samples = tech_pvt->cng_frame.datalen; - tech_pvt->cng_frame.flags = SFF_CNG; - *frame = &tech_pvt->cng_frame; - if (ftdm_channel_get_codec(tech_pvt->ftdmchan) == FTDM_CODEC_SLIN) { - tech_pvt->cng_frame.samples /= 2; - } - return SWITCH_STATUS_SUCCESS; - } - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id); - goto fail; - } - - wflags = FTDM_READ; - status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, chunk); - - if (status == FTDM_FAIL) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); - goto fail; - } - - if (status == FTDM_TIMEOUT) { - if (!switch_test_flag(tech_pvt, TFLAG_HOLD)) { - total_to -= chunk; - if (total_to <= 0) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "Too many timeouts while waiting I/O in channel %s device %d:%d!\n", name, span_id, chan_id); - goto fail; - } - } - goto top; - } - - if (!(wflags & FTDM_READ)) { - goto top; - } - - len = tech_pvt->read_frame.buflen; - if (ftdm_channel_read(tech_pvt->ftdmchan, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) { - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to read from dead channel %s device %d:%d\n", name, span_id, chan_id); - goto normal_failure; - } - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); - if (++tech_pvt->read_error > FTDM_MAX_READ_WRITE_ERRORS) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "too many I/O read errors on channel %s device %d:%d!\n", name, span_id, chan_id); - goto fail; - } - - } else { - tech_pvt->read_error = 0; - } - - *frame = &tech_pvt->read_frame; - tech_pvt->read_frame.datalen = (uint32_t)len; - tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen; - - if (ftdm_channel_get_codec(tech_pvt->ftdmchan) == FTDM_CODEC_SLIN) { - tech_pvt->read_frame.samples /= 2; - } - - while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdmchan, dtmf, sizeof(dtmf))) { - switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) }; - char *p; - for (p = dtmf; p && *p; p++) { - if (is_dtmf(*p)) { - _dtmf.digit = *p; - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id); - switch_channel_queue_dtmf(channel, &_dtmf); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -fail: - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "clearing IO in channel %s device %d:%d!\n", name, span_id, chan_id); -normal_failure: - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - return SWITCH_STATUS_GENERR; -} - -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) -{ - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - ftdm_size_t len; - unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; - const char *name = "(none)"; - ftdm_wait_flag_t wflags = FTDM_WRITE; - uint32_t span_id = 0, chan_id = 0; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - name = switch_channel_get_name(channel); - if (!tech_pvt->ftdmchan) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name); - return SWITCH_STATUS_FALSE; - } - - span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan); - chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id); - return SWITCH_STATUS_FALSE; - } - - if (switch_test_flag(tech_pvt, TFLAG_HOLD)) { - return SWITCH_STATUS_SUCCESS; - } - - if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id); - goto fail; - } - - if (switch_test_flag(frame, SFF_CNG)) { - frame->data = data; - frame->buflen = sizeof(data); - if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) { - goto fail; - } - memset(data, 255, frame->datalen); - } - - - wflags = FTDM_WRITE; - ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10); - - if (!(wflags & FTDM_WRITE)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id); - return SWITCH_STATUS_SUCCESS; - } - - len = frame->datalen; - if (ftdm_channel_write(tech_pvt->ftdmchan, frame->data, frame->buflen, &len) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id); - if (++tech_pvt->write_error > FTDM_MAX_READ_WRITE_ERRORS) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), - SWITCH_LOG_ERROR, "Too many I/O write errors on channel %s device %d:%d!\n", name, span_id, chan_id); - goto fail; - } - } else { - tech_pvt->write_error = 0; - } - - return SWITCH_STATUS_SUCCESS; - - fail: - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Error writing to channel %s device %d:%d!\n", name, span_id, chan_id); - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - return SWITCH_STATUS_GENERR; - -} - -static switch_status_t channel_receive_message_cas(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - uint32_t phy_id; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - phy_id = ftdm_channel_get_ph_id(tech_pvt->ftdmchan); - ftdm_log(FTDM_LOG_DEBUG, "Got Freeswitch message in R2 channel %d [%d]\n", phy_id, msg->message_id); - - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - return SWITCH_STATUS_SUCCESS; - } - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_RINGING: - { - ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS); - } - break; - case SWITCH_MESSAGE_INDICATE_PROGRESS: - { - ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA); - } - break; - case SWITCH_MESSAGE_INDICATE_ANSWER: - { - ftdm_channel_call_answer(tech_pvt->ftdmchan); - } - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - if (ftdm_channel_call_check_hangup(tech_pvt->ftdmchan)) { - return SWITCH_STATUS_SUCCESS; - } - - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - return SWITCH_STATUS_SUCCESS; - } - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_RINGING: - { - ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING); - } - break; - case SWITCH_MESSAGE_INDICATE_PROGRESS: - { - ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA); - } - break; - case SWITCH_MESSAGE_INDICATE_ANSWER: - { - ftdm_channel_call_answer(tech_pvt->ftdmchan); - } - break; - case SWITCH_MESSAGE_INDICATE_REDIRECT: - case SWITCH_MESSAGE_INDICATE_DEFLECT: - { - ftdm_usrmsg_t usrmsg; - const char *val = NULL; - - memset(&usrmsg, 0, sizeof(usrmsg)); - - if ((val = switch_channel_get_variable(channel, "freetdm_transfer_data"))) { - ftdm_usrmsg_add_var(&usrmsg, "transfer_data", val); - } - - switch_set_flag(tech_pvt, TFLAG_TRANSFER); - if (ftdm_channel_call_transfer_ex(tech_pvt->ftdmchan, msg->string_arg, &usrmsg) != FTDM_SUCCESS) { - switch_clear_flag(tech_pvt, TFLAG_TRANSFER); - } - while (switch_test_flag(tech_pvt, TFLAG_TRANSFER)) { - switch_yield(100000); - } - } - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message_fxo(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - return SWITCH_STATUS_SUCCESS; - } - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_PROGRESS: - case SWITCH_MESSAGE_INDICATE_ANSWER: - ftdm_channel_call_answer(tech_pvt->ftdmchan); - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message_fxs(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - switch_channel_t *channel; - private_t *tech_pvt; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = (private_t *) switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - return SWITCH_STATUS_SUCCESS; - } - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_PROGRESS: - case SWITCH_MESSAGE_INDICATE_ANSWER: - ftdm_channel_call_answer(tech_pvt->ftdmchan); - switch_channel_mark_answered(channel); - break; - case SWITCH_MESSAGE_INDICATE_RINGING: - if (!switch_channel_test_flag(channel, CF_ANSWERED) && - !switch_channel_test_flag(channel, CF_EARLY_MEDIA) && - !switch_channel_test_flag(channel, CF_RING_READY) - ) { - ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING); - switch_channel_mark_ring_ready(channel); - } - break; - default: - break; - } - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - private_t *tech_pvt; - switch_status_t status; - switch_channel_t *channel; - const char *var; - ftdm_channel_t *ftdmchan = NULL; - - tech_pvt = (private_t *) switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - channel = switch_core_session_get_channel(session); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - if (!(ftdmchan = tech_pvt->ftdmchan)) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - if (!tech_pvt->ftdmchan) { - switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE); - return SWITCH_STATUS_FALSE; - } - - switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_PROGRESS: - case SWITCH_MESSAGE_INDICATE_ANSWER: - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { - if ((var = switch_channel_get_variable(channel, "freetdm_pre_buffer_size"))) { - int tmp = atoi(var); - if (tmp > -1) { - ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp); - } - } - if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) { - ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL); - } - } - break; - case SWITCH_MESSAGE_INDICATE_UUID_CHANGE: - { - ftdm_channel_replace_token(tech_pvt->ftdmchan, msg->string_array_arg[0], msg->string_array_arg[1]); - } - break; - default: - break; - } - - switch (ftdm_channel_get_type(tech_pvt->ftdmchan)) { - case FTDM_CHAN_TYPE_FXS: - case FTDM_CHAN_TYPE_EM: - status = channel_receive_message_fxs(session, msg); - break; - case FTDM_CHAN_TYPE_FXO: - status = channel_receive_message_fxo(session, msg); - break; - case FTDM_CHAN_TYPE_B: - status = channel_receive_message_b(session, msg); - break; - case FTDM_CHAN_TYPE_CAS: - status = channel_receive_message_cas(session, msg); - break; - default: - status = SWITCH_STATUS_FALSE; - break; - } - - return status; -} - -switch_state_handler_table_t freetdm_state_handlers = { - /*.on_init */ channel_on_init, - /*.on_routing */ channel_on_routing, - /*.on_execute */ channel_on_execute, - /*.on_hangup */ channel_on_hangup, - /*.on_exchange_media */ channel_on_exchange_media, - /*.on_soft_execute */ channel_on_soft_execute, - /*.on_consume_media */ NULL, - /*.on_hibernate */ NULL, - /*.on_reset */ NULL, - /*.on_park*/ NULL, - /*.on_reporting*/ NULL, - /*.on_destroy*/ channel_on_destroy -}; - -switch_io_routines_t freetdm_io_routines = { - /*.outgoing_channel */ channel_outgoing_channel, - /*.read_frame */ channel_read_frame, - /*.write_frame */ channel_write_frame, - /*.kill_channel */ channel_kill_channel, - /*.send_dtmf */ channel_send_dtmf, - /*.receive_message*/ channel_receive_message -}; - -static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name) -{ - const char *variable = NULL; - - if (var_event) { - if ((variable = switch_event_get_header(var_event, variable_name))) { - return variable; - } - } - - if (session) { - switch_channel_t *channel = switch_core_session_get_channel(session); - if ((variable = switch_channel_get_variable(channel, variable_name))) { - return variable; - } - } - return NULL; -} - -typedef struct { - switch_event_t *var_event; - switch_core_session_t *new_session; - private_t *tech_pvt; - switch_caller_profile_t *caller_profile; -} hunt_data_t; - -static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data) -{ - uint32_t span_id, chan_id; - const char *var; - char *sess_uuid; - char name[128]; - ftdm_status_t status; - hunt_data_t *hdata = caller_data->priv; - switch_channel_t *channel = switch_core_session_get_channel(hdata->new_session); - - if ((var = switch_event_get_header(hdata->var_event, "freetdm_pre_buffer_size"))) { - int tmp = atoi(var); - if (tmp > -1) { - ftdm_channel_command(fchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp); - } - } - - span_id = ftdm_channel_get_span_id(fchan); - chan_id = ftdm_channel_get_id(fchan); - - tech_init(hdata->tech_pvt, hdata->new_session, fchan, caller_data); - - snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits); - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name); - switch_channel_set_name(channel, name); - switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(fchan)); - switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id); - switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chan_id); - - switch_channel_set_caller_profile(channel, hdata->caller_profile); - hdata->tech_pvt->caller_profile = hdata->caller_profile; - - switch_channel_set_state(channel, CS_INIT); - sess_uuid = switch_core_session_get_uuid(hdata->new_session); - status = ftdm_channel_add_token(fchan, sess_uuid, ftdm_channel_get_token_count(fchan)); - switch_assert(status == FTDM_SUCCESS); - - if (SPAN_CONFIG[span_id].limit_calls) { - char spanresource[512]; - snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(fchan), - caller_data->dnis.digits); - - ftdm_log(FTDM_LOG_DEBUG, "Adding rate limit resource on channel %d:%d (%s/%s/%d/%d)\n", - span_id, chan_id, FREETDM_LIMIT_REALM, - spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds); - - if (switch_limit_incr("hash", hdata->new_session, FREETDM_LIMIT_REALM, spanresource, - SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds) != SWITCH_STATUS_SUCCESS) { - return FTDM_BREAK; - } - } - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Attached session %s to channel %d:%d\n", sess_uuid, span_id, chan_id); - return FTDM_SUCCESS; -} - -/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines -that allocate memory or you will have 1 channel with memory allocated from another channel's pool! -*/ -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, - switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) -{ - hunt_data_t hunt_data; - const char *dest = NULL; - char *data = NULL; - int span_id = -1, group_id = -1, chan_id = 0; - switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - ftdm_status_t status; - ftdm_hunt_direction_t direction = FTDM_HUNT_BOTTOM_UP; - ftdm_caller_data_t caller_data = {{ 0 }}; - char *span_name = NULL; - switch_event_header_t *h; - char *argv[3]; - int argc = 0; - const char *var; - const char *dest_num = NULL, *callerid_num = NULL; - const char *network_peer_uuid = NULL; - char sigbridge_peer[255]; - switch_channel_t *peer_chan = NULL; - switch_channel_t *our_chan = NULL; - ftdm_hunting_scheme_t hunting; - ftdm_usrmsg_t usrmsg; - - memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t)); - memset(sigbridge_peer, 0, sizeof(sigbridge_peer)); - - if (!outbound_profile) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n"); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (zstr(outbound_profile->destination_number)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n"); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - - data = switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number); - - if (!zstr(outbound_profile->destination_number)) { - dest_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number)); - } - - if (!zstr(outbound_profile->caller_id_number)) { - callerid_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->caller_id_number)); - if ( callerid_num && *callerid_num == '+' ) { - callerid_num++; - } - } - - if (!zstr(callerid_num) && !strcmp(callerid_num, SWITCH_DEFAULT_CLID_NUMBER)) { - callerid_num = NULL; - } - - if ((argc = switch_separate_string(data, '/', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n"); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (switch_is_number(argv[0])) { - span_id = atoi(argv[0]); - } else { - span_name = argv[0]; - } - - if (*argv[1] == 'a') { - direction = FTDM_HUNT_BOTTOM_UP; - } else if (*argv[1] == 'A') { - direction = FTDM_HUNT_TOP_DOWN; - } else if (*argv[1] == 'R') { - direction = FTDM_HUNT_RR_DOWN; - } else if (*argv[1] == 'r') { - direction = FTDM_HUNT_RR_UP; - } else { - chan_id = atoi(argv[1]); - } - - if (!(dest = argv[2])) { - dest = ""; - } - - if (span_id == 0 && chan_id != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Span 0 is used to pick the first available span, selecting a channel is not supported (and doesn't make sense)\n"); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (span_id == -1 && !zstr(span_name)) { - ftdm_span_t *span; - ftdm_status_t zstatus = ftdm_span_find_by_name(span_name, &span); - if (zstatus == FTDM_SUCCESS && span) { - span_id = ftdm_span_get_id(span); - } - } - - if (span_id == -1) { - //Look for a group - ftdm_group_t *group; - ftdm_status_t zstatus = ftdm_group_find_by_name(span_name, &group); - if (zstatus == FTDM_SUCCESS && group) { - group_id = ftdm_group_get_id(group); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing ftdm span or group: %s\n", span_name); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - } - - if (group_id < 0 && chan_id < 0) { - direction = FTDM_HUNT_BOTTOM_UP; - chan_id = 0; - } - - if (session && globals.sip_headers && !switch_core_session_check_interface (session,freetdm_endpoint_interface) ) { - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *sipvar; - - network_peer_uuid = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-TransUUID"); - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerName"); - if (sipvar) { - ftdm_set_string(caller_data.cid_name, sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerNumber"); - if (sipvar) { - if ( *sipvar == '+' ) { - sipvar++; - } - ftdm_set_string(caller_data.cid_num.digits, sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI"); - if (sipvar) { - ftdm_set_string(caller_data.ani.digits, sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-TON"); - if (sipvar) { - caller_data.ani.type = (uint8_t)atoi(sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-Plan"); - if (sipvar) { - caller_data.ani.plan = (uint8_t)atoi(sipvar); - } - - /* Used by ftmod_sangoma_ss7 only */ - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-NADI"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_clg_nadi", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI2"); - if (sipvar) { - ftdm_set_string(caller_data.aniII, sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS"); - if (sipvar) { - ftdm_set_string(caller_data.dnis.digits, sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC"); - if (sipvar) { - ftdm_set_string(caller_data.loc.digits, sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Access-Transport-URLENC"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_access_transport_urlenc", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC-Screen"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_loc_screen_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC-Presentation"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_loc_pres_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC-NADI"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_loc_nadi", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-TON"); - if (sipvar) { - caller_data.dnis.type = (uint8_t)atoi(sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-Plan"); - if (sipvar) { - caller_data.dnis.plan = (uint8_t)atoi(sipvar); - } - - /* Used by ftmod_sangoma_ss7 only */ - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-NADI"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_cld_nadi", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS"); - if (sipvar) { - ftdm_set_string(caller_data.rdnis.digits, sipvar); - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_digits", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Plan"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_plan", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-NADI"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_nadi", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Screen"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_screen_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Presentation"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_pres_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_digits", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NumQual"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_numqual", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NADI"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_nadi", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Screen"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_screen_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Presentation"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_pres_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Plan"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_npi", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NumInComp"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_num_inc_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Screen"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_screen_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Presentation"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_pres_ind", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CPC"); - if (sipvar) { - ftdm_set_calling_party_category(sipvar, (uint8_t *)&caller_data.cpc); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_iam", sipvar); - } - - /* redirection information */ - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Indicator"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_indicator", sipvar); - } - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-OrigReason"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_orig", sipvar); - } - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Count"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_count", sipvar); - } - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Reason"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_reason", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn", sipvar); - } - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN-NADI"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn_nadi", sipvar); - } - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN-Plan"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn_plan", sipvar); - } - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN-Presentation"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn_pres", sipvar); - } - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM-FWD-IND-HEX"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_iam_fwd_ind_hex", sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM-NATURE-CONN-HEX"); - if (sipvar) { - ftdm_usrmsg_add_var(&usrmsg, "ss7_iam_nature_connection_hex", sipvar); - } - } - - if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) { - caller_data.screen = FTDM_SCREENING_VERIFIED_PASSED; - } - - if (switch_test_flag(outbound_profile, SWITCH_CPF_HIDE_NUMBER)) { - caller_data.pres = FTDM_PRES_RESTRICTED; - } - - if ((var = channel_get_variable(session, var_event, "freetdm_iam_fwd_ind_isdn_access_ind"))) { - ftdm_usrmsg_add_var(&usrmsg, "iam_fwd_ind_isdn_access_ind", var); - } - - if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) { - caller_data.bearer_capability = (uint8_t)atoi(var); - } - - if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) { - caller_data.bearer_layer1 = (uint8_t)atoi(var); - } - - if ((var = channel_get_variable(session, var_event, "freetdm_screening_ind"))) { - ftdm_set_screening_ind(var, &caller_data.screen); - } - - if ((var = channel_get_variable(session, var_event, "freetdm_presentation_ind"))) { - ftdm_set_presentation_ind(var, &caller_data.pres); - } - - if ((var = channel_get_variable(session, var_event, "freetdm_outbound_ton"))) { - ftdm_set_ton(var, &caller_data.dnis.type); - } else { - caller_data.dnis.type = outbound_profile->destination_number_ton; - } - - if ((var = channel_get_variable(session, var_event, "freetdm_outbound_npi"))) { - ftdm_set_npi(var, &caller_data.dnis.plan); - } else { - caller_data.dnis.plan = outbound_profile->destination_number_numplan; - } - - if ((var = channel_get_variable(session, var_event, "freetdm_calling_party_category"))) { - ftdm_set_calling_party_category(var, (uint8_t *)&caller_data.cpc); - } - - if (!zstr(dest)) { - ftdm_set_string(caller_data.dnis.digits, dest); - } - - caller_data.dnis.plan = outbound_profile->destination_number_numplan; - - /* blindly copy data from outbound_profile. They will be overwritten - * by calling ftdm_caller_data if needed after */ - caller_data.cid_num.type = outbound_profile->caller_ton; - caller_data.cid_num.plan = outbound_profile->caller_numplan; - caller_data.rdnis.type = outbound_profile->rdnis_ton; - caller_data.rdnis.plan = outbound_profile->rdnis_numplan; - - ftdm_set_string(caller_data.cid_name, outbound_profile->caller_id_name); - ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(callerid_num)); - - memset(&hunting, 0, sizeof(hunting)); - - if (group_id >= 0) { - hunting.mode = FTDM_HUNT_GROUP; - hunting.mode_data.group.group_id = group_id; - hunting.mode_data.group.direction = direction; - } else if (chan_id) { - hunting.mode = FTDM_HUNT_CHAN; - hunting.mode_data.chan.span_id = span_id; - hunting.mode_data.chan.chan_id = chan_id; - } else { - hunting.mode = FTDM_HUNT_SPAN; - hunting.mode_data.span.span_id = span_id; - hunting.mode_data.span.direction = direction; - } - - for (h = var_event->headers; h; h = h->next) { - if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) { - char *v = h->name + FREETDM_VAR_PREFIX_LEN; - if (!zstr(v)) { - if (!strcasecmp(v, "ss7_iam")) { - /* Do not print the value of ss7_iam as it is very long */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s to channel %d:%d\n", v, span_id, chan_id); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id); - } - - ftdm_usrmsg_add_var(&usrmsg, v, h->value); - } - } - } - - if ((*new_session = switch_core_session_request(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { - private_t *tech_pvt; - switch_caller_profile_t *caller_profile; - - switch_core_session_add_stream(*new_session, NULL); - if (!(tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); - switch_core_session_destroy(new_session); - cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - goto fail; - } - - our_chan = switch_core_session_get_channel(*new_session); - - switch_channel_set_flag(our_chan, CF_AUDIO); - - /* Figure out if there is a native bridge requested through SIP x headers */ - if (network_peer_uuid) { - switch_core_session_t *network_peer = switch_core_session_locate(network_peer_uuid); - if (network_peer) { - const char *my_uuid = switch_core_session_get_uuid(*new_session); - private_t *peer_private = switch_core_session_get_private(network_peer); - peer_chan = switch_core_session_get_channel(network_peer); - switch_set_string(tech_pvt->network_peer_uuid, network_peer_uuid); - switch_set_string(peer_private->network_peer_uuid, my_uuid); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session %s is network-bridged with %s\n", - my_uuid, network_peer_uuid); - - snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u", - ftdm_channel_get_span_id(peer_private->ftdmchan), ftdm_channel_get_id(peer_private->ftdmchan)); - switch_core_session_rwunlock(network_peer); - } - /* Figure out if there is a native bridge requested through dial plan variable and the originating channel is also freetdm (not going through SIP) */ - } else if (session - && (var = channel_get_variable(session, var_event, FREETDM_VAR_PREFIX "native_sigbridge")) - && switch_true(var) - && switch_core_session_compare(*new_session, session)) { - private_t *peer_pvt = switch_core_session_get_private(session); - peer_chan = switch_core_session_get_channel(session); - snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u", - ftdm_channel_get_span_id(peer_pvt->ftdmchan), ftdm_channel_get_id(peer_pvt->ftdmchan)); - } - - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num)); - caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, switch_str_nil(callerid_num)); - - hunting.result_cb = on_channel_found; - hunt_data.var_event = var_event; - hunt_data.new_session = *new_session; - hunt_data.caller_profile = caller_profile; - hunt_data.tech_pvt = tech_pvt; - caller_data.priv = &hunt_data; - - if (session && !zstr(sigbridge_peer)) { - peer_chan = switch_core_session_get_channel(session); - ftdm_usrmsg_add_var(&usrmsg, "sigbridge_peer", sigbridge_peer); - } - - if ((status = ftdm_call_place_ex(&caller_data, &hunting, &usrmsg)) != FTDM_SUCCESS) { - if (tech_pvt->read_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (tech_pvt->write_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - switch_core_session_destroy(new_session); - if (status == FTDM_BREAK || status == FTDM_EBUSY) { - cause = SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } else { - cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - goto fail; - } - - if (our_chan && peer_chan) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, - "Bridging native signaling of channel %s to channel %s\n", - switch_channel_get_name(peer_chan), switch_channel_get_name(our_chan)); - } - - return SWITCH_CAUSE_SUCCESS; - } - -fail: - return cause; -} - -static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel) -{ - if (channel) { - const char *var; - if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) { - if (switch_true(var)) { - ftdm_channel_command(fchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL); - ftdm_log(FTDM_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan)); - return; - } - } - /* the variable is not present or has a negative value then proceed to enable DTMF ... */ - } - if (ftdm_channel_command(fchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan)); - } -} - -ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp) -{ - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - const char *var_name = NULL; - const char *var_value = NULL; - uint32_t spanid, chanid; - char name[128]; - ftdm_caller_data_t *channel_caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - - *sp = NULL; - - spanid = ftdm_channel_get_span_id(sigmsg->channel); - chanid = ftdm_channel_get_id(sigmsg->channel); - - if (!(session = switch_core_session_request(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n"); - return FTDM_FAIL; - } - - /* I guess we always want DTMF detection */ - ftdm_enable_channel_dtmf(sigmsg->channel, NULL); - - switch_core_session_add_stream(session, NULL); - - tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t)); - assert(tech_pvt != NULL); - channel = switch_core_session_get_channel(session); - if (tech_init(tech_pvt, session, sigmsg->channel, channel_caller_data) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n"); - switch_core_session_destroy(&session); - return FTDM_FAIL; - } - - switch_channel_set_flag(channel, CF_AUDIO); - - channel_caller_data->collected[0] = '\0'; - - if (zstr(channel_caller_data->cid_name)) { - switch_set_string(channel_caller_data->cid_name, ftdm_channel_get_name(sigmsg->channel)); - } - - if (zstr(channel_caller_data->cid_num.digits)) { - if (!zstr(channel_caller_data->ani.digits)) { - switch_set_string(channel_caller_data->cid_num.digits, channel_caller_data->ani.digits); - } else { - switch_set_string(channel_caller_data->cid_num.digits, ftdm_channel_get_number(sigmsg->channel)); - } - } - - tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), - "FreeTDM", - SPAN_CONFIG[spanid].dialplan, - channel_caller_data->cid_name, - channel_caller_data->cid_num.digits, - NULL, - channel_caller_data->ani.digits, - channel_caller_data->aniII, - channel_caller_data->rdnis.digits, - (char *)modname, - SPAN_CONFIG[spanid].context, - channel_caller_data->dnis.digits); - - assert(tech_pvt->caller_profile != NULL); - - if (channel_caller_data->screen == 1 || channel_caller_data->screen == 3) { - switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN); - } - - tech_pvt->caller_profile->caller_ton = channel_caller_data->cid_num.type; - tech_pvt->caller_profile->caller_numplan = channel_caller_data->cid_num.plan; - tech_pvt->caller_profile->ani_ton = channel_caller_data->ani.type; - tech_pvt->caller_profile->ani_numplan = channel_caller_data->ani.plan; - tech_pvt->caller_profile->destination_number_ton = channel_caller_data->dnis.type; - tech_pvt->caller_profile->destination_number_numplan = channel_caller_data->dnis.plan; - tech_pvt->caller_profile->rdnis_ton = channel_caller_data->rdnis.type; - tech_pvt->caller_profile->rdnis_numplan = channel_caller_data->rdnis.plan; - - if (channel_caller_data->pres) { - switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER); - } - - snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", spanid, chanid, tech_pvt->caller_profile->destination_number); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect inbound channel %s\n", name); - switch_channel_set_name(channel, name); - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - - switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(sigmsg->channel)); - switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", spanid); - switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid); - switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability); - switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1); - switch_channel_set_variable_printf(channel, "freetdm_calling_party_category", ftdm_calling_party_category2str(channel_caller_data->cpc)); - switch_channel_set_variable_printf(channel, "screening_ind", ftdm_screening2str(channel_caller_data->screen)); - switch_channel_set_variable_printf(channel, "presentation_ind", ftdm_presentation2str(channel_caller_data->pres)); - - if (globals.sip_headers) { - switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel)); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-TransUUID", "%s",switch_core_session_get_uuid(session)); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ChanNumber", "%d", chanid); - - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallerName", "%s", channel_caller_data->cid_name); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallerNumber", "%s", channel_caller_data->cid_num.digits); - - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI", "%s", channel_caller_data->ani.digits); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-TON", "%d", channel_caller_data->ani.type); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-Plan", "%d", channel_caller_data->ani.plan); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI2", "%s", channel_caller_data->aniII); - - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS", "%s", channel_caller_data->dnis.digits); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-TON", "%d", channel_caller_data->dnis.type); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-Plan", "%d", channel_caller_data->dnis.plan); - - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-NADI", "%d", channel_caller_data->rdnis.type); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", ftdm_calling_party_category2str(channel_caller_data->cpc)); - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam_nature_connection_hex"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM-NATURE-CONN-HEX", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam_fwd_ind_hex"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM-FWD-IND-HEX", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_access_transport_urlenc"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Access-Transport-URLENC", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_indicator"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Indicator", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_orig"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-OrigReason", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_count"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Count", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_reason"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Reason", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_clg_nadi"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-NADI", "%s", var_value); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-NADI", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_cld_nadi"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-NADI", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_screen_ind"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Screen", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_pres_ind"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Presentation", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN", "%s", var_value); - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_numqual"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumQual", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_nadi"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NADI", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_screen_ind"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Screen", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_pres_ind"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Presentation", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_npi"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Plan", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_num_inc_ind"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumInComp", "%s", var_value); - } - } /* End - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); */ - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_cic"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CIC", "%s", var_value); - } - - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallReference", "%d", channel_caller_data->call_reference); - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_opc"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OPC", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_digits"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_screen_ind"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-Screen", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_pres_ind"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-Presentation", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_nadi"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-NADI", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn_nadi"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN-NADI", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn_plan"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN-Plan", "%s", var_value); - } - - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn_pres"); - if (!ftdm_strlen_zero(var_value)) { - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN-Presentation", "%s", var_value); - } - } - - /* Add any call variable to the dial plan */ - iter = ftdm_sigmsg_get_var_iterator(sigmsg, iter); - for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { - ftdm_get_current_var(curr, &var_name, &var_value); - snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); - switch_channel_set_variable_printf(channel, name, "%s", var_value); - if (!strcasecmp(var_name, "ss7_iam")) { - /* Do not print freetdm_ss7_iam as it is a very long variable */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s is present\n", name); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value); - } - } - ftdm_iterator_free(iter); - - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n"); - switch_core_session_destroy(&session); - return FTDM_FAIL; - } - - if (ftdm_channel_add_token(sigmsg->channel, switch_core_session_get_uuid(session), 0) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding token\n"); - switch_core_session_destroy(&session); - return FTDM_FAIL; - } - *sp = session; - - return FTDM_SUCCESS; -} - -static FIO_SIGNAL_CB_FUNCTION(on_common_signal) -{ - uint32_t chanid, spanid; - switch_event_t *event = NULL; - ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE; - - chanid = ftdm_channel_get_id(sigmsg->channel); - spanid = ftdm_channel_get_span_id(sigmsg->channel); - - switch (sigmsg->event_id) { - case FTDM_SIGEVENT_SMS: - { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - ftdm_sms_data_t *sms = (ftdm_sms_data_t*) caller_data->priv; - - ftdm_log(FTDM_LOG_INFO, "SMS received on %d:%d from %s: %s", spanid, chanid, sms->from, sms->body); - if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failed to create SMS event\n"); - return FTDM_FAIL; - } - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", sms->from); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "body", sms->body); - alarmbits = 0; - } - //return FTDM_BREAK; - break; - case FTDM_SIGEVENT_ALARM_CLEAR: - case FTDM_SIGEVENT_ALARM_TRAP: - { - if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n"); - return FTDM_FAIL; - } - if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n"); - return FTDM_FAIL; - } - if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear"); - } else { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap"); - } - } - break; - case FTDM_SIGEVENT_UP: - { - /* clear any rate limit resource for this span */ - char spanresource[512]; - if (SPAN_CONFIG[spanid].limit_reset_event == FTDM_LIMIT_RESET_ON_ANSWER && SPAN_CONFIG[spanid].limit_calls) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(sigmsg->channel), caller_data->dnis.digits); - ftdm_log(FTDM_LOG_DEBUG, "Clearing rate limit resource on channel %d:%d (%s/%s)\n", spanid, chanid, FREETDM_LIMIT_REALM, spanresource); - switch_limit_interval_reset("hash", FREETDM_LIMIT_REALM, spanresource); - } - return FTDM_SUCCESS; - } - break; - case FTDM_SIGEVENT_TRANSFER_COMPLETED: - { - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); - - switch_clear_flag_locked(tech_pvt, TFLAG_TRANSFER); - switch_channel_set_variable(channel, "freetdm_transfer_response", ftdm_transfer_response2str(sigmsg->ev_data.transfer_completed.response)); - switch_core_session_rwunlock(session); - } - return FTDM_SUCCESS; - } - break; - case FTDM_SIGEVENT_RELEASED: - case FTDM_SIGEVENT_INDICATION_COMPLETED: - case FTDM_SIGEVENT_DIALING: - { - /* Swallow these events */ - return FTDM_BREAK; - } - break; - case FTDM_SIGEVENT_STOP: - case FTDM_SIGEVENT_RESTART: - { - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; - while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - tech_pvt = switch_core_session_get_private(session); - - switch_clear_flag_locked(tech_pvt, TFLAG_TRANSFER); - switch_core_session_rwunlock(session); - return FTDM_SUCCESS; - } - } - break; - default: - return FTDM_SUCCESS; - break; - } - - if (event) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel)); - - if (alarmbits & FTDM_ALARM_RED) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red"); - } - if (alarmbits & FTDM_ALARM_YELLOW) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow"); - } - if (alarmbits & FTDM_ALARM_RAI) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai"); - } - if (alarmbits & FTDM_ALARM_BLUE) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue"); - } - if (alarmbits & FTDM_ALARM_AIS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais"); - } - if (alarmbits & FTDM_ALARM_GENERAL) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general"); - } - switch_event_fire(&event); - } - - return FTDM_BREAK; -} - -static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - ftdm_status_t status = FTDM_SUCCESS; - uint32_t spanid; - uint32_t chanid; - ftdm_caller_data_t *caller_data; - - spanid = ftdm_channel_get_span_id(sigmsg->channel); - chanid = ftdm_channel_get_id(sigmsg->channel); - caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - - ftdm_log(FTDM_LOG_DEBUG, "got FXO sig %d:%d [%s]\n", spanid, chanid, ftdm_signal_event2str(sigmsg->event_id)); - - switch (sigmsg->event_id) { - case FTDM_SIGEVENT_PROGRESS_MEDIA: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_pre_answered(channel); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_STOP: - { - private_t *tech_pvt = NULL; - while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - tech_pvt = switch_core_session_get_private(session); - switch_set_flag_locked(tech_pvt, TFLAG_DEAD); - ftdm_channel_clear_token(sigmsg->channel, 0); - channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, caller_data->hangup_cause); - ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_UP: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_answered(channel); - ftdm_enable_channel_dtmf(sigmsg->channel, channel); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_START: - { - status = ftdm_channel_from_event(sigmsg, &session); - if (status != FTDM_SUCCESS) { - ftdm_channel_call_hangup(sigmsg->channel); - } - } - break; - case FTDM_SIGEVENT_COLLECTED_DIGIT: /* Analog E&M */ - { - int span_id = ftdm_channel_get_span_id(sigmsg->channel); - char *dtmf = sigmsg->ev_data.collected.digits; - char *regex = SPAN_CONFIG[span_id].dial_regex; - char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex; - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - - if (zstr(regex)) { - regex = NULL; - } - - if (zstr(fail_regex)) { - fail_regex = NULL; - } - - ftdm_log(FTDM_LOG_DEBUG, "got DTMF sig [%s]\n", dtmf); - switch_set_string(caller_data->collected, dtmf); - - if ((regex || fail_regex) && !zstr(dtmf)) { - switch_regex_t *re = NULL; - int ovector[30]; - int match = 0; - - if (fail_regex) { - match = switch_regex_perform(dtmf, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); - status = match ? FTDM_SUCCESS : FTDM_BREAK; - switch_regex_safe_free(re); - ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs fail regex %s %s\n", dtmf, fail_regex, match ? "matched" : "did not match"); - } - - if (status == FTDM_SUCCESS && regex) { - match = switch_regex_perform(dtmf, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); - status = match ? FTDM_BREAK : FTDM_SUCCESS; - switch_regex_safe_free(re); - ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs dial regex %s %s\n", dtmf, regex, match ? "matched" : "did not match"); - } - ftdm_log(FTDM_LOG_DEBUG, "returning %s to COLLECT event with DTMF %s\n", status == FTDM_SUCCESS ? "success" : "break", dtmf); - } - } - break; - case FTDM_SIGEVENT_SIGSTATUS_CHANGED: - /* span signaling status changed ... nothing to do here .. */ - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n", - sigmsg->event_id, spanid, chanid); - } - break; - } - - return status; -} - -static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - ftdm_status_t status = FTDM_SUCCESS; - uint32_t chanid, spanid, tokencount; - - chanid = ftdm_channel_get_id(sigmsg->channel); - spanid = ftdm_channel_get_span_id(sigmsg->channel); - tokencount = ftdm_channel_get_token_count(sigmsg->channel); - - ftdm_log(FTDM_LOG_DEBUG, "got FXS sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id)); - - switch (sigmsg->event_id) { - case FTDM_SIGEVENT_UP: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_answered(channel); - ftdm_enable_channel_dtmf(sigmsg->channel, channel); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_PROGRESS: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_ring_ready(channel); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_START: - { - status = ftdm_channel_from_event(sigmsg, &session); - if (status != FTDM_SUCCESS) { - ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_BUSY); - } - } - break; - case FTDM_SIGEVENT_STOP: - { - private_t *tech_pvt = NULL; - switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; - if (tokencount) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - switch_core_session_t *session_a, *session_b, *session_t = NULL; - switch_channel_t *channel_a = NULL, *channel_b = NULL; - int digits = !zstr(caller_data->collected); - const char *br_a_uuid = NULL, *br_b_uuid = NULL; - private_t *tech_pvt = NULL; - - - if ((session_a = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 0)))) { - channel_a = switch_core_session_get_channel(session_a); - br_a_uuid = switch_channel_get_partner_uuid(channel_a); - - tech_pvt = switch_core_session_get_private(session_a); - stop_hold(session_a, switch_channel_get_partner_uuid(channel_a)); - switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); - } - - if ((session_b = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 1)))) { - channel_b = switch_core_session_get_channel(session_b); - br_b_uuid = switch_channel_get_partner_uuid(channel_b); - - tech_pvt = switch_core_session_get_private(session_b); - stop_hold(session_a, switch_channel_get_partner_uuid(channel_b)); - switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); - } - - if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND && - switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) { - - cause = SWITCH_CAUSE_ATTENDED_TRANSFER; - if (br_a_uuid && br_b_uuid) { - switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid); - } else if (br_a_uuid && digits) { - session_t = switch_core_session_locate(br_a_uuid); - } else if (br_b_uuid && digits) { - session_t = switch_core_session_locate(br_b_uuid); - } - } - - if (session_t) { - switch_ivr_session_transfer(session_t, caller_data->collected, NULL, NULL); - switch_core_session_rwunlock(session_t); - } - - if (session_a) { - switch_core_session_rwunlock(session_a); - } - - if (session_b) { - switch_core_session_rwunlock(session_b); - } - } - - while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - tech_pvt = switch_core_session_get_private(session); - switch_set_flag_locked(tech_pvt, TFLAG_DEAD); - channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, cause); - ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); - switch_core_session_rwunlock(session); - } - ftdm_channel_clear_token(sigmsg->channel, NULL); - } - break; - case FTDM_SIGEVENT_ADD_CALL: - { - cycle_foreground(sigmsg->channel, 1, NULL); - } - break; - case FTDM_SIGEVENT_FLASH: - { - chan_pvt_t *chanpvt = ftdm_channel_get_private(sigmsg->channel); - if (!chanpvt) { - ftdm_log(FTDM_LOG_ERROR, "%d:%d has no private data, can't handle FXS features! (this is a bug)\n", - chanid, spanid); - break; - } - if (ftdm_channel_call_check_hold(sigmsg->channel) && tokencount == 1) { - switch_core_session_t *session; - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - const char *buuid; - switch_channel_t *channel; - private_t *tech_pvt; - - tech_pvt = switch_core_session_get_private(session); - channel = switch_core_session_get_channel(session); - buuid = switch_channel_get_partner_uuid(channel); - ftdm_channel_call_unhold(sigmsg->channel); - stop_hold(session, buuid); - switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); - switch_core_session_rwunlock(session); - } - } else if (tokencount == 2 && (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)) { - if (switch_test_flag(chanpvt, ANALOG_OPTION_3WAY)) { - switch_clear_flag(chanpvt, ANALOG_OPTION_3WAY); - if ((session = ftdm_channel_get_session(sigmsg->channel, 1))) { - channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); - switch_core_session_rwunlock(session); - } - cycle_foreground(sigmsg->channel, 1, NULL); - } else { - char *cmd; - cmd = switch_mprintf("three_way::%s", ftdm_channel_get_token(sigmsg->channel, 0)); - switch_set_flag(chanpvt, ANALOG_OPTION_3WAY); - cycle_foreground(sigmsg->channel, 1, cmd); - free(cmd); - } - } else if ((SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_CALL_SWAP) - || (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY) - ) { - cycle_foreground(sigmsg->channel, 1, NULL); - if (tokencount == 1) { - ftdm_channel_call_hold(sigmsg->channel); - } - } - } - break; - case FTDM_SIGEVENT_COLLECTED_DIGIT: - { - int span_id = ftdm_channel_get_span_id(sigmsg->channel); - char *dtmf = sigmsg->ev_data.collected.digits; - char *regex = SPAN_CONFIG[span_id].dial_regex; - char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex; - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - - if (zstr(regex)) { - regex = NULL; - } - - if (zstr(fail_regex)) { - fail_regex = NULL; - } - - ftdm_log(FTDM_LOG_DEBUG, "got DTMF sig [%s]\n", dtmf); - switch_set_string(caller_data->collected, dtmf); - - if ((regex || fail_regex) && !zstr(dtmf)) { - switch_regex_t *re = NULL; - int ovector[30]; - int match = 0; - - if (fail_regex) { - match = switch_regex_perform(dtmf, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); - status = match ? FTDM_SUCCESS : FTDM_BREAK; - switch_regex_safe_free(re); - ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs fail regex %s %s\n", dtmf, fail_regex, match ? "matched" : "did not match"); - } - - if (status == FTDM_SUCCESS && regex) { - match = switch_regex_perform(dtmf, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); - status = match ? FTDM_BREAK : FTDM_SUCCESS; - switch_regex_safe_free(re); - ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs dial regex %s %s\n", dtmf, regex, match ? "matched" : "did not match"); - } - ftdm_log(FTDM_LOG_DEBUG, "returning %s to COLLECT event with DTMF %s\n", status == FTDM_SUCCESS ? "success" : "break", dtmf); - } - } - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n", - sigmsg->event_id, spanid, chanid); - } - break; - } - - return status; -} - -static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) -{ - uint32_t phyid, chanid, spanid; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - - phyid = ftdm_channel_get_ph_id(sigmsg->channel); - chanid = ftdm_channel_get_id(sigmsg->channel); - spanid = ftdm_channel_get_span_id(sigmsg->channel); - - ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel %d\n", ftdm_signal_event2str(sigmsg->event_id), phyid); - - if (on_common_signal(sigmsg) == FTDM_BREAK) { - return FTDM_SUCCESS; - } - - switch (sigmsg->event_id) { - case FTDM_SIGEVENT_STOP: /* on_call_disconnect from the R2 side */ - { - private_t *tech_pvt = NULL; - while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - tech_pvt = switch_core_session_get_private(session); - switch_set_flag_locked(tech_pvt, TFLAG_DEAD); - channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, caller_data->hangup_cause); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_START: /* on_call_offered from the R2 side */ - { - status = ftdm_channel_from_event(sigmsg, &session); - } - break; - case FTDM_SIGEVENT_COLLECTED_DIGIT: /* on DNIS received from the R2 forward side, return status == FTDM_BREAK to stop requesting DNIS */ - { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - int span_id = ftdm_channel_get_span_id(sigmsg->channel); - char *regex = SPAN_CONFIG[span_id].dial_regex; - char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex; - - if (zstr(regex)) { - regex = NULL; - } - - if (zstr(fail_regex)) { - fail_regex = NULL; - } - - ftdm_log(FTDM_LOG_DEBUG, "R2 DNIS so far [%s]\n", caller_data->dnis.digits); - - if ((regex || fail_regex) && !zstr(caller_data->dnis.digits)) { - switch_regex_t *re = NULL; - int ovector[30]; - int match = 0; - - if (fail_regex) { - match = switch_regex_perform(caller_data->dnis.digits, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); - status = match ? FTDM_SUCCESS : FTDM_BREAK; - switch_regex_safe_free(re); - } - - if (status == FTDM_SUCCESS && regex) { - match = switch_regex_perform(caller_data->dnis.digits, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); - status = match ? FTDM_BREAK : FTDM_SUCCESS; - } - - switch_regex_safe_free(re); - } - } - break; - case FTDM_SIGEVENT_PROGRESS: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_ring_ready(channel); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_PROGRESS_MEDIA: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_pre_answered(channel); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_UP: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_answered(channel); - ftdm_enable_channel_dtmf(sigmsg->channel, channel); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_SIGSTATUS_CHANGED: - { - ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n", - spanid, chanid, ftdm_signaling_status2str(sigstatus)); - } - break; - case FTDM_SIGEVENT_PROCEED: - case FTDM_SIGEVENT_INDICATION_COMPLETED: - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n", - sigmsg->event_id, spanid, chanid); - } - break; - } - - return status; -} - -static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) -{ - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - ftdm_caller_data_t *caller_data; - uint32_t spanid, chanid; - - ftdm_log(FTDM_LOG_DEBUG, "got clear channel sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id)); - - caller_data = ftdm_channel_get_caller_data(sigmsg->channel); - chanid = ftdm_channel_get_id(sigmsg->channel); - spanid = ftdm_channel_get_span_id(sigmsg->channel); - - if (on_common_signal(sigmsg) == FTDM_BREAK) { - return FTDM_SUCCESS; - } - - switch (sigmsg->event_id) { - case FTDM_SIGEVENT_START: - { - return ftdm_channel_from_event(sigmsg, &session); - } - break; - case FTDM_SIGEVENT_STOP: - case FTDM_SIGEVENT_RESTART: - { - private_t *tech_pvt = NULL; - while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - tech_pvt = switch_core_session_get_private(session); - switch_set_flag_locked(tech_pvt, TFLAG_DEAD); - channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, caller_data->hangup_cause); - switch_core_session_rwunlock(session); - } - } - break; - case FTDM_SIGEVENT_UP: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_answered(channel); - ftdm_enable_channel_dtmf(sigmsg->channel, channel); - switch_core_session_rwunlock(session); - } else { - const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n", - spanid, chanid, (uuid) ? uuid : "N/A"); - } - } - break; - case FTDM_SIGEVENT_PROGRESS_MEDIA: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_pre_answered(channel); - switch_core_session_rwunlock(session); - } else { - const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n", - spanid, chanid, (uuid) ? uuid : "N/A"); - } - } - break; - case FTDM_SIGEVENT_PROGRESS: - case FTDM_SIGEVENT_RINGING: - { - if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { - channel = switch_core_session_get_channel(session); - switch_channel_mark_ring_ready(channel); - switch_core_session_rwunlock(session); - } else { - const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n", - spanid, chanid, (uuid) ? uuid : "N/A"); - } - } - break; - case FTDM_SIGEVENT_SIGSTATUS_CHANGED: - { - ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n", - spanid, chanid, ftdm_signaling_status2str(sigstatus)); - } - break; - case FTDM_SIGEVENT_PROCEED: - case FTDM_SIGEVENT_FACILITY: - case FTDM_SIGEVENT_TRANSFER_COMPLETED: - /* FS does not have handlers for these messages, so ignore them for now */ - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n", - sigmsg->event_id, spanid, chanid); - } - break; - } - - return FTDM_SUCCESS; -} - -static FIO_SIGNAL_CB_FUNCTION(on_analog_signal) -{ - uint32_t spanid, chanid; - ftdm_chan_type_t type; - ftdm_status_t status = FTDM_FAIL; - - spanid = ftdm_channel_get_span_id(sigmsg->channel); - chanid = ftdm_channel_get_span_id(sigmsg->channel); - type = ftdm_channel_get_type(sigmsg->channel); - - if (on_common_signal(sigmsg) == FTDM_BREAK) { - return FTDM_SUCCESS; - } - - switch (type) { - case FTDM_CHAN_TYPE_FXO: - case FTDM_CHAN_TYPE_EM: - { - status = on_fxo_signal(sigmsg); - } - break; - case FTDM_CHAN_TYPE_FXS: - { - status = on_fxs_signal(sigmsg); - } - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled analog channel type %d for channel %d:%d\n", - type, spanid, chanid); - } - break; - } - - return status; -} - -static void ftdm_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) -{ - char *data = NULL; - va_list ap; - - va_start(ap, fmt); - - if (switch_vasprintf(&data, fmt, ap) != -1) { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, (char *)func, line, NULL, level, "%s", data); - } - if (data) { - free(data); - } - - va_end(ap); -} - -static uint32_t enable_analog_option(const char *str, uint32_t current_options) -{ - if (!strcasecmp(str, "3-way")) { - current_options |= ANALOG_OPTION_3WAY; - current_options &= ~ANALOG_OPTION_CALL_SWAP; - } else if (!strcasecmp(str, "call-swap")) { - current_options |= ANALOG_OPTION_CALL_SWAP; - current_options &= ~ANALOG_OPTION_3WAY; - } - - return current_options; -} - -#define LOAD_ERROR(...) { \ - ftdm_log(FTDM_LOG_ERROR, __VA_ARGS__); \ - globals.config_error = 1; \ - } - -/* - * Create ftdm_conf_node_t tree based on a fixed pattern XML configuration list. - * Last 2 args are for limited aka dumb recursivity. - */ -static int add_config_list_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode, - const char *list_name, const char *list_element_name, - const char *sub_list_name, const char *sub_list_element_name) -{ - char *var, *val; - switch_xml_t list; - switch_xml_t element; - switch_xml_t param; - - ftdm_conf_node_t *n_list; - ftdm_conf_node_t *n_element; - - list = switch_xml_child(swnode, list_name); - if (!list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no list %s found\n", list_name); - return -1; - } - - if ((FTDM_SUCCESS != ftdm_conf_node_create(list_name, &n_list, rootnode))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node\n", list_name); - return -1; - } - - for (element = switch_xml_child(list, list_element_name); element; element = element->next) { - char *element_name = (char *) switch_xml_attr(element, "name"); - - if (!element_name) { - continue; - } - - if ((FTDM_SUCCESS != ftdm_conf_node_create(list_element_name, &n_element, n_list))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", list_element_name, element_name); - return -1; - } - ftdm_conf_node_add_param(n_element, "name", element_name); - - for (param = switch_xml_child(element, "param"); param; param = param->next) { - var = (char *) switch_xml_attr_soft(param, "name"); - val = (char *) switch_xml_attr_soft(param, "value"); - ftdm_conf_node_add_param(n_element, var, val); - } - - if (sub_list_name && sub_list_element_name) { - if (add_config_list_nodes(element, n_element, sub_list_name, sub_list_element_name, NULL, NULL)) { - return -1; - } - } - } - - return 0; -} - -/* - * Create ftdm_conf_node_t tree based on a fixed pattern XML configuration list. - * Last arg is to specify if we have any sublist for e.g.: - * - * - * - * - * - * - * - * - * - */ -static int add_config_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode, - const char *list_name, const char *list_element_name, const char *sub_list_name) -{ - char *var, *val; - switch_xml_t list; - switch_xml_t sub_list; - switch_xml_t element; - switch_xml_t param; - - ftdm_conf_node_t *n_list; - ftdm_conf_node_t *n_element; - - list = switch_xml_child(swnode, list_name); - if (!list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no list %s found\n", list_name); - return -1; - } - - if ((FTDM_SUCCESS != ftdm_conf_node_create(list_name, &n_list, rootnode))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node\n", list_name); - return -1; - } - - for (element = switch_xml_child(list, list_element_name); element; element = element->next) { - char *element_name = (char *) switch_xml_attr(element, "name"); - - if (!element_name) { - continue; - } - - if ((FTDM_SUCCESS != ftdm_conf_node_create(list_element_name, &n_element, n_list))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", list_element_name, element_name); - return -1; - } - ftdm_conf_node_add_param(n_element, "name", element_name); - - for (param = switch_xml_child(element, "param"); param; param = param->next) { - var = (char *) switch_xml_attr_soft(param, "name"); - val = (char *) switch_xml_attr_soft(param, "value"); - ftdm_conf_node_add_param(n_element, var, val); - } - - /*If we have single node list */ - if (sub_list_name ) { - sub_list = switch_xml_child(element, sub_list_name); - if (!sub_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no sub_list %s found\n", sub_list_name); - return -1; - } - for (param = switch_xml_child(sub_list, "param"); param; param = param->next) { - var = (char *) switch_xml_attr_soft(param, "name"); - val = (char *) switch_xml_attr_soft(param, "value"); - ftdm_conf_node_add_param(n_element, var, val); - } - } - } - - return 0; -} - -static ftdm_conf_node_t *_get_ss7_config_node(switch_xml_t cfg, const char *confname, const char *operating_mode) -{ - switch_xml_t signode, ss7configs, isup, gen, param; - ftdm_conf_node_t *rootnode, *list; - char *var, *val; - int is_isup = 0x00; - - /* try to find the conf in the hash first */ - rootnode = switch_core_hash_find(globals.ss7_configs, confname); - if (rootnode) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ss7 config %s was found in the hash already\n", confname); - return rootnode; - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not found %s config in hash, searching in xml ...\n", confname); - - signode = switch_xml_child(cfg, "signaling_configs"); - if (!signode) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'signaling_configs' XML config section\n"); - return NULL; - } - - ss7configs = switch_xml_child(signode, "sngss7_configs"); - if (!ss7configs) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'sngss7_configs' XML config section\n"); - return NULL; - } - - /* sng_isup and ss7config xml childs are treated the same way. sng_isup was used initially, but does not make sense - * for configurations that do not have an ISUP layer, sng_isup is kept for backward compatibility */ - - /* search the ss7config */ - for (isup = switch_xml_child(ss7configs, "sngss7_config"); isup; isup = isup->next) { - char *name = (char *) switch_xml_attr(isup, "name"); - if (!name) { - continue; - } - if (!strcasecmp(name, confname)) { - break; - } - } - - if (!isup) { - /* search the isup config */ - for (isup = switch_xml_child(ss7configs, "sng_isup"); isup; isup = isup->next) { - char *name = (char *) switch_xml_attr(isup, "name"); - if (!name) { - continue; - } - if (!strcasecmp(name, confname)) { - break; - } - } - - if (!isup) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found '%s' ss7config or sng_isup XML config section\n", confname); - return NULL; - } - } - - /* found our XML chunk, create the root node */ - if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_isup", &rootnode, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create root node for sng_isup config %s\n", confname); - return NULL; - } - - /* operating mode , M2UA or ISUP */ - if (operating_mode && ('\0' != operating_mode[0])) { - if (!strcasecmp(operating_mode, "ISUP")) { - is_isup = 0x01; - } - else if (!strcasecmp(operating_mode, "M2UA_SG")) { - is_isup = 0x00; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid operating Mode[%s] \n", operating_mode); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Operating mode not specified, default to ISUP \n"); - is_isup = 0x01; - } - - /* add sng_gen */ - gen = switch_xml_child(isup, "sng_gen"); - if (gen == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_gen for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_gen", &list, rootnode))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", "sng_gen", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - for (param = switch_xml_child(gen, "param"); param; param = param->next) { - var = (char *) switch_xml_attr_soft(param, "name"); - val = (char *) switch_xml_attr_soft(param, "value"); - ftdm_conf_node_add_param(list, var, val); - } - - /* add relay channels */ - if (add_config_list_nodes(isup, rootnode, "sng_relay", "relay_channel", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_relay for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - /* add mtp1 links */ - if (add_config_list_nodes(isup, rootnode, "mtp1_links", "mtp1_link", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp1_links for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - /* add mtp2 links */ - if (add_config_list_nodes(isup, rootnode, "mtp2_links", "mtp2_link", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp2_links for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - if (is_isup) { - /* add mtp3 links */ - if (add_config_list_nodes(isup, rootnode, "mtp3_links", "mtp3_link", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp3_links for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - /* add mtp linksets */ - if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_linksets for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - /* add mtp routes */ - if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", "linksets", "linkset")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_routes for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - /* add isup interfaces */ - if (add_config_list_nodes(isup, rootnode, "isup_interfaces", "isup_interface", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process isup_interfaces for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - /* add cc spans */ - if (add_config_list_nodes(isup, rootnode, "cc_spans", "cc_span", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process cc_spans for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - } else { - /* add sctp links */ - if (add_config_nodes(isup, rootnode, "sng_sctp_interfaces", "sng_sctp_interface", "sng_source_addresses")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_sctp_interface for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - if (add_config_list_nodes(isup, rootnode, "sng_nif_interfaces", "sng_nif_interface", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_nif_interfaces for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - if (add_config_list_nodes(isup, rootnode, "sng_m2ua_interfaces", "sng_m2ua_interface", NULL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_interfaces for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - if (add_config_nodes(isup, rootnode, "sng_m2ua_peer_interfaces", "sng_m2ua_peer_interface", "sng_destination_addresses")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_peer_interfaces for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - - if (add_config_nodes(isup, rootnode, "sng_m2ua_cluster_interfaces", "sng_m2ua_cluster_interface", "sng_m2ua_peers")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_cluster_interfaces for sng_isup config %s\n", confname); - ftdm_conf_node_destroy(rootnode); - return NULL; - } - } - - switch_core_hash_insert(globals.ss7_configs, confname, rootnode); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added SS7 node configuration %s\n", confname); - return rootnode; -} - -static int add_profile_parameters(switch_xml_t cfg, const char *profname, ftdm_conf_parameter_t *parameters, int len) -{ - switch_xml_t profnode, profile, param; - int paramindex = 0; - - profnode = switch_xml_child(cfg, "config_profiles"); - if (!profnode) { - LOAD_ERROR("cannot find profile '%s', there is no 'config_profiles' XML section\n", profname); - return 0; - } - - /* search the profile */ - for (profile = switch_xml_child(profnode, "profile"); profile; profile = profile->next) { - char *name = (char *) switch_xml_attr(profile, "name"); - if (!name) { - continue; - } - if (!strcasecmp(name, profname)) { - break; - } - } - - if (!profile) { - LOAD_ERROR("failed to find profile '%s'\n", profname); - return 0; - } - - for (param = switch_xml_child(profile, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if (!var || !val) { - continue; - } - parameters[paramindex].var = var; - parameters[paramindex].val = val; - paramindex++; - } - - return paramindex; -} - -static void parse_gsm_spans(switch_xml_t cfg, switch_xml_t spans) -{ - switch_xml_t myspan, param; - - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; - char *id = (char *) switch_xml_attr(myspan, "id"); - char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); - ftdm_span_t *span = NULL; - uint32_t span_id = 0; - unsigned paramindex = 0; - - if (!name && !id) { - LOAD_ERROR("GSM span missing required attribute 'id' or 'name', skipping ...\n"); - continue; - } - - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - memset(spanparameters, 0, sizeof(spanparameters)); - paramindex = 0; - - if (configname) { - paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters)); - if (paramindex) { - ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id); - } - } - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) - 1 == paramindex) { - LOAD_ERROR("Too many parameters for GSM span, ignoring any parameter after %s\n", var); - break; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - if (ftdm_configure_span_signaling(span, - "gsm", - on_clear_channel_signal, - spanparameters) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring Sangoma GSM FreeTDM span %d\n", span_id); - continue; - } - - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "GSM", sizeof(SPAN_CONFIG[span_id].type)); - - ftdm_log(FTDM_LOG_DEBUG, "Configured GSM FreeTDM span %d\n", span_id); - ftdm_span_start(span); - } -} - -static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans) -{ - switch_xml_t myspan, param; - - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; - char *id = (char *) switch_xml_attr(myspan, "id"); - char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); - ftdm_span_t *span = NULL; - uint32_t span_id = 0; - unsigned paramindex = 0; - - if (!name && !id) { - LOAD_ERROR("sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n"); - continue; - } - - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - memset(spanparameters, 0, sizeof(spanparameters)); - paramindex = 0; - - if (configname) { - paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters)); - if (paramindex) { - ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id); - } - } - - /* some defaults first */ - SPAN_CONFIG[span_id].limit_backend = "hash"; - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT; - SPAN_CONFIG[span_id].digital_sampling_rate = 8000; - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) - 1 == paramindex) { - LOAD_ERROR("Too many parameters for ss7 span, ignoring any parameter after %s\n", var); - break; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "unrestricted-digital-codec")) { - //switch_core_strdup(pool, val); - const switch_codec_implementation_t *codec = NULL; - int num_codecs; - num_codecs = switch_loadable_module_get_codecs_sorted(&codec, NULL, 1, &val, 1); - if (num_codecs != 1 || !codec) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Failed finding codec %s for unrestricted digital calls\n", val); - } else { - SPAN_CONFIG[span_id].digital_codec = switch_core_strdup(module_pool, codec->iananame); - SPAN_CONFIG[span_id].digital_sampling_rate = codec->samples_per_second; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Unrestricted digital codec is %s at %dhz for span %d\n", - SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate, span_id); - } - } else if (!strcasecmp(var, "call_limit_backend")) { - SPAN_CONFIG[span_id].limit_backend = val; - ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id); - } else if (!strcasecmp(var, "call_limit_rate")) { - int calls; - int seconds; - if (sscanf(val, "%d/%d", &calls, &seconds) != 2) { - LOAD_ERROR("Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var); - } else { - if (calls < 1 || seconds < 1) { - LOAD_ERROR("Invalid %s parameter value, minimum call limit must be 1 per second\n", var); - } else { - SPAN_CONFIG[span_id].limit_calls = calls; - SPAN_CONFIG[span_id].limit_seconds = seconds; - } - } - } else if (!strcasecmp(var, "call_limit_reset_event")) { - if (!strcasecmp(val, "answer")) { - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER; - } else { - LOAD_ERROR("Invalid %s parameter value, only accepted event is 'answer'\n", var); - } - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - if (ftdm_configure_span_signaling(span, - "sangoma_isdn", - on_clear_channel_signal, - spanparameters) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring Sangoma ISDN FreeTDM span %d\n", span_id); - continue; - } - - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type)); - - ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id); - ftdm_span_start(span); - } -} -static switch_status_t load_config_path(void) -{ - const char *cf = "freetdm.conf"; - switch_xml_t cfg, xml, settings, param; - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); - return SWITCH_STATUS_TERM; - } - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "mod-dir")) { - ftdm_global_set_mod_directory(val); - } else if (!strcasecmp(var, "conf-dir")) { - ftdm_global_set_config_directory(val); - } - } - } - - switch_xml_free(xml); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t load_config(void) -{ - const char *cf = "freetdm.conf"; - switch_xml_t cfg, xml, settings, param, spans, myspan; - ftdm_conf_node_t *ss7confnode = NULL; - unsigned int i = 0; - ftdm_channel_t *fchan = NULL; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - memset(&globals, 0, sizeof(globals)); - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); - - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); - return SWITCH_STATUS_TERM; - } - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "debug")) { - globals.debug = atoi(val); - } else if (!strcasecmp(var, "hold-music")) { - switch_set_string(globals.hold_music, val); - } else if (!strcasecmp(var, "crash-on-assert")) { - globals.crash_on_assert = (uint8_t)switch_true(val); - } else if (!strcasecmp(var, "fail-on-error")) { - globals.fail_on_error = (uint8_t)switch_true(val); - } else if (!strcasecmp(var, "sip-headers")) { - globals.sip_headers = switch_true(val); - } else if (!strcasecmp(var, "enable-analog-option")) { - globals.analog_options = enable_analog_option(val, globals.analog_options); - } - } - } - - if ((spans = switch_xml_child(cfg, "sangoma_pri_spans"))) { - parse_bri_pri_spans(cfg, spans); - } - - if ((spans = switch_xml_child(cfg, "sangoma_bri_spans"))) { - parse_bri_pri_spans(cfg, spans); - } - - if ((spans = switch_xml_child(cfg, "gsm_spans"))) { - parse_gsm_spans(cfg, spans); - } - - switch_core_hash_init(&globals.ss7_configs); - if ((spans = switch_xml_child(cfg, "sangoma_ss7_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; - char *id = (char *) switch_xml_attr(myspan, "id"); - char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); - char *operating_mode = (char *) switch_xml_attr(myspan, "operating_mode"); - ftdm_span_t *span = NULL; - uint32_t span_id = 0; - unsigned paramindex = 0; - if (!name && !id) { - LOAD_ERROR("ss7 span missing required attribute 'id' or 'name', skipping ...\n"); - continue; - } - if (!configname) { - LOAD_ERROR("ss7 span missing required attribute, skipping ...\n"); - continue; - } - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - ss7confnode = _get_ss7_config_node(cfg, configname, operating_mode); - if (!ss7confnode) { - LOAD_ERROR("Error finding ss7config '%s' for FreeTDM span id: %s\n", configname, switch_str_nil(id)); - continue; - } - - memset(spanparameters, 0, sizeof(spanparameters)); - paramindex = 0; - - if (operating_mode) { - spanparameters[paramindex].var = "operating-mode"; - spanparameters[paramindex].val = operating_mode; - paramindex++; - } - - spanparameters[paramindex].var = "confnode"; - spanparameters[paramindex].ptr = ss7confnode; - paramindex++; - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) - 1 == paramindex) { - LOAD_ERROR("Too many parameters for ss7 span, ignoring any parameter after %s\n", var); - break; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - if (ftdm_configure_span_signaling(span, - "sangoma_ss7", - on_clear_channel_signal, - spanparameters) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring ss7 FreeTDM span %d\n", span_id); - continue; - } - - SPAN_CONFIG[span_id].span = span; - - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (SS7)", sizeof(SPAN_CONFIG[span_id].type)); - - ftdm_log(FTDM_LOG_DEBUG, "Configured ss7 FreeTDM span %d with config node %s\n", span_id, configname); - - if (FTDM_SUCCESS != ftdm_span_start(span)) { - LOAD_ERROR("Error Starting ss7 FreeTDM span %d\n", span_id); - continue; - } - } - } - - if ((spans = switch_xml_child(cfg, "analog_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - char *id = (char *) switch_xml_attr(myspan, "id"); - char *name = (char *) switch_xml_attr(myspan, "name"); - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - const char *tonegroup = NULL; - char *digit_timeout = NULL; - char *max_digits = NULL; - char *hotline = NULL; - char *dial_regex = NULL; - char *hold_music = NULL; - char *fail_dial_regex = NULL; - const char *enable_callerid = "true"; - const char *answer_polarity = "false"; - const char *hangup_polarity = "false"; - const char *polarity_callerid = "false"; - int polarity_delay = 600; - int callwaiting = 1; - int dialtone_timeout = 5000; - - uint32_t span_id = 0, to = 0, max = 0; - ftdm_span_t *span = NULL; - analog_option_t analog_options = ANALOG_OPTION_NONE; - - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - /* some defaults first */ - SPAN_CONFIG[span_id].limit_backend = "hash"; - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT; - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "analog_spans var = %s\n", var); - if (!strcasecmp(var, "tonegroup")) { - tonegroup = val; - } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) { - digit_timeout = val; - } else if (!strcasecmp(var, "wait-dialtone-timeout")) { - dialtone_timeout = atoi(val); - } else if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "call_limit_backend")) { - SPAN_CONFIG[span_id].limit_backend = val; - ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id); - } else if (!strcasecmp(var, "call_limit_rate")) { - int calls; - int seconds; - if (sscanf(val, "%d/%d", &calls, &seconds) != 2) { - LOAD_ERROR("Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var); - } else { - if (calls < 1 || seconds < 1) { - LOAD_ERROR("Invalid %s parameter value, minimum call limit must be 1 per second\n", var); - } else { - SPAN_CONFIG[span_id].limit_calls = calls; - SPAN_CONFIG[span_id].limit_seconds = seconds; - } - } - } else if (!strcasecmp(var, "call_limit_reset_event")) { - if (!strcasecmp(val, "answer")) { - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER; - } else { - LOAD_ERROR("Invalid %s parameter value, only accepted event is 'answer'\n", var); - } - } else if (!strcasecmp(var, "dial-regex")) { - dial_regex = val; - } else if (!strcasecmp(var, "enable-callerid")) { - enable_callerid = val; - } else if (!strcasecmp(var, "answer-polarity-reverse")) { - answer_polarity = val; - } else if (!strcasecmp(var, "hangup-polarity-reverse")) { - hangup_polarity = val; - } else if (!strcasecmp(var, "polarity-delay")) { - polarity_delay = atoi(val); - } else if (!strcasecmp(var, "polarity-callerid")) { - polarity_callerid = val; - } else if (!strcasecmp(var, "fail-dial-regex")) { - fail_dial_regex = val; - } else if (!strcasecmp(var, "hold-music")) { - hold_music = val; - } else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) { - max_digits = val; - } else if (!strcasecmp(var, "hotline")) { - hotline = val; - } else if (!strcasecmp(var, "callwaiting")) { - callwaiting = switch_true(val) ? 1 : 0; - } else if (!strcasecmp(var, "enable-analog-option")) { - analog_options = enable_analog_option(val, analog_options); - } - } - - if (!id && !name) { - LOAD_ERROR("span missing required param 'id'\n"); - continue; - } - - if (!tonegroup) { - tonegroup = "us"; - } - - if (digit_timeout) { - to = atoi(digit_timeout); - } - - if (max_digits) { - max = atoi(max_digits); - } - - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - if (ftdm_configure_span(span, "analog", on_analog_signal, - "tonemap", tonegroup, - "digit_timeout", &to, - "max_dialstr", &max, - "hotline", hotline ? hotline : "", - "enable_callerid", enable_callerid, - "answer_polarity_reverse", answer_polarity, - "hangup_polarity_reverse", hangup_polarity, - "polarity_callerid", polarity_callerid, - "polarity_delay", &polarity_delay, - "callwaiting", &callwaiting, - "wait_dialtone_timeout", &dialtone_timeout, - FTDM_TAG_END) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span)); - continue; - } - - SPAN_CONFIG[span_id].span = span; - switch_set_string(SPAN_CONFIG[span_id].context, context); - switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan); - SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options; - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - fchan = ftdm_iterator_current(curr); - ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]); - } - ftdm_iterator_free(chaniter); - - if (dial_regex) { - switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex); - } - - if (fail_dial_regex) { - switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex); - } - - if (hold_music) { - switch_set_string(SPAN_CONFIG[span_id].hold_music, hold_music); - } - switch_copy_string(SPAN_CONFIG[span_id].type, "analog", sizeof(SPAN_CONFIG[span_id].type)); - ftdm_span_start(span); - } - } - - if ((spans = switch_xml_child(cfg, "analog_em_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - char *id = (char *) switch_xml_attr(myspan, "id"); - char *name = (char *) switch_xml_attr(myspan, "name"); - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - const char *tonegroup = NULL; - char *digit_timeout = NULL; - char *dial_timeout = NULL; - char *release_guard_time_ms = NULL; - char *max_digits = NULL; - char *dial_regex = NULL; - char *hold_music = NULL; - char *fail_dial_regex = NULL; - char str_false[] = "false"; - char str_empty[] = ""; - char *answer_supervision = str_false; - char *immediate_ringback = str_false; - char *ringback_file = str_empty; - uint32_t span_id = 0, to = 0, max = 0, dial_timeout_int = 0, release_guard_time_ms_int = 0; - ftdm_span_t *span = NULL; - analog_option_t analog_options = ANALOG_OPTION_NONE; - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "tonegroup")) { - tonegroup = val; - } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) { - digit_timeout = val; - } else if (!strcasecmp(var, "dial-timeout")) { - dial_timeout = val; - } else if (!strcasecmp(var, "release-guard-time-ms")) { - release_guard_time_ms = val; - } else if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "dial-regex")) { - dial_regex = val; - } else if (!strcasecmp(var, "fail-dial-regex")) { - fail_dial_regex = val; - } else if (!strcasecmp(var, "hold-music")) { - hold_music = val; - } else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) { - max_digits = val; - } else if (!strcasecmp(var, "answer-supervision")) { - answer_supervision = val; - } else if (!strcasecmp(var, "immediate-ringback")) { - immediate_ringback = val; - } else if (!strcasecmp(var, "ringback-file")) { - ringback_file = val; - } else if (!strcasecmp(var, "enable-analog-option")) { - analog_options = enable_analog_option(val, analog_options); - } - } - - if (!id && !name) { - LOAD_ERROR("span missing required param 'id'\n"); - continue; - } - - if (!tonegroup) { - tonegroup = "us"; - } - - if (digit_timeout) { - to = atoi(digit_timeout); - } - - if (dial_timeout) { - dial_timeout_int = atoi(dial_timeout); - } - - if (release_guard_time_ms) { - release_guard_time_ms_int = atoi(release_guard_time_ms); - } - - if (max_digits) { - max = atoi(max_digits); - } - - - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - - if (ftdm_configure_span(span, "analog_em", on_analog_signal, - "tonemap", tonegroup, - "answer_supervision", answer_supervision, - "immediate_ringback", immediate_ringback, - "ringback_file", ringback_file, - "digit_timeout", &to, - "dial_timeout", &dial_timeout_int, - "release_guard_time_ms", &release_guard_time_ms_int, - "max_dialstr", &max, - FTDM_TAG_END) != FTDM_SUCCESS) { - LOAD_ERROR("Error starting FreeTDM span %d\n", span_id); - continue; - } - - SPAN_CONFIG[span_id].span = span; - switch_set_string(SPAN_CONFIG[span_id].context, context); - switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan); - SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options; - - if (dial_regex) { - switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex); - } - - if (fail_dial_regex) { - switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex); - } - - if (hold_music) { - switch_set_string(SPAN_CONFIG[span_id].hold_music, hold_music); - } - switch_copy_string(SPAN_CONFIG[span_id].type, "analog_em", sizeof(SPAN_CONFIG[span_id].type)); - ftdm_span_start(span); - } - } - - if ((spans = switch_xml_child(cfg, "pri_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - char *name = (char *) switch_xml_attr(myspan, "name"); - ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - unsigned paramindex = 0; - ftdm_span_t *span = NULL; - uint32_t span_id = 0; - - if (!name) { - LOAD_ERROR("span missing required attribute 'name'\n"); - continue; - } - - memset(spanparameters, 0, sizeof(spanparameters)); - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) - 1 == paramindex) { - LOAD_ERROR("Too many parameters for pri span '%s', ignoring everything after '%s'\n", name, var); - break; - } - - if (ftdm_strlen_zero(var) || ftdm_strlen_zero(val)) { - ftdm_log(FTDM_LOG_WARNING, "Skipping parameter with empty name or value\n"); - continue; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - zstatus = ftdm_span_find_by_name(name, &span); - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span %s\n", name); - continue; - } - - span_id = ftdm_span_get_id(span); - if (ftdm_configure_span_signaling(span, "isdn", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring FreeTDM span %s\n", name); - continue; - } - - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type)); - - ftdm_span_start(span); - } - } - - if ((spans = switch_xml_child(cfg, "pritap_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - - char *name = (char *) switch_xml_attr(myspan, "name"); - - ftdm_status_t zstatus = FTDM_FAIL; - unsigned paramindex = 0; - ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; - const char *context = "default"; - const char *dialplan = "XML"; - ftdm_span_t *span = NULL; - int span_id = 0; - - if (!name) { - LOAD_ERROR("span missing required attribute 'name'\n"); - continue; - } - - memset(spanparameters, 0, sizeof(spanparameters)); - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) - 1 == paramindex) { - LOAD_ERROR("Too many parameters for pritap span '%s', ignoring everything after '%s'\n", name, var); - break; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - zstatus = ftdm_span_find_by_name(name, &span); - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span %s\n", name); - continue; - } - - span_id = ftdm_span_get_id(span); - if (ftdm_configure_span_signaling(span, "pritap", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring FreeTDM span %s\n", name); - continue; - } - - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type)); - - ftdm_span_start(span); - } - } - - - if ((spans = switch_xml_child(cfg, "libpri_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - char *name = (char *) switch_xml_attr(myspan, "name"); - ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - unsigned paramindex = 0; - ftdm_span_t *span = NULL; - uint32_t span_id = 0; - - if (!name) { - LOAD_ERROR("span missing required attribute 'name'\n"); - continue; - } - - memset(spanparameters, 0, sizeof(spanparameters)); - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) - 1 == paramindex) { - LOAD_ERROR("Too many parameters for libpri span, ignoring everything after '%s'\n", var); - break; - } - - if (ftdm_strlen_zero(var) || ftdm_strlen_zero(val)) { - ftdm_log(FTDM_LOG_WARNING, "Skipping parameter with empty name or value\n"); - continue; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - zstatus = ftdm_span_find_by_name(name, &span); - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM span %s\n", name); - continue; - } - - span_id = ftdm_span_get_id(span); - if (ftdm_configure_span_signaling(span, "libpri", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring FreeTDM span %s\n", name); - continue; - } - - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type)); - - ftdm_span_start(span); - } - } - - if ((spans = switch_xml_child(cfg, "r2_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); - ftdm_status_t zstatus = FTDM_FAIL; - - /* common non r2 stuff */ - const char *context = "default"; - const char *dialplan = "XML"; - char *dial_regex = NULL; - char *fail_dial_regex = NULL; - uint32_t span_id = 0; - ftdm_span_t *span = NULL; - - ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS]; - unsigned paramindex = 0; - - if (!name) { - LOAD_ERROR("'name' attribute required for R2 spans!\n"); - continue; - } - - memset(spanparameters, 0, sizeof(spanparameters)); - - if (configname) { - paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters)); - if (paramindex) { - ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id); - } - } - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - /* string parameters */ - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "dial-regex")) { - dial_regex = val; - } else if (!strcasecmp(var, "fail-dial-regex")) { - fail_dial_regex = val; - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - zstatus = ftdm_span_find_by_name(name, &span); - if (zstatus != FTDM_SUCCESS) { - LOAD_ERROR("Error finding FreeTDM R2 Span '%s'\n", name); - continue; - } - span_id = ftdm_span_get_id(span); - - if (ftdm_configure_span_signaling(span, "r2", on_r2_signal, spanparameters) != FTDM_SUCCESS) { - LOAD_ERROR("Error configuring FreeTDM R2 span %s, error: %s\n", name, ftdm_span_get_last_error(span)); - continue; - } - - if (dial_regex) { - switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex); - } - - if (fail_dial_regex) { - switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex); - } - - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "R2", sizeof(SPAN_CONFIG[span_id].type)); - - if (ftdm_span_start(span) == FTDM_FAIL) { - LOAD_ERROR("Error starting FreeTDM R2 span %s, error: %s\n", name, ftdm_span_get_last_error(span)); - continue; - } - } - } - - if (globals.crash_on_assert) { - ftdm_log(FTDM_LOG_WARNING, "Crash on assert enabled\n"); - ftdm_global_set_crash_policy(FTDM_CRASH_ON_ASSERT); - } - - switch_xml_free(xml); - - if (globals.fail_on_error && globals.config_error) { - ftdm_log(FTDM_LOG_ERROR, "Refusing to load module with errors\n"); - return SWITCH_STATUS_TERM; - } - - return SWITCH_STATUS_SUCCESS; -} - -void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream) -{ - uint32_t span_id; - uint32_t phspan_id, phchan_id; - const char *chan_type; - const char *state; - const char *last_state; - const char *uuid = NULL; - char sessionid[255]; - float txgain, rxgain; - switch_core_session_t *session = NULL; - ftdm_alarm_flag_t alarmflag; - ftdm_caller_data_t *caller_data; - ftdm_channel_t *ftdmchan; - ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; - - if (chan_id > ftdm_span_get_chan_count(span)) { - return; - } - - strcpy(sessionid, "(none)"); - ftdmchan = ftdm_span_get_channel(span, chan_id); - span_id = ftdm_span_get_id(span); - - phspan_id = ftdm_channel_get_ph_span_id(ftdmchan); - phchan_id = ftdm_channel_get_ph_id(ftdmchan); - chan_type = ftdm_chan_type2str(ftdm_channel_get_type(ftdmchan)); - state = ftdm_channel_get_state_str(ftdmchan); - last_state = ftdm_channel_get_last_state_str(ftdmchan); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_RX_GAIN, &rxgain); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_TX_GAIN, &txgain); - caller_data = ftdm_channel_get_caller_data(ftdmchan); - ftdm_channel_get_sig_status(ftdmchan, &sigstatus); - ftdm_channel_get_alarms(ftdmchan, &alarmflag); - - uuid = ftdm_channel_get_uuid(ftdmchan, 0); - if (!zstr(uuid)) { - if (!(session = switch_core_session_locate(uuid))) { - snprintf(sessionid, sizeof(sessionid), "%s (dead)", uuid); - } else { - snprintf(sessionid, sizeof(sessionid), "%s", uuid); - switch_core_session_rwunlock(session); - } - } - - stream->write_function(stream, - "span_id: %u\n" - "chan_id: %u\n" - "physical_span_id: %u\n" - "physical_chan_id: %u\n" - "physical_status: %s\n" - "physical_status_red: %d\n" - "physical_status_yellow: %d\n" - "physical_status_rai: %d\n" - "physical_status_blue: %d\n" - "physical_status_ais: %d\n" - "physical_status_general: %d\n" - "signaling_status: %s\n" - "type: %s\n" - "state: %s\n" - "last_state: %s\n" - "txgain: %3.2f\n" - "rxgain: %3.2f\n" - "cid_date: %s\n" - "cid_name: %s\n" - "cid_num: %s\n" - "ani: %s\n" - "aniII: %s\n" - "dnis: %s\n" - "rdnis: %s\n" - "cause: %s\n" - "session: %s\n\n", - span_id, - chan_id, - phspan_id, - phchan_id, - alarmflag ? "alarmed" : "ok", - (alarmflag & FTDM_ALARM_RED) ? 1 : 0, - (alarmflag & FTDM_ALARM_YELLOW) ? 1 : 0, - (alarmflag & FTDM_ALARM_RAI) ? 1 : 0, - (alarmflag & FTDM_ALARM_BLUE) ? 1 : 0, - (alarmflag & FTDM_ALARM_AIS) ? 1 : 0, - (alarmflag & FTDM_ALARM_GENERAL) ? 1 : 0, - ftdm_signaling_status2str(sigstatus), - chan_type, - state, - last_state, - txgain, - rxgain, - caller_data->cid_date, - caller_data->cid_name, - caller_data->cid_num.digits, - caller_data->ani.digits, - caller_data->aniII, - caller_data->dnis.digits, - caller_data->rdnis.digits, - switch_channel_cause2str(caller_data->hangup_cause), - sessionid); -} - -void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream) -{ - uint32_t span_id; - uint32_t phspan_id, phchan_id; - const char *chan_type; - const char *state; - const char *last_state; - float txgain, rxgain; - ftdm_caller_data_t *caller_data; - ftdm_channel_t *ftdmchan; - ftdm_alarm_flag_t alarmflag; - ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; - - if (chan_id > ftdm_span_get_chan_count(span)) { - return; - } - - ftdmchan = ftdm_span_get_channel(span, chan_id); - span_id = ftdm_span_get_id(span); - - phspan_id = ftdm_channel_get_ph_span_id(ftdmchan); - phchan_id = ftdm_channel_get_ph_id(ftdmchan); - chan_type = ftdm_chan_type2str(ftdm_channel_get_type(ftdmchan)); - state = ftdm_channel_get_state_str(ftdmchan); - last_state = ftdm_channel_get_last_state_str(ftdmchan); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_RX_GAIN, &rxgain); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_TX_GAIN, &txgain); - caller_data = ftdm_channel_get_caller_data(ftdmchan); - ftdm_channel_get_sig_status(ftdmchan, &sigstatus); - ftdm_channel_get_alarms(ftdmchan, &alarmflag); - - - stream->write_function(stream, - " \n" - " %u\n" - " %u>\n" - " %u\n" - " %u\n" - " %s\n" - " %d\n" - " %d\n" - " %d\n" - " %d\n" - " %d\n" - " %d\n" - " %s\n" - " %s\n" - " %s\n" - " %s\n" - " %3.2f\n" - " %3.2f\n" - " %s\n" - " %s\n" - " %s\n" - " %s\n" - " %s\n" - " %s\n" - " %s\n" - " %s\n" - " \n", - span_id, - chan_id, - phspan_id, - phchan_id, - alarmflag ? "alarmed" : "ok", - (alarmflag & FTDM_ALARM_RED) ? 1 : 0, - (alarmflag & FTDM_ALARM_YELLOW) ? 1 : 0, - (alarmflag & FTDM_ALARM_RAI) ? 1 : 0, - (alarmflag & FTDM_ALARM_BLUE) ? 1 : 0, - (alarmflag & FTDM_ALARM_AIS) ? 1 : 0, - (alarmflag & FTDM_ALARM_GENERAL) ? 1 : 0, - ftdm_signaling_status2str(sigstatus), - chan_type, - state, - last_state, - txgain, - rxgain, - caller_data->cid_date, - caller_data->cid_name, - caller_data->cid_num.digits, - caller_data->ani.digits, - caller_data->aniII, - caller_data->dnis.digits, - caller_data->rdnis.digits, - switch_channel_cause2str(caller_data->hangup_cause)); -} - -typedef struct ftdm_cli_entry ftdm_cli_entry_t; -typedef switch_status_t (*ftdm_cli_function_t)(ftdm_cli_entry_t *cli, const char *cmd, switch_core_session_t *session, - switch_stream_handle_t *stream, int argc, char *argv[]); -#define FTDM_CLI_DECLARE(name) static switch_status_t name(ftdm_cli_entry_t *cli, const char *cmd, \ - switch_core_session_t *session, switch_stream_handle_t *stream, \ - int argc, char *argv[]) -static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli); - - -typedef struct cmd_ioread_data { - int num_times; - uint32_t interval; - ftdm_span_t *span; - ftdm_channel_t *fchan; - switch_memory_pool_t *pool; - int already_open; -} cmd_ioread_data_t; - -static void *SWITCH_THREAD_FUNC ioread_thread(switch_thread_t *thread, void *obj) -{ - ftdm_wait_flag_t wflags = FTDM_READ; - ftdm_status_t status = FTDM_FAIL; - unsigned char iobuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - cmd_ioread_data_t *data = obj; - int span_id = ftdm_span_get_id(data->span); - int chan_id = ftdm_channel_get_id(data->fchan); - ftdm_size_t len = ftdm_channel_get_io_packet_len(data->fchan); - ftdm_size_t origlen = len; - unsigned int pbuf[5]; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Started ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n", - data->num_times, data->interval, len, span_id, chan_id); - - while (ftdm_running() && data->num_times > 0) { - data->num_times--; - - wflags = FTDM_READ; - status = ftdm_channel_wait(data->fchan, &wflags, (data->interval * 10)); - - if (status == FTDM_FAIL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to wait for IO in device %d:%d!\n", span_id, chan_id); - continue; - } - - if (status == FTDM_TIMEOUT) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Timed out while waiting I/O in device %d:%d!\n", span_id, chan_id); - continue; - } - - len = origlen; - if (ftdm_channel_read(data->fchan, iobuf, &len) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from device %d:%d!\n", span_id, chan_id); - continue; - } - pbuf[0] = iobuf[0]; - pbuf[1] = iobuf[1]; - pbuf[2] = iobuf[2]; - pbuf[3] = iobuf[3]; - pbuf[4] = iobuf[4]; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read 0x%1X 0x%1X 0x%1X 0x%1X 0x%1X\n", - pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4]); - } - - if (!data->already_open) { - ftdm_channel_close(&data->fchan); - } - - switch_core_destroy_memory_pool(&data->pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Done ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n", - data->num_times, data->interval, origlen, span_id, chan_id); - return NULL; -} - -FTDM_CLI_DECLARE(ftdm_cmd_ioread) -{ - char *span_name = NULL; - int channo = 0; - ftdm_status_t status = FTDM_SUCCESS; - switch_threadattr_t *attr = NULL; - switch_thread_t *thread = NULL; - - cmd_ioread_data_t *thdata; - cmd_ioread_data_t data; - - memset(&data, 0, sizeof(data)); - data.num_times = 1; - - if (argc < 3) { - print_usage(stream, cli); - goto end; - } - - span_name = argv[1]; - - ftdm_span_find_by_name(span_name, &data.span); - if (!data.span) { - stream->write_function(stream, "-ERR span %s not found\n", span_name); - goto end; - } - - channo = atoi(argv[2]); - - status = ftdm_channel_open(ftdm_span_get_id(data.span), channo, &data.fchan); - if (!data.fchan || (status != FTDM_SUCCESS && status != FTDM_EBUSY)) { - stream->write_function(stream, "-ERR Failed to open channel %d in span %s\n", channo, span_name); - goto end; - } - - if (status == FTDM_EBUSY) { - data.already_open = 1; - } - - if (argc > 3) { - data.num_times = atoi(argv[3]); - if (data.num_times < 1) { - data.num_times = 1; - } - } - - if (argc > 4) { - data.interval = atoi(argv[4]); - } - - if (data.interval <= 0 || data.interval > 10000) { - data.interval = ftdm_channel_get_io_interval(data.fchan); - } - - switch_core_new_memory_pool(&data.pool); - - thdata = switch_core_alloc(data.pool, sizeof(data)); - memcpy(thdata, &data, sizeof(*thdata)); - - switch_threadattr_create(&attr, data.pool); - switch_threadattr_detach_set(attr, 1); - switch_threadattr_stacksize_set(attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, attr, ioread_thread, thdata, data.pool); - -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_list) -{ - int j; - - for (j = 0 ; j < FTDM_MAX_SPANS_INTERFACE; j++) { - ftdm_channel_t *fchan; - ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE; - const char *flags = "none"; - ftdm_signaling_status_t sigstatus; - - if (!SPAN_CONFIG[j].span) { - continue; - } - - if (SPAN_CONFIG[j].analog_options & ANALOG_OPTION_3WAY) { - flags = "3way"; - } else if (SPAN_CONFIG[j].analog_options & ANALOG_OPTION_CALL_SWAP) { - flags = "call swap"; - } - fchan = ftdm_span_get_channel(SPAN_CONFIG[j].span, 1); - ftdm_channel_get_alarms(fchan, &alarmbits); - - if ((FTDM_SUCCESS == ftdm_span_get_sig_status(SPAN_CONFIG[j].span, &sigstatus))) { - stream->write_function(stream, - "+OK\n" - "span: %u (%s)\n" - "type: %s\n" - "physical_status: %s\n" - "signaling_status: %s\n" - "chan_count: %u\n" - "dialplan: %s\n" - "context: %s\n" - "dial_regex: %s\n" - "fail_dial_regex: %s\n" - "hold_music: %s\n" - "analog_options: %s\n", - j, - ftdm_span_get_name(SPAN_CONFIG[j].span), - SPAN_CONFIG[j].type, - alarmbits ? "alarmed" : "ok", - ftdm_signaling_status2str(sigstatus), - ftdm_span_get_chan_count(SPAN_CONFIG[j].span), - SPAN_CONFIG[j].dialplan, - SPAN_CONFIG[j].context, - SPAN_CONFIG[j].dial_regex, - SPAN_CONFIG[j].fail_dial_regex, - SPAN_CONFIG[j].hold_music, - flags - ); - } else { - stream->write_function(stream, - "+OK\n" - "span: %u (%s)\n" - "type: %s\n" - "physical_status: %s\n" - "chan_count: %u\n" - "dialplan: %s\n" - "context: %s\n" - "dial_regex: %s\n" - "fail_dial_regex: %s\n" - "hold_music: %s\n" - "analog_options: %s\n", - j, - ftdm_span_get_name(SPAN_CONFIG[j].span), - SPAN_CONFIG[j].type, - alarmbits ? "alarmed" : "ok", - ftdm_span_get_chan_count(SPAN_CONFIG[j].span), - SPAN_CONFIG[j].dialplan, - SPAN_CONFIG[j].context, - SPAN_CONFIG[j].dial_regex, - SPAN_CONFIG[j].fail_dial_regex, - SPAN_CONFIG[j].hold_music, - flags); - } - } - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_start_stop) -{ - char *span_name = argv[1]; - ftdm_span_t *span = NULL; - ftdm_status_t status; - - if (argc < 2) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(span_name, &span); - if (!span) { - stream->write_function(stream, "-ERR span %s not found\n", span_name); - goto end; - } - - if (!strcasecmp(argv[0], "stop")) { - status = ftdm_span_stop(span); - } else { - status = ftdm_span_start(span); - } - - stream->write_function(stream, status == FTDM_SUCCESS ? "+OK\n" : "-ERR failure\n"); -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_reset) -{ - uint32_t chan_id = 0; - uint32_t ccount = 0; - ftdm_channel_t *chan; - ftdm_span_t *span = NULL; - - if (argc < 2) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[1], &span); - if (!span) { - stream->write_function(stream, "-ERR span %s not found\n", argv[1]); - goto end; - } - - if (argc > 2) { - chan_id = atoi(argv[2]); - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel %d\n", chan_id); - goto end; - } - } - - if (chan_id) { - chan = ftdm_span_get_channel(span, chan_id); - if (!chan) { - stream->write_function(stream, "-ERR Could not find channel %d\n", chan_id); - goto end; - } - stream->write_function(stream, "Resetting channel %s:%s\n", argv[1], argv[2]); - ftdm_channel_reset(chan); - } else { - uint32_t i = 0; - ccount = ftdm_span_get_chan_count(span); - for (i = 1; i < ccount; i++) { - chan = ftdm_span_get_channel(span, i); - stream->write_function(stream, "Resetting channel %s:%d\n", argv[1], i); - ftdm_channel_reset(chan); - } - } - -end: - - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_dump) -{ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - uint32_t chan_id = 0; - ftdm_span_t *span; - char *as = NULL; - - if (argc < 2) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[1], &span); - if (argc > 2) { - if (argv[3] && !strcasecmp(argv[2], "as")) { - as = argv[3]; - } else { - chan_id = atoi(argv[2]); - } - } - - if (argv[4] && !strcasecmp(argv[3], "as")) { - as = argv[4]; - } - - if (!zstr(as) && !strcasecmp(as, "xml")) { - stream->write_function(stream, "\n"); - if (!span) { - stream->write_function(stream, "invalid span\n"); - } else { - if (chan_id) { - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "invalid channel\n"); - } else { - dump_chan_xml(span, chan_id, stream); - } - } else { - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - dump_chan_xml(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream); - } - ftdm_iterator_free(chaniter); - } - } - stream->write_function(stream, "\n"); - } else { - if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); - } else { - if (chan_id) { - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel\n"); - } else { - char *dbgstr = NULL; - ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); - dump_chan(span, chan_id, stream); - dbgstr = ftdm_channel_get_history_str(fchan); - stream->write_function(stream, "%s\n", dbgstr); - ftdm_free(dbgstr); - } - } else { - stream->write_function(stream, "+OK\n"); - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - dump_chan(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream); - } - ftdm_iterator_free(chaniter); - } - } - } - -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_alarms) -{ - ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE; - uint32_t chan_id = 0; - ftdm_span_t *span; - - if (argc < 3) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[1], &span); - chan_id = atoi(argv[2]); - if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); - } else if (chan_id) { - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel\n"); - } else { - ftdm_channel_t *chan = ftdm_span_get_channel(span, chan_id); - if (!chan) { - stream->write_function(stream, "-ERR channel not configured\n"); - } else { - ftdm_channel_get_alarms(chan, &alarmbits); - if (!strlen(ftdm_channel_get_last_error(chan))) { - stream->write_function(stream, "+OK No alarms\n"); - } else { - stream->write_function(stream, "-ERR %s on %s:%d\n", ftdm_channel_get_last_error(chan), argv[1], chan); - } - } - } - } -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_sigstatus) -{ - ftdm_span_t *span = NULL; - ftdm_signaling_status_t sigstatus; - - if (argc < 3) { - print_usage(stream, cli); - goto end; - } - - if (!strcasecmp(argv[1], "get") && argc < 3) { - print_usage(stream, cli); - goto end; - } - - if (!strcasecmp(argv[1], "set") && argc != 5) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[2], &span); - if (!span) { - stream->write_function(stream, "-ERR invalid span %s\n", argv[2]); - goto end; - } - - if (!strcasecmp(argv[1], "get")) { - if (argc == 4) { - uint32_t chan_id = atol(argv[3]); - ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); - if (!fchan) { - stream->write_function(stream, "-ERR invalid channel id '%d'\n", chan_id); - goto end; - } - - if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) { - stream->write_function(stream, "Channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus)); - } else { - stream->write_function(stream, "-ERR failed to get channel signaling status\n"); - } - goto end; - } else { - if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) { - stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus)); - } else { - stream->write_function(stream, "-ERR failed to read span signaling status: %s\n", ftdm_span_get_last_error(span)); - } - } - goto end; - } - if (!strcasecmp(argv[1], "set")) { - sigstatus = ftdm_str2ftdm_signaling_status(argv[4]); - - if (!strcasecmp(argv[3], "all")) { - if ((FTDM_SUCCESS == ftdm_span_set_sig_status(span, sigstatus))) { - stream->write_function(stream, "Signaling status of all channels from span %s set to %s\n", - ftdm_span_get_name(span), ftdm_signaling_status2str(sigstatus)); - } else { - stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus)); - } - goto end; - } else { - uint32_t chan_id = atol(argv[3]); - ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); - if (!fchan) { - stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id); - goto end; - } - - if ((FTDM_SUCCESS == ftdm_channel_set_sig_status(fchan, sigstatus))) { - stream->write_function(stream, "Signaling status of channel %d set to %s\n", chan_id, - ftdm_signaling_status2str(sigstatus)); - } else { - stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus)); - } - goto end; - } - } - -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_trace) -{ - char tracepath[255]; - unsigned i = 0; - uint32_t chan_id = 0; - uint32_t span_id = 0; - uint32_t chan_count = 0; - ftdm_status_t status; - ftdm_span_t *span = NULL; - ftdm_channel_t *chan = NULL; - - if (argc < 3) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[2], &span); - if (!span) { - stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]); - goto end; - } - - chan_count = ftdm_span_get_chan_count(span); - - if (argc > 3) { - chan_id = atoi(argv[3]); - if (chan_id > chan_count) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - } - - span_id = ftdm_span_get_id(span); - - if (chan_id) { - chan = ftdm_span_get_channel(span, chan_id); - - snprintf(tracepath, sizeof(tracepath), "%s-in-s%dc%d", argv[1], span_id, chan_id); - status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_INPUT, tracepath); - if (status != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR failed to enable input trace at path %s\n", tracepath); - goto end; - } - - snprintf(tracepath, sizeof(tracepath), "%s-out-s%dc%d", argv[1], span_id, chan_id); - status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_OUTPUT, tracepath); - if (status != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR failed to enable output trace at path %s\n", tracepath); - ftdm_channel_command(chan, FTDM_COMMAND_TRACE_END_ALL, NULL); - goto end; - } - } else { - for (i = 1; i <= chan_count; i++) { - chan = ftdm_span_get_channel(span, i); - - snprintf(tracepath, sizeof(tracepath), "%s-in-s%dc%d", argv[1], span_id, i); - status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_INPUT, tracepath); - if (status != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR failed to enable input trace at path %s\n", tracepath); - goto end; - } - - snprintf(tracepath, sizeof(tracepath), "%s-out-s%dc%d", argv[1], span_id, i); - status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_OUTPUT, tracepath); - if (status != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR failed to enable output trace at path %s\n", tracepath); - ftdm_channel_command(chan, FTDM_COMMAND_TRACE_END_ALL, NULL); - goto end; - } - } - } - stream->write_function(stream, "+OK trace enabled with prefix path %s\n", argv[1]); -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_notrace) -{ - uint32_t i = 0; - uint32_t chan_id = 0; - uint32_t chan_count = 0; - ftdm_channel_t *fchan = NULL; - ftdm_span_t *span = NULL; - - if (argc < 2) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[1], &span); - if (!span) { - stream->write_function(stream, "-ERR failed to find span %s\n", argv[1]); - goto end; - } - - chan_count = ftdm_span_get_chan_count(span); - - if (argc > 2) { - chan_id = atoi(argv[2]); - if (chan_id > chan_count) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - } - - if (chan_id) { - fchan = ftdm_span_get_channel(span, chan_id); - ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL); - } else { - for (i = 1; i <= chan_count; i++) { - fchan = ftdm_span_get_channel(span, i); - ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL); - } - } - stream->write_function(stream, "+OK trace disabled\n"); - -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_gains) -{ - unsigned int i = 0; - float txgain = 0.0; - float rxgain = 0.0; - uint32_t chan_id = 0; - uint32_t ccount = 0; - ftdm_channel_t *chan; - ftdm_span_t *span = NULL; - - if (argc < 4) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[3], &span); - if (!span) { - stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]); - goto end; - } - - if (argc > 4) { - chan_id = atoi(argv[4]); - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - } - - i = sscanf(argv[1], "%f", &rxgain); - i += sscanf(argv[2], "%f", &txgain); - if (i != 2) { - stream->write_function(stream, "-ERR invalid gains\n"); - goto end; - } - - if (chan_id) { - chan = ftdm_span_get_channel(span, chan_id); - ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_GAIN, &rxgain); - ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_GAIN, &txgain); - } else { - ccount = ftdm_span_get_chan_count(span); - for (i = 1; i < ccount; i++) { - chan = ftdm_span_get_channel(span, i); - ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_GAIN, &rxgain); - ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_GAIN, &txgain); - } - } - stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain); -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_dtmf) -{ - unsigned i = 0; - uint32_t chan_id = 0; - unsigned schan_count = 0; - ftdm_span_t *span = NULL; - ftdm_command_t fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT; - ftdm_channel_t *fchan; - - if (argc < 3) { - print_usage(stream, cli); - goto end; - } - - if (switch_true(argv[1])) { - fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT; - } else { - fcmd = FTDM_COMMAND_DISABLE_DTMF_DETECT; - } - - ftdm_span_find_by_name(argv[2], &span); - if (!span) { - stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]); - goto end; - } - - schan_count = ftdm_span_get_chan_count(span); - if (argc > 3) { - chan_id = atoi(argv[3]); - if (chan_id > schan_count) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - } - - if (chan_id) { - fchan = ftdm_span_get_channel(span, chan_id); - ftdm_channel_command(fchan, fcmd, NULL); - } else { - for (i = 1; i <= schan_count; i++) { - fchan = ftdm_span_get_channel(span, i); - ftdm_channel_command(fchan, fcmd, NULL); - } - } - - stream->write_function(stream, "+OK DTMF detection was %s\n", fcmd == FTDM_COMMAND_ENABLE_DTMF_DETECT ? "enabled" : "disabled"); -end: - return SWITCH_STATUS_SUCCESS; -} - -FTDM_CLI_DECLARE(ftdm_cmd_queuesize) -{ - unsigned int i = 0; - uint32_t rxsize = 10; - uint32_t txsize = 10; - uint32_t chan_id = 0; - uint32_t ccount = 0; - ftdm_channel_t *chan; - ftdm_span_t *span = NULL; - - if (argc < 4) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[3], &span); - if (!span) { - stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]); - goto end; - } - - if (argc > 4) { - chan_id = atoi(argv[4]); - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - } - - i = sscanf(argv[1], "%u", &rxsize); - i += sscanf(argv[2], "%u", &txsize); - if (i != 2) { - stream->write_function(stream, "-ERR invalid queue sizes provided\n"); - goto end; - } - - if (chan_id) { - chan = ftdm_span_get_channel(span, chan_id); - ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &rxsize); - ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txsize); - } else { - ccount = ftdm_span_get_chan_count(span); - for (i = 1; i < ccount; i++) { - chan = ftdm_span_get_channel(span, i); - ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &rxsize); - ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txsize); - } - } - stream->write_function(stream, "+OK queue sizes set to Rx %d and Tx %d\n", rxsize, txsize); -end: - return SWITCH_STATUS_SUCCESS; -} - -static void exec_io_command(const char *cmd, switch_stream_handle_t *stream, ftdm_channel_t *fchan) -{ - int enable = 0; - ftdm_channel_iostats_t stats; - - if (!strcasecmp("enable", cmd)) { - enable = 1; - ftdm_channel_command(fchan, FTDM_COMMAND_SWITCH_IOSTATS, &enable); - } else if (!strcasecmp("disable", cmd)) { - enable = 0; - ftdm_channel_command(fchan, FTDM_COMMAND_SWITCH_IOSTATS, &enable); - } else if (!strcasecmp("flush", cmd)) { - ftdm_channel_command(fchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL); - } else { - ftdm_channel_command(fchan, FTDM_COMMAND_GET_IOSTATS, &stats); - stream->write_function(stream, "-- IO statistics for channel %d:%d --\n", - ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan)); - stream->write_function(stream, "Rx errors: %u\n", stats.rx.errors); - stream->write_function(stream, "Rx queue size: %u\n", stats.rx.queue_size); - stream->write_function(stream, "Rx queue len: %u\n", stats.rx.queue_len); - stream->write_function(stream, "Rx count: %lu\n", stats.rx.packets); - - stream->write_function(stream, "Tx errors: %u\n", stats.tx.errors); - stream->write_function(stream, "Tx queue size: %u\n", stats.tx.queue_size); - stream->write_function(stream, "Tx queue len: %u\n", stats.tx.queue_len); - stream->write_function(stream, "Tx count: %lu\n", stats.tx.packets); - stream->write_function(stream, "Tx idle: %u\n", stats.tx.idle_packets); - } -} - -FTDM_CLI_DECLARE(ftdm_cmd_iostats) -{ - uint32_t chan_id = 0; - ftdm_channel_t *chan; - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_span_t *span = NULL; - - if (argc < 3) { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[2], &span); - if (!span) { - stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]); - goto end; - } - - if (argc > 3) { - chan_id = atoi(argv[3]); - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - chan = ftdm_span_get_channel(span, chan_id); - exec_io_command(argv[1], stream, chan); - } else { - iter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - chan = ftdm_iterator_current(curr); - exec_io_command(argv[1], stream, chan); - } - ftdm_iterator_free(iter); - } - stream->write_function(stream, "+OK\n"); -end: - return SWITCH_STATUS_SUCCESS; -} - -#define CASINTS(cas) ((cas) & (1 << 3)) ? 1 : 0, \ - ((cas) & (1 << 2)) ? 1 : 0, \ - ((cas) & (1 << 1)) ? 1 : 0, \ - ((cas) & (1 << 0)) ? 1 : 0 -FTDM_CLI_DECLARE(ftdm_cmd_cas) -{ - uint32_t chan_id = 0; - switch_bool_t do_read = SWITCH_FALSE; - ftdm_channel_t *chan; - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_span_t *span = NULL; - const char *write_bits_str = ""; - int32_t abcd_bits = 0; - - if (argc < 3) { - print_usage(stream, cli); - goto end; - } - - if (!strcasecmp(argv[1], "read")) { - do_read = SWITCH_TRUE; - chan_id = argc > 3 ? atoi(argv[3]) : 0; - } else if (!strcasecmp(argv[1], "write") && argc >= 4) { - const char *str = NULL; - int mask = 0x08; - do_read = SWITCH_FALSE; - if (argc == 4) { - chan_id = 0; - write_bits_str = argv[3]; - } else { - chan_id = atoi(argv[3]); - write_bits_str = argv[4]; - } - if (strlen(write_bits_str) != 4) { - stream->write_function(stream, "-ERR Invalid CAS bits '%s'. CAS ABCD string must be composed of only four 1's and 0's (e.g. 1101)\n", write_bits_str); - goto end; - } - str = write_bits_str; - while (*str) { - if (*str == '1') { - abcd_bits |= mask; - } else if (*str != '0') { - stream->write_function(stream, "-ERR Invalid CAS bits '%s'. CAS ABCD string must be composed of only four 1's and 0's (e.g. 1101)\n", write_bits_str); - goto end; - } - str++; - mask = (mask >> 1); - } - } else { - print_usage(stream, cli); - goto end; - } - - ftdm_span_find_by_name(argv[2], &span); - if (!span) { - stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]); - goto end; - } - - if (chan_id) { - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - chan = ftdm_span_get_channel(span, chan_id); - if (do_read) { - ftdm_channel_command(chan, FTDM_COMMAND_GET_CAS_BITS, &abcd_bits); - stream->write_function(stream, "Read CAS bits from channel %d: %d%d%d%d (0x0%X)\n", chan_id, CASINTS(abcd_bits), abcd_bits); - } else { - stream->write_function(stream, "Writing 0x0%X to channel %d\n", abcd_bits, chan_id); - } - } else { - iter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - chan = ftdm_iterator_current(curr); - //ftdm_channel_command(); - chan_id = ftdm_channel_get_id(chan); - if (do_read) { - ftdm_channel_command(chan, FTDM_COMMAND_GET_CAS_BITS, &abcd_bits); - stream->write_function(stream, "Read CAS bits from channel %d: %d%d%d%d (0x0%X)\n", chan_id, CASINTS(abcd_bits), abcd_bits); - } else { - stream->write_function(stream, "Writing 0x0%X to channel %d\n", abcd_bits, chan_id); - } - } - ftdm_iterator_free(iter); - } - stream->write_function(stream, "+OK\n"); -end: - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_API(ftdm_api_exec_usage) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - uint32_t chan_id = 0; - ftdm_channel_t *chan = NULL; - ftdm_span_t *span = NULL; - uint32_t tokencnt = 0; - /*ftdm_cli_entry_t *entry = NULL;*/ - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - stream->write_function(stream, "-ERR invalid args\n"); - goto end; - } - - if (argc < 2) { - stream->write_function(stream, "-ERR invalid args\n"); - goto end; - } - - ftdm_span_find_by_name(argv[0], &span); - chan_id = atoi(argv[1]); - if (!span) { - stream->write_function(stream, "-ERR invalid span\n"); - goto end; - } - - if (chan_id <= 0) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - - if (chan_id > ftdm_span_get_chan_count(span)) { - stream->write_function(stream, "-ERR invalid channel\n"); - goto end; - } - - chan = ftdm_span_get_channel(span, chan_id); - if (!chan) { - stream->write_function(stream, "-ERR channel not configured\n"); - goto end; - } - - tokencnt = ftdm_channel_get_token_count(chan); - stream->write_function(stream, "%d", tokencnt); - -end: - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -struct ftdm_cli_entry { - const char *name; - const char *args; - const char *complete; - const char *desc; - ftdm_cli_function_t execute; - switch_api_function_t execute_api; -}; - -static ftdm_cli_entry_t ftdm_cli_options[] = -{ - { "list", "", "", NULL, ftdm_cmd_list, NULL }, - { "start", "", "", NULL, ftdm_cmd_start_stop, NULL }, - { "stop", "", "", NULL, ftdm_cmd_start_stop, NULL }, - { "reset", " []", "", NULL, ftdm_cmd_reset, NULL }, - { "alarms", " ", "", NULL, ftdm_cmd_alarms, NULL }, - { "dump", " []", "", NULL, ftdm_cmd_dump, NULL }, - { "sigstatus", "get|set [] []", "::[set:get", NULL, ftdm_cmd_sigstatus, NULL }, - { "trace", " []", "", NULL, ftdm_cmd_trace, NULL }, - { "notrace", " []", "", NULL, ftdm_cmd_notrace, NULL }, - { "gains", " []", "", NULL, ftdm_cmd_gains, NULL }, - { "dtmf", "on|off []", "::[on:off", NULL, ftdm_cmd_dtmf, NULL }, - { "queuesize", " []", "", NULL, ftdm_cmd_queuesize, NULL }, - { "iostats", "enable|disable|flush|print ", "::[enable:disable:flush:print", NULL, ftdm_cmd_iostats, NULL }, - { "ioread", " [num_times] [interval]", "", NULL, ftdm_cmd_ioread, NULL }, - { "cas", "read|write [] []", "::[read:write", NULL, ftdm_cmd_cas, NULL }, - - /* Stand-alone commands (not part of the generic ftdm API */ - { "ftdm_usage", " ", "", "Return channel call count", NULL, ftdm_api_exec_usage }, - - /* Fake handlers as they are handled within freetdm library, - * we should provide a way inside freetdm to query for completions from signaling modules */ - { "core state", "[!]", "", NULL, NULL, NULL }, - { "core flag", "[!] [] []", "", NULL, NULL, NULL }, - { "core spanflag", "[!] []", "", NULL, NULL, NULL }, - { "core calls", "", "", NULL, NULL, NULL }, -}; - -static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli) -{ - stream->write_function(stream, "-ERR Usage: ftdm %s %s\n", cli->name, cli->args); -} - -static void print_full_usage(switch_stream_handle_t *stream) -{ - int i = 0; - ftdm_cli_entry_t *entry = NULL; - - stream->write_function(stream, "USAGE:\n"); - stream->write_function(stream, "--------------------------------------------------------------------------------\n"); - for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) { - entry = &ftdm_cli_options[i]; - if (entry->execute_api) { - continue; - } - stream->write_function(stream, "ftdm %s %s\n", entry->name, entry->args); - } - stream->write_function(stream, "--------------------------------------------------------------------------------\n"); -} - -SWITCH_STANDARD_API(ftdm_api_exec) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - int i = 0; - ftdm_cli_entry_t *entry = NULL; - - if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc) { - print_full_usage(stream); - goto end; - } - - for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) { - entry = &ftdm_cli_options[i]; - if (!strcasecmp(argv[0], entry->name) && entry->execute) { - entry->execute(entry, cmd, session, stream, argc, argv); - break; - } - } - - /* if the command was not found in the main CLI entries, try to execute it as a FreeTDM API */ - if (i == ftdm_array_len(ftdm_cli_options)) { - char *rply = ftdm_api_execute(cmd); - if (rply) { - stream->write_function(stream, "%s", rply); - ftdm_free(rply); - } else { - print_full_usage(stream); - } - } - -end: - switch_safe_free(mycmd); - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_STANDARD_APP(enable_dtmf_function) -{ - private_t *tech_pvt; - - if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) { - ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n"); - return; - } - - tech_pvt = switch_core_session_get_private(session); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE); - return; - } - - ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL); - ftdm_log(FTDM_LOG_INFO, "DTMF detection enabled in channel %d:%d\n", ftdm_channel_get_id(tech_pvt->ftdmchan), ftdm_channel_get_span_id(tech_pvt->ftdmchan)); -} - -SWITCH_STANDARD_APP(disable_dtmf_function) -{ - private_t *tech_pvt; - - if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) { - ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n"); - return; - } - - tech_pvt = switch_core_session_get_private(session); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE); - return; - } - - ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL); - ftdm_log(FTDM_LOG_INFO, "DTMF detection Disabled in channel %d:%d\n", ftdm_channel_get_id(tech_pvt->ftdmchan), ftdm_channel_get_span_id(tech_pvt->ftdmchan)); -} - -SWITCH_STANDARD_APP(disable_ec_function) -{ - private_t *tech_pvt; - int x = 0; - - if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) { - ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n"); - return; - } - - tech_pvt = switch_core_session_get_private(session); - - if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE); - return; - } - - ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOCANCEL, &x); - ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOTRAIN, &x); - ftdm_log(FTDM_LOG_INFO, "Echo Canceller Disabled\n"); -} - - -SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load) -{ - int i = 0; - ftdm_cli_entry_t *entry = NULL; - switch_api_interface_t *commands_api_interface = NULL; - switch_application_interface_t *app_interface = NULL; - - module_pool = pool; - - ftdm_global_set_logger(ftdm_logger); - - ftdm_global_set_mod_directory(SWITCH_GLOBAL_dirs.mod_dir); - - ftdm_global_set_config_directory(SWITCH_GLOBAL_dirs.conf_dir); - - if (load_config_path() != SWITCH_STATUS_SUCCESS) { - ftdm_global_destroy(); - return SWITCH_STATUS_TERM; - } - - if (ftdm_global_init() != FTDM_SUCCESS) { - ftdm_global_destroy(); - ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n"); - return SWITCH_STATUS_TERM; - } - - if (ftdm_global_configuration() != FTDM_SUCCESS) { - ftdm_global_destroy(); - ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM\n"); - return SWITCH_STATUS_TERM; - } - - if (load_config() != SWITCH_STATUS_SUCCESS) { - ftdm_global_destroy(); - return SWITCH_STATUS_TERM; - } - - *module_interface = switch_loadable_module_create_module_interface(pool, modname); - freetdm_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); - freetdm_endpoint_interface->interface_name = "freetdm"; - freetdm_endpoint_interface->io_routines = &freetdm_io_routines; - freetdm_endpoint_interface->state_handler = &freetdm_state_handlers; - - SWITCH_ADD_API(commands_api_interface, "ftdm", "FreeTDM commands", ftdm_api_exec, " "); - for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) { - char complete_cli[512]; - entry = &ftdm_cli_options[i]; - if (entry->execute_api) { - /* This is a stand-alone API */ - SWITCH_ADD_API(commands_api_interface, entry->name, entry->desc, ftdm_api_exec_usage, entry->args); - snprintf(complete_cli, sizeof(complete_cli), "add %s %s", entry->name, entry->complete); - switch_console_set_complete(complete_cli); - } else { - snprintf(complete_cli, sizeof(complete_cli), "add ftdm %s %s", entry->name, entry->complete); - switch_console_set_complete(complete_cli); - } - } - - SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE); - SWITCH_ADD_APP(app_interface, "disable_dtmf", "Disable DTMF Detection", "Disable DTMF Detection", disable_dtmf_function, "", SAF_NONE); - SWITCH_ADD_APP(app_interface, "enable_dtmf", "Enable DTMF Detection", "Enable DTMF Detection", enable_dtmf_function, "", SAF_NONE); -#if 0 - ctdm_init(*module_interface); -#endif - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown) -{ - switch_hash_index_t *hi; - const void *var; - void *val; - - /* destroy ss7 configs */ - for (hi = switch_core_hash_first(globals.ss7_configs); hi; hi = switch_core_hash_next(&hi)) { - switch_core_hash_this(hi, &var, NULL, &val); - ftdm_conf_node_destroy(val); - } - - switch_core_hash_destroy(&globals.ss7_configs); - ftdm_global_destroy(); - - // this breaks pika but they are MIA so *shrug* - //return SWITCH_STATUS_NOUNLOAD; - return SWITCH_STATUS_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/mod_freetdm/mod_openzap.2005.vcproj b/libs/freetdm/mod_freetdm/mod_openzap.2005.vcproj deleted file mode 100644 index 491d0d574a..0000000000 --- a/libs/freetdm/mod_freetdm/mod_openzap.2005.vcproj +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/mod_freetdm/tdm.c b/libs/freetdm/mod_freetdm/tdm.c deleted file mode 100644 index d53c8a584b..0000000000 --- a/libs/freetdm/mod_freetdm/tdm.c +++ /dev/null @@ -1,719 +0,0 @@ -/* -* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005-2011, Anthony Minessale II -* -* Version: MPL 1.1 -* -* The contents of this file are subject to the Mozilla Public License Version -* 1.1 (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* http://www.mozilla.org/MPL/ -* -* Software distributed under the License is distributed on an "AS IS" basis, -* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -* for the specific language governing rights and limitations under the -* License. -* -* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* -* The Initial Developer of the Original Code is -* Anthony Minessale II -* Portions created by the Initial Developer are Copyright (C) -* the Initial Developer. All Rights Reserved. -* -* Contributor(s): -* -* Mathieu Rene -* -* tdm.c -- FreeTDM Controllable Channel Module -* -*/ - -#include -#include "freetdm.h" - -void ctdm_init(switch_loadable_module_interface_t *module_interface); - -/* Parameters */ - -#define kSPAN_ID "span" -#define kCHAN_ID "chan" -#define kSPAN_NAME "span_name" -#define kPREBUFFER_LEN "prebuffer_len" -#define kECHOCANCEL "echo_cancel" - - -static struct { - switch_memory_pool_t *pool; - switch_endpoint_interface_t *endpoint_interface; -} ctdm; - -typedef struct { - int span_id; - int chan_id; - ftdm_channel_t *ftdm_channel; - switch_core_session_t *session; - switch_codec_t read_codec, write_codec; - switch_frame_t read_frame; - int prebuffer_len; - - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; -} ctdm_private_t; - -static switch_status_t channel_on_init(switch_core_session_t *session); -static switch_status_t channel_on_destroy(switch_core_session_t *session); -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, - switch_memory_pool_t **pool, - switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); -static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg); -static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event); -static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf); - - -static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span); - -switch_state_handler_table_t ctdm_state_handlers = { - .on_init = channel_on_init, - .on_destroy = channel_on_destroy -}; - -switch_io_routines_t ctdm_io_routines = { - .send_dtmf = channel_send_dtmf, - .outgoing_channel = channel_outgoing_channel, - .read_frame = channel_read_frame, - .write_frame = channel_write_frame, - .receive_message = channel_receive_message, - .receive_event = channel_receive_event -}; - -static void ctdm_report_alarms(ftdm_channel_t *channel) -{ - switch_event_t *event = NULL; - ftdm_alarm_flag_t alarmflag = 0; - - if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n"); - return; - } - - if (ftdm_channel_get_alarms(channel, &alarmflag) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve alarms %s:%d\n", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel)); - return; - } - - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(channel)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(channel)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(channel)); - - if (alarmflag) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap"); - } else { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear"); - } - - if (alarmflag & FTDM_ALARM_RED) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red"); - } - if (alarmflag & FTDM_ALARM_YELLOW) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow"); - } - if (alarmflag & FTDM_ALARM_RAI) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai"); - } - if (alarmflag & FTDM_ALARM_BLUE) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue"); - } - if (alarmflag & FTDM_ALARM_AIS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais"); - } - if (alarmflag & FTDM_ALARM_GENERAL) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general"); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reporting [%s] alarms for %s:%d\n", - (alarmflag?"ftdm-alarm-trap":"ftdm-alarm-clear"), ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel)); - - switch_event_fire(&event); - return; -} - -static ftdm_channel_t *ctdm_get_channel_from_event(switch_event_t *event, ftdm_span_t *span) -{ - uint32_t chan_id = 0; - const char *chan_number = NULL; - - chan_number = switch_event_get_header(event, "chan-number"); - - if (zstr(chan_number)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channel number specified\n"); - return NULL; - } - chan_id = atoi(chan_number); - if (!chan_id) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid channel number:%s\n", chan_number); - return NULL; - } - - return ftdm_span_get_channel_ph(span, chan_id); -} - - -static void ctdm_event_handler(switch_event_t *event) -{ - ftdm_status_t status = FTDM_FAIL; - switch(event->event_id) { - case SWITCH_EVENT_TRAP: - { - ftdm_span_t *span = NULL; - ftdm_channel_t *channel = NULL; - const char *span_name = NULL; - - const char *cond = switch_event_get_header(event, "condition"); - const char *command = switch_event_get_header(event, "command"); - if (zstr(cond)) { - return; - } - - span_name = switch_event_get_header(event, "span-name"); - - if (ftdm_span_find_by_name(span_name, &span) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name); - return; - } - - if (!strcmp(cond, "mg-tdm-prepare")) { - status = ctdm_span_prepare(span); - if (status == FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s:prepared successfully\n", span_name); - } else if (status != FTDM_EINVAL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:Failed to prepare span\n", span_name); - } - } else if (!strcmp(cond, "mg-tdm-check")) { - channel = ctdm_get_channel_from_event(event, span); - if (!channel) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n"); - return; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Requesting alarm status for %s:%d\n", - ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel)); - - ctdm_report_alarms(channel); - } else if (!strcmp(cond, "mg-tdm-dtmfremoval")) { - uint8_t enable = 0; - channel = ctdm_get_channel_from_event(event, span); - if (!channel) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n"); - return; - } - - if (zstr(command)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:No command specified for mg-tdm-dtmfremoval\n", span_name); - return; - } - - if (!strcmp(command, "enable")) { - enable = 1; - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s DTMF-removal for %s:%d\n", - enable ? "Enabling" : "Disabling", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel)); - - ftdm_channel_command(channel, enable ? FTDM_COMMAND_ENABLE_DTMF_REMOVAL : FTDM_COMMAND_DISABLE_DTMF_REMOVAL, 0); - } - } - break; - default: - break; - } - return; -} - -void ctdm_init(switch_loadable_module_interface_t *module_interface) -{ - switch_endpoint_interface_t *endpoint_interface; - ctdm.pool = module_interface->pool; - endpoint_interface = switch_loadable_module_create_interface(module_interface, SWITCH_ENDPOINT_INTERFACE); - endpoint_interface->interface_name = "tdm"; - endpoint_interface->io_routines = &ctdm_io_routines; - endpoint_interface->state_handler = &ctdm_state_handlers; - ctdm.endpoint_interface = endpoint_interface; - - switch_event_bind("mod_freetdm", SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, ctdm_event_handler, NULL); -} - -static FIO_SIGNAL_CB_FUNCTION(on_signal_cb) -{ - uint32_t chanid, spanid; - switch_event_t *event = NULL; - ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE; - - chanid = ftdm_channel_get_id(sigmsg->channel); - spanid = ftdm_channel_get_span_id(sigmsg->channel); - - switch(sigmsg->event_id) { - case FTDM_SIGEVENT_ALARM_CLEAR: - case FTDM_SIGEVENT_ALARM_TRAP: - { - if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n"); - return FTDM_FAIL; - } - - if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n"); - return FTDM_FAIL; - } - if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) { - ftdm_log(FTDM_LOG_NOTICE, "Alarm cleared on channel %d:%d\n", spanid, chanid); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear"); - } else { - ftdm_log(FTDM_LOG_NOTICE, "Alarm raised on channel %d:%d\n", spanid, chanid); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap"); - } - } - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unhandled event %d\n", sigmsg->event_id); - break; - } - - if (event) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel)); - - if (alarmbits & FTDM_ALARM_RED) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red"); - } - if (alarmbits & FTDM_ALARM_YELLOW) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow"); - } - if (alarmbits & FTDM_ALARM_RAI) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai"); - } - if (alarmbits & FTDM_ALARM_BLUE) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue"); - } - if (alarmbits & FTDM_ALARM_AIS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais"); - } - if (alarmbits & FTDM_ALARM_GENERAL) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general"); - } - - switch_event_fire(&event); - } - return FTDM_SUCCESS; -} - -static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span) -{ - if (ftdm_span_register_signal_cb(span, on_signal_cb) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register signal CB\n"); - return FTDM_FAIL; - } - return ftdm_span_start(span); -} - -static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, - switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, - switch_memory_pool_t **pool, - switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) -{ - const char *szchanid = switch_event_get_header(var_event, kCHAN_ID), - *span_name = switch_event_get_header(var_event, kSPAN_NAME), - *szprebuffer_len = switch_event_get_header(var_event, kPREBUFFER_LEN); - int chan_id; - int span_id; - switch_caller_profile_t *caller_profile; - ftdm_span_t *span; - ftdm_channel_t *chan; - switch_channel_t *channel; - char name[128]; - const char *dname; - ftdm_codec_t codec; - uint32_t interval; - ctdm_private_t *tech_pvt = NULL; - - if (zstr(szchanid) || zstr(span_name)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Both ["kSPAN_ID"] and ["kCHAN_ID"] have to be set.\n"); - goto fail; - } - - chan_id = atoi(szchanid); - - if (ftdm_span_find_by_name(span_name, &span) == FTDM_SUCCESS) { - span_id = ftdm_span_get_id(span); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name); - goto fail; - } - - if (!(*new_session = switch_core_session_request(ctdm.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n"); - goto fail; - } - - channel = switch_core_session_get_channel(*new_session); - - if (ftdm_channel_open_ph(span_id, chan_id, &chan) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open span or channel.\n"); - goto fail; - } - - switch_channel_set_flag(channel, CF_AUDIO); - - span = ftdm_channel_get_span(chan); - - tech_pvt = switch_core_session_alloc(*new_session, sizeof *tech_pvt); - tech_pvt->chan_id = chan_id; - tech_pvt->span_id = span_id; - tech_pvt->ftdm_channel = chan; - tech_pvt->session = *new_session; - tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); - tech_pvt->read_frame.data = tech_pvt->databuf; - tech_pvt->prebuffer_len = zstr(szprebuffer_len) ? 0 : atoi(szprebuffer_len); - switch_core_session_set_private(*new_session, tech_pvt); - - - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - switch_channel_set_caller_profile(channel, caller_profile); - - snprintf(name, sizeof(name), "tdm/%d:%d", span_id, chan_id); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name); - switch_channel_set_name(channel, name); - - switch_channel_set_state(channel, CS_INIT); - - if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_CODEC, &codec)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n"); - return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; - } - - if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n"); - return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; - } - - if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n"); - return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; - } - - if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to set enable echo cancellation.\n"); - } - - switch(codec) { - case FTDM_CODEC_ULAW: - { - dname = "PCMU"; - } - break; - case FTDM_CODEC_ALAW: - { - dname = "PCMA"; - } - break; - case FTDM_CODEC_SLIN: - { - dname = "L16"; - } - break; - default: - { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec); - goto fail; - } - } - - - if (switch_core_codec_init(&tech_pvt->read_codec, - dname, - NULL, - NULL, - 8000, - interval, - 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n"); - goto fail; - } else { - if (switch_core_codec_init(&tech_pvt->write_codec, - dname, - NULL, - NULL, - 8000, - interval, - 1, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n"); - switch_core_codec_destroy(&tech_pvt->read_codec); - goto fail; - } - } - - if (switch_core_session_set_read_codec(*new_session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n"); - goto fail; - } - - if (switch_core_session_set_write_codec(*new_session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n"); - } - - if (switch_core_session_thread_launch(*new_session) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't start session thread.\n"); - goto fail; - } - - switch_channel_mark_answered(channel); - - return SWITCH_CAUSE_SUCCESS; - -fail: - - if (tech_pvt) { - if (tech_pvt->ftdm_channel) { - ftdm_channel_close(&tech_pvt->ftdm_channel); - } - - if (tech_pvt->read_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (tech_pvt->write_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - } - - if (*new_session) { - switch_core_session_destroy(new_session); - } - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; -} - -static switch_status_t channel_on_init(switch_core_session_t *session) -{ - switch_channel_t *channel = switch_core_session_get_channel(session); - - switch_channel_set_state(channel, CS_CONSUME_MEDIA); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_destroy(switch_core_session_t *session) -{ - ctdm_private_t *tech_pvt = switch_core_session_get_private(session); - - if ((tech_pvt = switch_core_session_get_private(session))) { - - if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to enable echo cancellation.\n"); - } - - if (tech_pvt->read_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (tech_pvt->write_codec.implementation) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } - - switch_core_session_unset_read_codec(session); - switch_core_session_unset_write_codec(session); - - ftdm_channel_close(&tech_pvt->ftdm_channel); - } - - return SWITCH_STATUS_SUCCESS; -} - - -static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) -{ - ftdm_wait_flag_t wflags = FTDM_READ; - ftdm_status_t status; - ctdm_private_t *tech_pvt; - const char *name; - switch_channel_t *channel; - int chunk; - uint32_t span_id, chan_id; - ftdm_size_t len; - char dtmf[128] = ""; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - name = switch_channel_get_name(channel); - -top: - wflags = FTDM_READ; - chunk = ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 2; - status = ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, chunk); - - - span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel); - chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel); - - if (status == FTDM_FAIL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); - goto fail; - } - - if (status == FTDM_TIMEOUT) { - goto top; - } - - if (!(wflags & FTDM_READ)) { - goto top; - } - - len = tech_pvt->read_frame.buflen; - if (ftdm_channel_read(tech_pvt->ftdm_channel, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); - } - - *frame = &tech_pvt->read_frame; - tech_pvt->read_frame.datalen = (uint32_t)len; - tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen; - tech_pvt->read_frame.codec = &tech_pvt->read_codec; - - if (ftdm_channel_get_codec(tech_pvt->ftdm_channel) == FTDM_CODEC_SLIN) { - tech_pvt->read_frame.samples /= 2; - } - - while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdm_channel, dtmf, sizeof(dtmf))) { - switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) }; - char *p; - for (p = dtmf; p && *p; p++) { - if (is_dtmf(*p)) { - _dtmf.digit = *p; - ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id); - switch_channel_queue_dtmf(channel, &_dtmf); - } - } - } - - return SWITCH_STATUS_SUCCESS; - -fail: - return SWITCH_STATUS_GENERR; -} - -static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) -{ - ftdm_wait_flag_t wflags = FTDM_WRITE; - ctdm_private_t *tech_pvt; - const char *name; - switch_channel_t *channel; - uint32_t span_id, chan_id; - ftdm_size_t len; - unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; - - channel = switch_core_session_get_channel(session); - assert(channel != NULL); - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel); - chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel); - - name = switch_channel_get_name(channel); - - if (switch_test_flag(frame, SFF_CNG)) { - frame->data = data; - frame->buflen = sizeof(data); - if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) { - goto fail; - } - memset(data, 255, frame->datalen); - } - - wflags = FTDM_WRITE; - ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 10); - - if (!(wflags & FTDM_WRITE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id); - return SWITCH_STATUS_SUCCESS; - } - - len = frame->datalen; - if (ftdm_channel_write(tech_pvt->ftdm_channel, frame->data, frame->buflen, &len) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id); - } - - return SWITCH_STATUS_SUCCESS; - -fail: - return SWITCH_STATUS_GENERR; -} - -static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) -{ - ctdm_private_t *tech_pvt = NULL; - char tmp[2] = ""; - - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - tmp[0] = dtmf->digit; - ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SEND_DTMF, tmp); - - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) -{ - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event) -{ - const char *command = switch_event_get_header(event, "command"); - ctdm_private_t *tech_pvt = switch_core_session_get_private(session); - - if (!zstr(command)) { - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received %s command \n",command); - - if (!strcasecmp(command, kPREBUFFER_LEN)) { - const char *szval = switch_event_get_header(event, kPREBUFFER_LEN); - int val = !zstr(szval) ? atoi(szval) : 0; - - if (tech_pvt->prebuffer_len == val) { - tech_pvt->prebuffer_len = val; - if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n"); - return SWITCH_STATUS_GENERR; - } - } - } else if (!strcasecmp(command, kECHOCANCEL)) { - const char *szval = switch_event_get_header(event, kECHOCANCEL); - int enabled = !!switch_true(szval); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM sending echo cancel [%s] command \n",enabled ? "enable" : "disable"); - - if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, enabled ? FTDM_COMMAND_ENABLE_ECHOCANCEL : FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to %s echo cancellation.\n", enabled ? "enable" : "disable"); - } - - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received unknown command [%s] \n",command); - } - } - - return SWITCH_STATUS_SUCCESS; -} - diff --git a/libs/freetdm/msvc/freetdm.2008.vcproj b/libs/freetdm/msvc/freetdm.2008.vcproj deleted file mode 100644 index 46594bf38c..0000000000 --- a/libs/freetdm/msvc/freetdm.2008.vcproj +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters b/libs/freetdm/msvc/freetdm.2010.vcxproj.filters deleted file mode 100644 index 9f15c9c737..0000000000 --- a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters +++ /dev/null @@ -1,137 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - diff --git a/libs/freetdm/msvc/openzap.2005.vcproj b/libs/freetdm/msvc/openzap.2005.vcproj deleted file mode 100644 index 85d4a89206..0000000000 --- a/libs/freetdm/msvc/openzap.2005.vcproj +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/testanalog/testanalog.2005.vcproj b/libs/freetdm/msvc/testanalog/testanalog.2005.vcproj deleted file mode 100644 index 93553d2a5f..0000000000 --- a/libs/freetdm/msvc/testanalog/testanalog.2005.vcproj +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/testanalog/testanalog.2008.vcproj b/libs/freetdm/msvc/testanalog/testanalog.2008.vcproj deleted file mode 100644 index 24f418ab19..0000000000 --- a/libs/freetdm/msvc/testanalog/testanalog.2008.vcproj +++ /dev/null @@ -1,349 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/testanalog/testanalog.2010.vcxproj.filters b/libs/freetdm/msvc/testanalog/testanalog.2010.vcxproj.filters deleted file mode 100644 index 7ac3635cc5..0000000000 --- a/libs/freetdm/msvc/testanalog/testanalog.2010.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/msvc/testboost/testboost.2008.vcproj b/libs/freetdm/msvc/testboost/testboost.2008.vcproj deleted file mode 100644 index c273b3c02b..0000000000 --- a/libs/freetdm/msvc/testboost/testboost.2008.vcproj +++ /dev/null @@ -1,354 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/testboost/testboost.2010.vcxproj.filters b/libs/freetdm/msvc/testboost/testboost.2010.vcxproj.filters deleted file mode 100644 index 74181d60a8..0000000000 --- a/libs/freetdm/msvc/testboost/testboost.2010.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/msvc/testboost/testsangomaboost.2008.vcproj b/libs/freetdm/msvc/testboost/testsangomaboost.2008.vcproj deleted file mode 100644 index 77ca1594df..0000000000 --- a/libs/freetdm/msvc/testboost/testsangomaboost.2008.vcproj +++ /dev/null @@ -1,354 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj.filters b/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj.filters deleted file mode 100644 index e72f14e161..0000000000 --- a/libs/freetdm/msvc/testboost/testsangomaboost.2010.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/msvc/testisdn/testisdn.2005.vcproj b/libs/freetdm/msvc/testisdn/testisdn.2005.vcproj deleted file mode 100644 index 133557166b..0000000000 --- a/libs/freetdm/msvc/testisdn/testisdn.2005.vcproj +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/testisdn/testisdn.2008.vcproj b/libs/freetdm/msvc/testisdn/testisdn.2008.vcproj deleted file mode 100644 index 86698ec3e4..0000000000 --- a/libs/freetdm/msvc/testisdn/testisdn.2008.vcproj +++ /dev/null @@ -1,349 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/msvc/testisdn/testisdn.2010.vcxproj.filters b/libs/freetdm/msvc/testisdn/testisdn.2010.vcxproj.filters deleted file mode 100644 index 9d48828d4a..0000000000 --- a/libs/freetdm/msvc/testisdn/testisdn.2010.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/sample/CMakeLists.txt b/libs/freetdm/sample/CMakeLists.txt deleted file mode 100644 index 9baf1bdf16..0000000000 --- a/libs/freetdm/sample/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -# Arnaldo M Pereira -# -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(sample) - -#ADD_SUBDIRECTORY(sched) FIXME: this code doesnt compile diff --git a/libs/freetdm/sample/dso/CMakeLists.txt b/libs/freetdm/sample/dso/CMakeLists.txt deleted file mode 100644 index defcc5c7f5..0000000000 --- a/libs/freetdm/sample/dso/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# Arnaldo M Pereira -# -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(dso) - -IF(NOT DEFINED WIN32) - INCLUDE_DIRECTORIES(/usr/local/freeswitch/include) - ADD_DEFINITIONS(-Wall) - ADD_EXECUTABLE(ftdmload ftdmload.c) - TARGET_LINK_LIBRARIES(ftdmload freetdm) -ENDIF(NOT DEFINED WIN32) diff --git a/libs/freetdm/sample/dso/Makefile b/libs/freetdm/sample/dso/Makefile deleted file mode 100644 index 51067191d2..0000000000 --- a/libs/freetdm/sample/dso/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CC=gcc -CFLAGS=-Wall -I/usr/local/freeswitch/include -LDFLAGS=-L/usr/local/freeswitch/lib -lfreetdm - -ftdmload: ftdmload.o - -clean: - rm -rf ftdmload.o - rm -rf ftdmload - -export: - export LD_LIBRARY_PATH=/usr/local/freeswitch/lib - - diff --git a/libs/freetdm/sample/dso/ftdmload.c b/libs/freetdm/sample/dso/ftdmload.c deleted file mode 100644 index 80bcc02fc0..0000000000 --- a/libs/freetdm/sample/dso/ftdmload.c +++ /dev/null @@ -1,168 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include - -#define ARRLEN(obj) (sizeof(obj)/sizeof(obj[0])) - -struct dso_entry { - char name[25]; - ftdm_dso_lib_t lib; -}; - -struct dso_entry loaded[10]; - -static void *(*real_dlopen)(const char *filename, int flag) = NULL; -static int (*real_dlclose)(void *handle) = NULL; - -static void print_stack() -{ - void *stacktrace[100]; - char **symbols; - int size; - int i; - size = backtrace(stacktrace, ARRLEN(stacktrace)); - symbols = backtrace_symbols(stacktrace, size); - if (!symbols) { - return; - } - for (i = 0; i < size; i++) { - ftdm_log(FTDM_LOG_DEBUG, "%s\n", symbols[i]); - } - free(symbols); -} - -void *dlopen(const char *filename, int flag) -{ - char *msg = NULL; - void *handle = NULL; - print_stack(); - if (real_dlopen == NULL) { - dlerror(); - real_dlopen = dlsym(RTLD_NEXT, "dlopen"); - if ((msg = dlerror()) != NULL) { - fprintf(stderr, "dlsym failed: %s\n", msg); - exit(1); - } - fprintf(stderr, "Real dlopen at addr %p\n", real_dlopen); - } - handle = real_dlopen(filename, flag); - if (!handle) { - return NULL; - } - ftdm_log(FTDM_LOG_NOTICE, "Loaded %s with handle %p\n", filename, handle); - return handle; -} - -int dlclose(void *handle) -{ - char *msg = NULL; - print_stack(); - if (real_dlclose == NULL) { - dlerror(); - real_dlclose = dlsym(RTLD_NEXT, "dlclose"); - if ((msg = dlerror()) != NULL) { - fprintf(stderr, "dlsym failed: %s\n", msg); - exit(1); - } - fprintf(stderr, "Real dlclose at addr %p\n", real_dlclose); - } - ftdm_log(FTDM_LOG_NOTICE, "Unloading %p\n", handle); - return real_dlclose(handle); -} - -int load(char *name) -{ - char path[255]; - char *err; - struct dso_entry *entry = NULL; - int i; - - for (i = 0; i < ARRLEN(loaded); i++) { - if (!loaded[i].lib) { - entry = &loaded[i]; - break; - } - } - - if (!entry) { - ftdm_log(FTDM_LOG_CRIT, "Cannot load more libraries\n"); - return -1; - } - - ftdm_build_dso_path(name, path, sizeof(path)); - ftdm_log(FTDM_LOG_DEBUG, "Loading %s!\n", path); - entry->lib = ftdm_dso_open(path, &err); - if (!entry->lib) { - ftdm_log(FTDM_LOG_CRIT, "Cannot load library '%s': %s\n", path, err); - return -1; - } - strncpy(entry->name, name, sizeof(entry->name)-1); - entry->name[sizeof(entry->name)-1] = 0; - return 0; -} - -int unload(char *name) -{ - int i; - struct dso_entry *entry = NULL; - ftdm_log(FTDM_LOG_DEBUG, "Unloading %s!\n", name); - for (i = 0; i < ARRLEN(loaded); i++) { - if (loaded[i].lib && !strcasecmp(loaded[i].name, name)) { - entry = &loaded[i]; - break; - } - } - - if (!entry) { - ftdm_log(FTDM_LOG_CRIT, "Library %s not found\n", name); - return -1; - } - - ftdm_dso_destroy(&entry->lib); - entry->lib = NULL; - return 0; -} - -int main(int argc, char *argv[]) -{ - char cmdline[255]; - char name[255]; - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - - if (ftdm_global_init() != FTDM_SUCCESS) { - fprintf(stderr, "Error loading FreeTDM\n"); - exit(-1); - } - - memset(loaded, 0, sizeof(loaded)); - - printf("CLI> "); - while (fgets(cmdline, sizeof(cmdline), stdin)) { - if (sscanf(cmdline, "load=%s\n", name) == 1) { - load(name); - } else if (sscanf(cmdline, "unload=%s\n", name) == 1) { - unload(name); - } else if (!strncasecmp(cmdline, "exit", sizeof("exit")-1)) { - printf("Quitting ...\n"); - sleep(1); - break; - } else { - fprintf(stderr, "load= | unload= | exit\n"); - } - printf("\nCLI> "); - } - - - ftdm_global_destroy(); - - printf("Done, press any key to die!\n"); - - getchar(); - return 0; -} - diff --git a/libs/freetdm/sample/sched/CMakeLists.txt b/libs/freetdm/sample/sched/CMakeLists.txt deleted file mode 100644 index d769925be0..0000000000 --- a/libs/freetdm/sample/sched/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# Arnaldo M Pereira -# -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(sched) - -IF(NOT DEFINED WIN32) - INCLUDE_DIRECTORIES(/usr/local/freeswitch/include) - ADD_DEFINITIONS(-Wall) - ADD_EXECUTABLE(ftdmsched ftdmsched.c) - TARGET_LINK_LIBRARIES(ftdmsched freetdm) -ENDIF(NOT DEFINED WIN32) diff --git a/libs/freetdm/sample/sched/ftdmsched.c b/libs/freetdm/sample/sched/ftdmsched.c deleted file mode 100644 index e6e391ee4b..0000000000 --- a/libs/freetdm/sample/sched/ftdmsched.c +++ /dev/null @@ -1,110 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include -#include "../../src/include/private/ftdm_core.h" - -static int running = 1; - -typedef struct custom_data { - ftdm_timer_t *heartbeat_timer; - int beat; - int counter; - ftdm_sched_callback_t callback; - ftdm_sched_t *sched; -} custom_data_t; - -void trap(int signal) -{ - running = 0; -} - -void handle_heartbeat(void *usrdata) -{ - ftdm_status_t status; - custom_data_t *data = usrdata; - - printf("beep (elapsed %dms count= %d)\n", data->beat, data->counter); - if (data->beat > 1000) { - data->beat -= 1000; - } else if (data->beat <= 1000 && data->beat > 200) { - data->beat -= 100; - } else if (data->beat <= 200 && data->beat > 100) { - if (!data->counter--) { - data->counter = 5; - data->beat -= 100; - } - } else if (data->beat <= 100 && data->beat > 10) { - if (!data->counter--) { - data->counter = 10; - data->beat -= 10; - if (data->beat == 10) { - data->counter = 200; - } - } - } else { - if (!data->counter--) { - data->counter = 5; - data->beat--; - } - } - - if (!data->beat) { - printf("beeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep you're dead!\n"); - return; - } - - data->heartbeat_timer = NULL; - status = ftdm_sched_timer(data->sched, "heartbeat", data->beat, data->callback, data, &data->heartbeat_timer); - if (status != FTDM_SUCCESS) { - fprintf(stderr, "Error creating heartbeat timer\n"); - running = 0; - return; - } -} - -int main(int argc, char *argv[]) -{ - ftdm_status_t status; - custom_data_t data; - - ftdm_sched_t *sched; - signal(SIGINT, trap); - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - - if (ftdm_global_init() != FTDM_SUCCESS) { - fprintf(stderr, "Error loading FreeTDM\n"); - exit(-1); - } - - status = ftdm_sched_create(&sched, "testsched"); - if (status != FTDM_SUCCESS) { - fprintf(stderr, "Error creating sched\n"); - exit(-1); - } - - data.sched = sched; - data.counter = 10; - data.beat = 5000; - data.callback = handle_heartbeat; - status = ftdm_sched_timer(sched, "heartbeat", data.beat, data.callback, &data, &data.heartbeat_timer); - if (status != FTDM_SUCCESS) { - fprintf(stderr, "Error creating heartbeat timer\n"); - exit(-1); - } - - ftdm_sched_free_run(sched); - - while (running) { - ftdm_sleep(10); - } - - ftdm_global_destroy(); - - printf("Done, press any key to die!\n"); - - getchar(); - return 0; -} - diff --git a/libs/freetdm/src/detect_dtmf.c b/libs/freetdm/src/detect_dtmf.c deleted file mode 100644 index 34335256f0..0000000000 --- a/libs/freetdm/src/detect_dtmf.c +++ /dev/null @@ -1,54 +0,0 @@ -//#include "freetdm.h" -#include "libteletone_detect.h" - -int main(int argc, char *argv[]) -{ - int fd, b; - short sln[512] = {0}; - teletone_dtmf_detect_state_t dtmf_detect = {0}; - teletone_hit_type_t hit; - - if (argc < 2) { - fprintf(stderr, "Arg Error!\n"); - exit(-1); - } - - teletone_dtmf_detect_init (&dtmf_detect, 8000); - - if ((fd = open(argv[1], O_RDONLY)) < 0) { - fprintf(stderr, "File Error! [%s]\n", strerror(errno)); - exit(-1); - } - - while((b = read(fd, sln, 320)) > 0) { - char digit_char; - unsigned int dur; - - teletone_dtmf_detect(&dtmf_detect, sln, b / 2); - if ((hit = teletone_dtmf_get(&dtmf_detect, &digit_char, &dur))) { - const char *hs = NULL; - - - switch(hit) { - case TT_HIT_BEGIN: - hs = "begin"; - break; - - case TT_HIT_MIDDLE: - hs = "middle"; - break; - - case TT_HIT_END: - hs = "end"; - break; - default: - break; - } - - printf("%s digit: %c\n", hs, digit_char); - } - } - close(fd); - return 0; -} - diff --git a/libs/freetdm/src/detect_tones.c b/libs/freetdm/src/detect_tones.c deleted file mode 100644 index 5cd52d4d99..0000000000 --- a/libs/freetdm/src/detect_tones.c +++ /dev/null @@ -1,32 +0,0 @@ -//#include "freetdm.h" -#include "libteletone_detect.h" - -int main(int argc, char *argv[]) -{ - teletone_multi_tone_t mt = {0}; - teletone_tone_map_t map = {{0}}; - - int fd, b; - short sln[512] = {0}; - - if (argc < 2) { - fprintf(stderr, "Arg Error!\n"); - exit(-1); - } - - map.freqs[0] = atof("350"); - map.freqs[1] = atof("440"); - teletone_multi_tone_init(&mt, &map); - - if ((fd = open(argv[1], O_RDONLY)) < 0) { - fprintf(stderr, "File Error! [%s]\n", strerror(errno)); - exit(-1); - } - - while((b = read(fd, sln, 320)) > 0) { - printf("TEST %d %d\n", b, teletone_multi_tone_detect(&mt, sln, b / 2)); - } - close(fd); - return 0; -} - diff --git a/libs/freetdm/src/fsk.c b/libs/freetdm/src/fsk.c deleted file mode 100644 index 9e6f97287e..0000000000 --- a/libs/freetdm/src/fsk.c +++ /dev/null @@ -1,351 +0,0 @@ - -/* - * bell202.c - * - * Copyright (c) 2005 Robert Krten. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This module contains a Bell-202 1200-baud FSK decoder, suitable for - * use in a library. The general style of the library calls is modeled - * after the POSIX pthread_*() functions. - * - * 2005 03 20 R. Krten created -*/ -#include -#include -#include -#include -#include -#include - -#include "fsk.h" -#include "uart.h" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -fsk_modem_definition_t fsk_modem_definitions[] = -{ - { /* FSK_V23_FORWARD_MODE1 */ 1700, 1300, 600 }, - { /* FSK_V23_FORWARD_MODE2 */ 2100, 1300, 1200 }, - { /* FSK_V23_BACKWARD */ 450, 390, 75 }, - { /* FSK_BELL202 */ 2200, 1200, 1200 }, -}; - -/* - * dsp_fsk_attr_init - * - * Initializes the attributes structure; this must be done before the - * attributes structure is used. -*/ - -void dsp_fsk_attr_init (dsp_fsk_attr_t *attr) -{ - memset(attr, 0, sizeof(*attr)); -} - -/* - * dsp_fsk_attr_get_bithandler - * dsp_fsk_attr_set_bithandler - * dsp_fsk_attr_get_bytehandler - * dsp_fsk_attr_set_bytehandler - * dsp_fsk_attr_getsamplerate - * dsp_fsk_attr_setsamplerate - * - * These functions get and set their respective elements from the - * attributes structure. If an error code is returned, it is just - * zero == ok, -1 == fail. -*/ - -bithandler_func_t dsp_fsk_attr_get_bithandler(dsp_fsk_attr_t *attr, void **bithandler_arg) -{ - *bithandler_arg = attr->bithandler_arg; - return attr->bithandler; -} - -void dsp_fsk_attr_set_bithandler(dsp_fsk_attr_t *attr, bithandler_func_t bithandler, void *bithandler_arg) -{ - attr->bithandler = bithandler; - attr->bithandler_arg = bithandler_arg; -} - -bytehandler_func_t dsp_fsk_attr_get_bytehandler(dsp_fsk_attr_t *attr, void **bytehandler_arg) -{ - *bytehandler_arg = attr->bytehandler_arg; - return attr->bytehandler; -} - -void dsp_fsk_attr_set_bytehandler(dsp_fsk_attr_t *attr, bytehandler_func_t bytehandler, void *bytehandler_arg) -{ - attr->bytehandler = bytehandler; - attr->bytehandler_arg = bytehandler_arg; -} - -int dsp_fsk_attr_get_samplerate (dsp_fsk_attr_t *attr) -{ - return attr->sample_rate; -} - -int dsp_fsk_attr_set_samplerate (dsp_fsk_attr_t *attr, int samplerate) -{ - if (samplerate <= 0) { - return -1; - } - attr->sample_rate = samplerate; - return 0; -} - -/* - * dsp_fsk_create - * - * Creates a handle for subsequent use. The handle is created to contain - * a context data structure for use by the sample handler function. The - * function expects an initialized attributes structure, and returns the - * handle or a NULL if there were errors. - * - * Once created, the handle can be used until it is destroyed. -*/ - -dsp_fsk_handle_t *dsp_fsk_create(dsp_fsk_attr_t *attr) -{ - int i; - double phi_mark, phi_space; - dsp_fsk_handle_t *handle; - - handle = ftdm_malloc(sizeof(*handle)); - if (!handle) { - return NULL; - } - - memset(handle, 0, sizeof(*handle)); - - /* fill the attributes member */ - memcpy(&handle->attr, attr, sizeof(*attr)); - - /* see if we can do downsampling. We only really need 6 samples to "match" */ - if (attr->sample_rate / fsk_modem_definitions[FSK_BELL202].freq_mark > 6) { - handle->downsampling_count = attr->sample_rate / fsk_modem_definitions[FSK_BELL202].freq_mark / 6; - } else { - handle->downsampling_count = 1; - } - handle->current_downsample = 1; - - /* calculate the correlate size (number of samples required for slowest wave) */ - handle->corrsize = attr->sample_rate / handle->downsampling_count / fsk_modem_definitions[FSK_BELL202].freq_mark; - - /* allocate the correlation sin/cos arrays and initialize */ - for (i = 0; i < 4; i++) { - handle->correlates[i] = ftdm_malloc(sizeof(double) * handle->corrsize); - if (handle->correlates[i] == NULL) { - /* some failed, back out memory allocations */ - dsp_fsk_destroy(&handle); - return NULL; - } - } - - /* now initialize them */ - phi_mark = 2. * M_PI / ((double) attr->sample_rate / (double) handle->downsampling_count / (double) fsk_modem_definitions[FSK_BELL202].freq_mark); - phi_space = 2. * M_PI / ((double) attr->sample_rate / (double) handle->downsampling_count / (double) fsk_modem_definitions[FSK_BELL202].freq_space); - - for (i = 0; i < handle->corrsize; i++) { - handle->correlates[0][i] = sin(phi_mark * (double) i); - handle->correlates[1][i] = cos(phi_mark * (double) i); - handle->correlates[2][i] = sin(phi_space * (double) i); - handle->correlates[3][i] = cos(phi_space * (double) i); - } - - /* initialize the ring buffer */ - handle->buffer = ftdm_malloc(sizeof(double) * handle->corrsize); - if (!handle->buffer) { /* failed; back out memory allocations */ - dsp_fsk_destroy(&handle); - return NULL; - } - memset(handle->buffer, 0, sizeof(double) * handle->corrsize); - handle->ringstart = 0; - - /* initalize intra-cell position */ - handle->cellpos = 0; - handle->celladj = fsk_modem_definitions[FSK_BELL202].baud_rate / (double) attr->sample_rate * (double) handle->downsampling_count; - - /* if they have provided a byte handler, add a UART to the processing chain */ - if (handle->attr.bytehandler) { - dsp_uart_attr_t uart_attr; - dsp_uart_handle_t *uart_handle; - - dsp_uart_attr_init(&uart_attr); - dsp_uart_attr_set_bytehandler(&uart_attr, handle->attr.bytehandler, handle->attr.bytehandler_arg); - uart_handle = dsp_uart_create(&uart_attr); - if (uart_handle == NULL) { - dsp_fsk_destroy(&handle); - return NULL; - } - handle->attr.bithandler = dsp_uart_bit_handler; - handle->attr.bithandler_arg = uart_handle; - } - - return handle; -} - -/* - * dsp_fsk_destroy - * - * Destroys a handle, releasing any associated memory. Sets handle pointer to NULL - * so A destroyed handle can not be used for anything after the destroy. -*/ - -void dsp_fsk_destroy(dsp_fsk_handle_t **handle) -{ - int i; - - /* if empty handle, just return */ - if (*handle == NULL) { - return; - } - - for (i = 0; i < 4; i++) { - if ((*handle)->correlates[i] != NULL) { - ftdm_safe_free((*handle)->correlates[i]); - (*handle)->correlates[i] = NULL; - } - } - - if ((*handle)->buffer != NULL) { - ftdm_safe_free((*handle)->buffer); - (*handle)->buffer = NULL; - } - - if ((*handle)->attr.bytehandler) { - dsp_uart_handle_t** dhandle = (void *)(&(*handle)->attr.bithandler_arg); - dsp_uart_destroy(dhandle); - } - - ftdm_safe_free(*handle); - *handle = NULL; -} - -/* - * dsp_fsk_sample - * - * This is the main processing entry point. The function accepts a normalized - * sample (i.e., one whose range is between -1 and +1). The function performs - * the Bell-202 FSK modem decode processing, and, if it detects a valid bit, - * will call the bithandler associated with the attributes structure. - * - * For the Bell-202 standard, a logical zero (space) is 2200 Hz, and a logical - * one (mark) is 1200 Hz. -*/ - -void -dsp_fsk_sample (dsp_fsk_handle_t *handle, double normalized_sample) -{ - double val; - double factors[4]; - int i, j; - - /* if we can avoid processing samples, do so */ - if (handle->downsampling_count != 1) { - if (handle->current_downsample < handle->downsampling_count) { - handle->current_downsample++; - return; /* throw this sample out */ - } - handle->current_downsample = 1; - } - - /* store sample in buffer */ - handle->buffer[handle->ringstart++] = normalized_sample; - if (handle->ringstart >= handle->corrsize) { - handle->ringstart = 0; - } - - /* do the correlation calculation */ - factors[0] = factors[1] = factors[2] = factors[3] = 0; /* clear out intermediate sums */ - j = handle->ringstart; - for (i = 0; i < handle->corrsize; i++) { - if (j >= handle->corrsize) { - j = 0; - } - val = handle->buffer[j]; - factors[0] += handle->correlates[0][i] * val; - factors[1] += handle->correlates[1][i] * val; - factors[2] += handle->correlates[2][i] * val; - factors[3] += handle->correlates[3][i] * val; - j++; - } - - /* store the bit (bit value is comparison of the two sets of correlate factors) */ - handle->previous_bit = handle->current_bit; - handle->current_bit = (factors[0] * factors[0] + factors[1] * factors[1] > factors[2] * factors[2] + factors[3] * factors[3]); - - /* if there's a transition, we can synchronize the cell position */ - if (handle->previous_bit != handle->current_bit) { - handle->cellpos = 0.5; /* adjust cell position to be in the middle of the cell */ - } - handle->cellpos += handle->celladj; /* walk the cell along */ - - if (handle->cellpos > 1.0) { - handle->cellpos -= 1.0; - - switch (handle->state) { - case FSK_STATE_DATA: - { - - (*handle->attr.bithandler) (handle->attr.bithandler_arg, handle->current_bit); - } - break; - case FSK_STATE_CHANSEIZE: - { - - if (handle->last_bit != handle->current_bit) { - handle->conscutive_state_bits++; - } else { - handle->conscutive_state_bits = 0; - } - - if (handle->conscutive_state_bits > 15) { - handle->state = FSK_STATE_CARRIERSIG; - handle->conscutive_state_bits = 0; - } - } - break; - case FSK_STATE_CARRIERSIG: - { - if (handle->current_bit) { - handle->conscutive_state_bits++; - } else { - handle->conscutive_state_bits = 0; - } - - if (handle->conscutive_state_bits > 15) { - handle->state = FSK_STATE_DATA; - handle->conscutive_state_bits = 0; - } - } - break; - } - - handle->last_bit = handle->current_bit; - } -} - diff --git a/libs/freetdm/src/ftdm_backtrace.c b/libs/freetdm/src/ftdm_backtrace.c deleted file mode 100644 index 8f6756d939..0000000000 --- a/libs/freetdm/src/ftdm_backtrace.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * - */ -#ifndef _DEFAULT_SOURCE -#define _DEFAULT_SOURCE -#endif -#define _BSD_SOURCE -#include "private/ftdm_core.h" - -#if defined(HAVE_EXECINFO_H) && !defined(__FreeBSD__) -#include -#include -#include -#include - -#define FTDM_BACKTRACE_MAX 50 - -FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv) -{ - void *stacktrace[FTDM_BACKTRACE_MAX]; - char **symbols = NULL; - size_t size = 0; - pid_t tid = 0; - int si = 0; - - if (!callback) { - return FTDM_EINVAL; - } - - tid = syscall(SYS_gettid); - - size = backtrace(stacktrace, ftdm_array_len(stacktrace)); - symbols = backtrace_symbols(stacktrace, size); - - for (si = 0; si < size; si++) { - callback(tid, stacktrace[si], symbols[si], priv); - } - - free(symbols); - return FTDM_SUCCESS; -} - -#else /* !HAVE_EXECINFO_H */ - -FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv) -{ - ftdm_log(FTDM_LOG_DEBUG, "Stack traces are not available on this platform!\n"); - return FTDM_NOTIMPL; -} - -#endif - - -static void span_backtrace(const int tid, const void *addr, const char *symbol, void *priv) -{ - ftdm_span_t *span = priv; - ftdm_log(FTDM_LOG_DEBUG, "[%d][tid:%d] %p -> %s\n", - ftdm_span_get_id(span), tid, addr, symbol); -} - -FT_DECLARE(ftdm_status_t) ftdm_backtrace_span(ftdm_span_t *span) -{ - return ftdm_backtrace_walk(&span_backtrace, span); -} - - -static void chan_backtrace(const int tid, const void *addr, const char *symbol, void *priv) -{ - ftdm_channel_t *chan = priv; - ftdm_log(FTDM_LOG_DEBUG, "[%d:%d][tid:%d] %p -> %s\n", - ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan), tid, addr, symbol); -} - -FT_DECLARE(ftdm_status_t) ftdm_backtrace_chan(ftdm_channel_t *chan) -{ - return ftdm_backtrace_walk(&chan_backtrace, chan); -} diff --git a/libs/freetdm/src/ftdm_buffer.c b/libs/freetdm/src/ftdm_buffer.c deleted file mode 100644 index 42d5fbaec6..0000000000 --- a/libs/freetdm/src/ftdm_buffer.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "private/ftdm_core.h" -#include "ftdm_buffer.h" - -static unsigned buffer_id = 0; - -struct ftdm_buffer { - unsigned char *data; - unsigned char *head; - ftdm_size_t used; - ftdm_size_t actually_used; - ftdm_size_t datalen; - ftdm_size_t max_len; - ftdm_size_t blocksize; - unsigned id; - int loops; -}; - - -FT_DECLARE(ftdm_status_t) ftdm_buffer_create(ftdm_buffer_t **buffer, ftdm_size_t blocksize, ftdm_size_t start_len, ftdm_size_t max_len) -{ - ftdm_buffer_t *new_buffer; - - new_buffer = ftdm_malloc(sizeof(*new_buffer)); - if (new_buffer) { - memset(new_buffer, 0, sizeof(*new_buffer)); - - if (!start_len) { - start_len = 250; - } - - if (!blocksize) { - blocksize = start_len; - } - - new_buffer->data = ftdm_malloc(start_len); - if (!new_buffer->data) { - ftdm_safe_free(new_buffer); - return FTDM_MEMERR; - } - memset(new_buffer->data, 0, start_len); - - new_buffer->max_len = max_len; - new_buffer->datalen = start_len; - new_buffer->id = buffer_id++; - new_buffer->blocksize = blocksize; - new_buffer->head = new_buffer->data; - - *buffer = new_buffer; - return FTDM_SUCCESS; - } - - return FTDM_MEMERR; -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_len(ftdm_buffer_t *buffer) -{ - - assert(buffer != NULL); - - return buffer->datalen; - -} - - -FT_DECLARE(ftdm_size_t) ftdm_buffer_freespace(ftdm_buffer_t *buffer) -{ - assert(buffer != NULL); - - - if (buffer->max_len) { - return (ftdm_size_t) (buffer->max_len - buffer->used); - } - return 1000000; - -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_inuse(ftdm_buffer_t *buffer) -{ - assert(buffer != NULL); - - return buffer->used; -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_seek(ftdm_buffer_t *buffer, ftdm_size_t datalen) -{ - ftdm_size_t reading = 0; - - assert(buffer != NULL); - - if (buffer->used < 1) { - buffer->used = 0; - return 0; - } else if (buffer->used >= datalen) { - reading = datalen; - } else { - reading = buffer->used; - } - - buffer->used = buffer->actually_used - reading; - buffer->head = buffer->data + reading; - - return reading; -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_toss(ftdm_buffer_t *buffer, ftdm_size_t datalen) -{ - ftdm_size_t reading = 0; - - assert(buffer != NULL); - - if (buffer->used < 1) { - buffer->used = 0; - return 0; - } else if (buffer->used >= datalen) { - reading = datalen; - } else { - reading = buffer->used; - } - - buffer->used -= reading; - buffer->head += reading; - - return buffer->used; -} - -FT_DECLARE(void) ftdm_buffer_set_loops(ftdm_buffer_t *buffer, int loops) -{ - buffer->loops = loops; -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_read_loop(ftdm_buffer_t *buffer, void *data, ftdm_size_t datalen) -{ - ftdm_size_t len; - if ((len = ftdm_buffer_read(buffer, data, datalen)) < datalen) { - if (buffer->loops == 0) { - return len; - } - buffer->head = buffer->data; - buffer->used = buffer->actually_used; - len = ftdm_buffer_read(buffer, (char*)data + len, datalen - len); - buffer->loops--; - } - return len; -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_read(ftdm_buffer_t *buffer, void *data, ftdm_size_t datalen) -{ - ftdm_size_t reading = 0; - - assert(buffer != NULL); - assert(data != NULL); - - - if (buffer->used < 1) { - buffer->used = 0; - return 0; - } else if (buffer->used >= datalen) { - reading = datalen; - } else { - reading = buffer->used; - } - - memcpy(data, buffer->head, reading); - buffer->used -= reading; - buffer->head += reading; - - /* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */ - return reading; -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_write(ftdm_buffer_t *buffer, const void *data, ftdm_size_t datalen) -{ - ftdm_size_t freespace, actual_freespace; - - assert(buffer != NULL); - assert(data != NULL); - assert(buffer->data != NULL); - - if (!datalen) { - return buffer->used; - } - - actual_freespace = buffer->datalen - buffer->actually_used; - if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) { - memmove(buffer->data, buffer->head, buffer->used); - buffer->head = buffer->data; - buffer->actually_used = buffer->used; - } - - freespace = buffer->datalen - buffer->used; - - /* - if (buffer->data != buffer->head) { - memmove(buffer->data, buffer->head, buffer->used); - buffer->head = buffer->data; - } - */ - - if (freespace < datalen) { - ftdm_size_t new_size, new_block_size; - void *data; - - new_size = buffer->datalen + datalen; - new_block_size = buffer->datalen + buffer->blocksize; - - if (new_block_size > new_size) { - new_size = new_block_size; - } - buffer->head = buffer->data; - data = realloc(buffer->data, new_size); - if (!data) { - return 0; - } - buffer->data = data; - buffer->head = buffer->data; - buffer->datalen = new_size; - } - - - freespace = buffer->datalen - buffer->used; - - if (freespace < datalen) { - return 0; - } else { - memcpy(buffer->head + buffer->used, data, datalen); - buffer->used += datalen; - buffer->actually_used += datalen; - } - /* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */ - - return buffer->used; -} - -FT_DECLARE(void) ftdm_buffer_zero(ftdm_buffer_t *buffer) -{ - assert(buffer != NULL); - assert(buffer->data != NULL); - - buffer->used = 0; - buffer->actually_used = 0; - buffer->head = buffer->data; -} - -FT_DECLARE(ftdm_size_t) ftdm_buffer_zwrite(ftdm_buffer_t *buffer, const void *data, ftdm_size_t datalen) -{ - ftdm_size_t w; - - if (!(w = ftdm_buffer_write(buffer, data, datalen))) { - ftdm_buffer_zero(buffer); - return ftdm_buffer_write(buffer, data, datalen); - } - - return w; -} - -FT_DECLARE(void) ftdm_buffer_destroy(ftdm_buffer_t **buffer) -{ - if (*buffer) { - ftdm_safe_free((*buffer)->data); - ftdm_safe_free(*buffer); - } - - *buffer = NULL; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_call_utils.c b/libs/freetdm/src/ftdm_call_utils.c deleted file mode 100644 index d23c95af4e..0000000000 --- a/libs/freetdm/src/ftdm_call_utils.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * Ricardo Barroetaveña - * - */ - -#include "private/ftdm_core.h" -#include - - - - -FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len) -{ - /* This implementation of url_encode is slightly different compared to the - * Freeswitch one. This is because this implementation accepts the full - * range of values (0x00 - 0xFF) compared to the Freeswitch implementation - * that does not accept 0x00 */ - - const char *p; - size_t x = 0,y = 0; - const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}"; - const char hex[] = "0123456789ABCDEF"; - - if (!buf) { - return 0; - } - - if (!url) { - return 0; - } - - len--; - - for (p = url; y <= len; p++) { - if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) { - buf[x++] = '%'; - buf[x++] = hex[(*p >> 4) & 0x0f]; - buf[x++] = hex[*p & 0x0f]; - } else { - buf[x++] = *p; - } - y++; - } - buf[x] = '\0'; - return buf; -} - - -FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len) -{ - /* This implementation of url_decode is slightly different compared to the - * Freeswitch one. This is because this implementation accepts the full - * range of values (0x00 - 0xFF) compared to the Freeswitch implementation - * that does not accept 0x00 */ - - char *o; - unsigned int tmp; - ftdm_size_t mylen = 0; - - if (ftdm_strlen_zero(s)) { - return s; - } - - for (o = s; *s; s++, o++) { - if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) { - *o = (char) tmp; - s += 2; - } else { - *o = *s; - } - mylen++; - } - *o = '\0'; - *len = mylen; - return s; -} - -FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *string, uint8_t *target) -{ - uint8_t val; - ftdm_status_t status = FTDM_SUCCESS; - - val = ftdm_str2ftdm_npi(string); - if (val == FTDM_NPI_INVALID) { - ftdm_log(FTDM_LOG_WARNING, "Invalid NPI string (%s)\n", string); - status = FTDM_FAIL; - val = FTDM_NPI_UNKNOWN; - } - *target = val; - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_set_ton(const char *string, uint8_t *target) -{ - uint8_t val; - ftdm_status_t status = FTDM_SUCCESS; - - val = ftdm_str2ftdm_ton(string); - if (val == FTDM_TON_INVALID) { - ftdm_log(FTDM_LOG_WARNING, "Invalid TON string (%s)\n", string); - status = FTDM_FAIL; - val = FTDM_TON_UNKNOWN; - } - *target = val; - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_set_bearer_capability(const char *string, uint8_t *target) -{ - uint8_t val; - ftdm_status_t status = FTDM_SUCCESS; - - val = ftdm_str2ftdm_bearer_cap(string); - if (val == FTDM_NPI_INVALID) { - ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer-Capability string (%s)\n", string); - status = FTDM_FAIL; - val = FTDM_BEARER_CAP_SPEECH; - } - - *target = val; - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_set_bearer_layer1(const char *string, uint8_t *target) -{ - uint8_t val; - ftdm_status_t status = FTDM_SUCCESS; - - val = ftdm_str2ftdm_usr_layer1_prot(string); - if (val == FTDM_USER_LAYER1_PROT_INVALID) { - ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer Layer 1 Protocol string (%s)\n", string); - status = FTDM_FAIL; - val = FTDM_USER_LAYER1_PROT_ULAW; - } - - *target = val; - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_set_screening_ind(const char *string, uint8_t *target) -{ - uint8_t val; - ftdm_status_t status = FTDM_SUCCESS; - - val = ftdm_str2ftdm_screening(string); - if (val == FTDM_SCREENING_INVALID) { - ftdm_log(FTDM_LOG_WARNING, "Invalid screening indicator string (%s)\n", string); - status = FTDM_FAIL; - val = FTDM_SCREENING_NOT_SCREENED; - } - - *target = val; - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t *target) -{ - uint8_t val; - ftdm_status_t status = FTDM_SUCCESS; - - val = ftdm_str2ftdm_presentation(string); - if (val == FTDM_PRES_INVALID) { - ftdm_log(FTDM_LOG_WARNING, "Invalid presentation string (%s)\n", string); - status = FTDM_FAIL; - val = FTDM_PRES_ALLOWED; - } - - *target = val; - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number) -{ - if (!number) { - return FTDM_FAIL; - } - - for ( ; *number; number++) { - if (!isdigit(*number)) { - return FTDM_FAIL; - } - } - return FTDM_SUCCESS; -} - - -FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target) -{ - uint8_t val; - ftdm_status_t status = FTDM_SUCCESS; - - val = ftdm_str2ftdm_calling_party_category(string); - if (val == FTDM_CPC_INVALID) { - ftdm_log(FTDM_LOG_WARNING, "Invalid category string (%s)\n", string); - val = FTDM_CPC_ORDINARY; - status = FTDM_FAIL; - } - - *target = val; - return status; -} - diff --git a/libs/freetdm/src/ftdm_callerid.c b/libs/freetdm/src/ftdm_callerid.c deleted file mode 100644 index d3223502f4..0000000000 --- a/libs/freetdm/src/ftdm_callerid.c +++ /dev/null @@ -1,307 +0,0 @@ -#include "private/ftdm_core.h" -#include "fsk.h" -#include "uart.h" - - - -static void fsk_byte_handler (void *x, int data) -{ - ftdm_fsk_data_state_t *state = (ftdm_fsk_data_state_t *) x; - uint8_t byte = (uint8_t)data; - - top: - - if (state->init == 3) { - return; - } - - if (state->dlen) { - goto add_byte; - } - - if (state->bpos == 1) { - state->blen = byte; - - if ((uint32_t)(state->dlen = state->bpos + byte + 2) > state->bufsize) { - state->dlen = state->bufsize; - } - goto top; - } - - add_byte: - - if (state->bpos <= state->dlen) { - state->buf[state->bpos++] = byte; - } else { - state->init = 3; - } -} - -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_init(ftdm_fsk_data_state_t *state, uint8_t *data, uint32_t datalen) -{ - memset(state, 0, sizeof(*state)); - state->buf = data; - state->bufsize = datalen; - state->bpos = 2; - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_sdmf(ftdm_fsk_data_state_t *state, const char *date, char *number) -{ - size_t dlen = strlen(date); - size_t nlen = strlen(number); - - state->buf[0] = FTDM_CID_TYPE_SDMF; - memcpy(&state->buf[state->bpos], date, dlen); - state->bpos += dlen; - memcpy(&state->buf[state->bpos], number, nlen); - state->bpos += nlen; - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_mdmf(ftdm_fsk_data_state_t *state, ftdm_mdmf_type_t type, const uint8_t *data, uint32_t datalen) -{ - state->buf[0] = FTDM_CID_TYPE_MDMF; - state->buf[state->bpos++] = type; - state->buf[state->bpos++] = (uint8_t)datalen; - memcpy(&state->buf[state->bpos], data, datalen); - state->bpos += datalen; - return FTDM_SUCCESS; -} - - -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_checksum(ftdm_fsk_data_state_t *state) -{ - uint32_t i; - uint8_t check = 0; - - state->buf[1] = (uint8_t)(state->bpos - 2); - - for (i = 0; i < state->bpos; i++) { - check = check + state->buf[i]; - } - - state->checksum = state->buf[state->bpos] = (uint8_t)(256 - check); - state->bpos++; - - state->dlen = state->bpos; - state->blen = state->buf[1]; - - return FTDM_SUCCESS; -} - - -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_parse(ftdm_fsk_data_state_t *state, ftdm_size_t *type, char **data, ftdm_size_t *len) -{ - - ftdm_size_t i; - int sum = 0; - - top: - - if (state->checksum != 0 || state->ppos >= state->dlen - 1) { - return FTDM_FAIL; - } - - if (!state->ppos) { - for(i = 0; i < state->bpos; i++) { - sum += state->buf[i]; - } - state->checksum = sum % 256; - state->ppos = 2; - - if (state->buf[0] != FTDM_CID_TYPE_MDMF && state->buf[0] != FTDM_CID_TYPE_SDMF) { - state->checksum = -1; - } - goto top; - } - - if (state->buf[0] == FTDM_CID_TYPE_SDMF) { - /* convert sdmf to mdmf so we don't need 2 parsers */ - if (state->ppos == 2) { - *type = MDMF_DATETIME; - *len = 8; - } else { - if (state->buf[state->ppos] == 'P' || state->buf[state->ppos] == 'O') { - *type = MDMF_NO_NUM; - *len = 1; - } else { - *type = MDMF_PHONE_NUM; - *len = state->blen - 8; - } - } - *data = (char *)&state->buf[state->ppos]; - state->ppos += *len; - return FTDM_SUCCESS; - } else if (state->buf[0] == FTDM_CID_TYPE_MDMF) { - *type = state->buf[state->ppos++]; - *len = state->buf[state->ppos++]; - *data = (char *)&state->buf[state->ppos]; - state->ppos += *len; - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -FT_DECLARE(ftdm_status_t) ftdm_fsk_demod_feed(ftdm_fsk_data_state_t *state, int16_t *data, ftdm_size_t samples) -{ - uint32_t x; - int16_t *sp = data; - - if (state->init == 3) { - return FTDM_FAIL; - } - - for (x = 0; x < samples; x++) { - dsp_fsk_sample (state->fsk1200_handle, (double) *sp++ / 32767.0); - if (state->dlen && state->bpos >= state->dlen) { - state->init = 3; - return FTDM_FAIL; - } - } - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_fsk_demod_destroy(ftdm_fsk_data_state_t *state) -{ - dsp_fsk_destroy(&state->fsk1200_handle); - memset(state, 0, sizeof(*state)); - return FTDM_SUCCESS; -} - -FT_DECLARE(int) ftdm_fsk_demod_init(ftdm_fsk_data_state_t *state, int rate, uint8_t *buf, ftdm_size_t bufsize) -{ - - dsp_fsk_attr_t fsk1200_attr; - - if (state->fsk1200_handle) { - dsp_fsk_destroy(&state->fsk1200_handle); - } - - memset(state, 0, sizeof(*state)); - memset(buf, 0, bufsize); - state->buf = buf; - state->bufsize = bufsize; - - dsp_fsk_attr_init (&fsk1200_attr); - dsp_fsk_attr_set_samplerate (&fsk1200_attr, rate); - dsp_fsk_attr_set_bytehandler (&fsk1200_attr, fsk_byte_handler, state); - state->fsk1200_handle = dsp_fsk_create (&fsk1200_attr); - - if (state->fsk1200_handle == NULL) { - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_size_t) ftdm_fsk_modulator_generate_bit(ftdm_fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, ftdm_size_t buflen) -{ - ftdm_size_t i; - - for(i = 0 ; i < buflen; i++) { - fsk_trans->bit_accum += fsk_trans->bit_factor; - if (fsk_trans->bit_accum >= FTDM_FSK_MOD_FACTOR) { - fsk_trans->bit_accum -= (FTDM_FSK_MOD_FACTOR + fsk_trans->bit_factor); - break; - } - - buf[i] = teletone_dds_state_modulate_sample(&fsk_trans->dds, bit); - } - - return i; -} - - -FT_DECLARE(int32_t) ftdm_fsk_modulator_generate_carrier_bits(ftdm_fsk_modulator_t *fsk_trans, uint32_t bits) -{ - uint32_t i = 0; - ftdm_size_t r = 0; - int8_t bit = 1; - - for (i = 0; i < bits; i++) { - if ((r = ftdm_fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { - if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != FTDM_SUCCESS) { - break; - } - } else { - break; - } - } - - return i; -} - - -FT_DECLARE(void) ftdm_fsk_modulator_generate_chan_sieze(ftdm_fsk_modulator_t *fsk_trans) -{ - uint32_t i = 0; - ftdm_size_t r = 0; - int8_t bit = 0; - - for (i = 0; i < fsk_trans->chan_sieze_bits; i++) { - if ((r = ftdm_fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { - if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != FTDM_SUCCESS) { - break; - } - } else { - break; - } - bit = !bit; - } - - -} - - -FT_DECLARE(void) ftdm_fsk_modulator_send_data(ftdm_fsk_modulator_t *fsk_trans) -{ - ftdm_size_t r = 0; - int8_t bit = 0; - - while((bit = ftdm_bitstream_get_bit(&fsk_trans->bs)) > -1) { - if ((r = ftdm_fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { - if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != FTDM_SUCCESS) { - break; - } - } else { - break; - } - } -} - - -FT_DECLARE(ftdm_status_t) ftdm_fsk_modulator_init(ftdm_fsk_modulator_t *fsk_trans, - fsk_modem_types_t modem_type, - uint32_t sample_rate, - ftdm_fsk_data_state_t *fsk_data, - float db_level, - uint32_t carrier_bits_start, - uint32_t carrier_bits_stop, - uint32_t chan_sieze_bits, - ftdm_fsk_write_sample_t write_sample_callback, - void *user_data) -{ - memset(fsk_trans, 0, sizeof(*fsk_trans)); - fsk_trans->modem_type = modem_type; - teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_space, sample_rate, 0); - teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_mark, sample_rate, 1); - fsk_trans->bit_factor = (uint32_t)((fsk_modem_definitions[fsk_trans->modem_type].baud_rate * FTDM_FSK_MOD_FACTOR) / (float)sample_rate); - fsk_trans->samples_per_bit = (uint32_t) (sample_rate / fsk_modem_definitions[fsk_trans->modem_type].baud_rate); - fsk_trans->est_bytes = (int32_t)(((fsk_data->dlen * 10) + carrier_bits_start + carrier_bits_stop + chan_sieze_bits) * ((fsk_trans->samples_per_bit + 1) * 2)); - fsk_trans->bit_accum = 0; - fsk_trans->fsk_data = fsk_data; - teletone_dds_state_set_tx_level(&fsk_trans->dds, db_level); - ftdm_bitstream_init(&fsk_trans->bs, fsk_trans->fsk_data->buf, (uint32_t)fsk_trans->fsk_data->dlen, FTDM_ENDIAN_BIG, 1); - fsk_trans->carrier_bits_start = carrier_bits_start; - fsk_trans->carrier_bits_stop = carrier_bits_stop; - fsk_trans->chan_sieze_bits = chan_sieze_bits; - fsk_trans->write_sample_callback = write_sample_callback; - fsk_trans->user_data = user_data; - return FTDM_SUCCESS; -} - diff --git a/libs/freetdm/src/ftdm_config.c b/libs/freetdm/src/ftdm_config.c deleted file mode 100644 index 9352284edf..0000000000 --- a/libs/freetdm/src/ftdm_config.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - */ - -#include "private/ftdm_core.h" - -#ifndef FTDM_MOD_DIR -#define FTDM_MOD_DIR "." -#endif - -#define FTDM_MAX_CONF_DIR 512 - -static char g_ftdm_config_dir[FTDM_MAX_CONF_DIR] = FTDM_CONFIG_DIR; -static char g_ftdm_mod_dir[FTDM_MAX_CONF_DIR] = FTDM_MOD_DIR; - -FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path) -{ - snprintf(g_ftdm_mod_dir, sizeof(g_ftdm_mod_dir), "%s", path); - ftdm_log(FTDM_LOG_DEBUG, "New mod directory: %s\n", g_ftdm_mod_dir); -} - -FT_DECLARE(void) ftdm_global_set_config_directory(const char *path) -{ - snprintf(g_ftdm_config_dir, sizeof(g_ftdm_config_dir), "%s", path); - ftdm_log(FTDM_LOG_DEBUG, "New config directory: %s\n", g_ftdm_config_dir); -} - -int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) -{ - FILE *f; - const char *path = NULL; - char path_buf[1024]; - - if (file_path[0] == '/') { - path = file_path; - } else { - snprintf(path_buf, sizeof(path_buf), "%s%s%s", g_ftdm_config_dir, FTDM_PATH_SEPARATOR, file_path); - path = path_buf; - } - - if (!path) { - return 0; - } - - memset(cfg, 0, sizeof(*cfg)); - cfg->lockto = -1; - ftdm_log(FTDM_LOG_DEBUG, "Configuration file is %s\n", path); - f = fopen(path, "r"); - - if (!f) { - if (file_path[0] != '/') { - int last = -1; - char *var, *val; - - snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", g_ftdm_config_dir, FTDM_PATH_SEPARATOR); - path = path_buf; - - if ((f = fopen(path, "r")) == 0) { - return 0; - } - - cfg->file = f; - ftdm_set_string(cfg->path, path); - - while (ftdm_config_next_pair(cfg, &var, &val)) { - if ((cfg->sectno != last) && !strcmp(cfg->section, file_path)) { - cfg->lockto = cfg->sectno; - return 1; - } - } - - ftdm_config_close_file(cfg); - memset(cfg, 0, sizeof(*cfg)); - return 0; - } - - return 0; - } else { - cfg->file = f; - ftdm_set_string(cfg->path, path); - return 1; - } -} - -void ftdm_config_close_file(ftdm_config_t *cfg) -{ - - if (cfg->file) { - fclose(cfg->file); - } - - memset(cfg, 0, sizeof(*cfg)); -} - - - -int ftdm_config_next_pair(ftdm_config_t *cfg, char **var, char **val) -{ - int ret = 0; - char *p, *end; - - *var = *val = NULL; - - if (!cfg->path) { - return 0; - } - - for (;;) { - cfg->lineno++; - - if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { - ret = 0; - break; - } - *var = cfg->buf; - - if (**var == '[' && (end = strchr(*var, ']')) != 0) { - *end = '\0'; - (*var)++; - if (**var == '+') { - (*var)++; - ftdm_copy_string(cfg->section, *var, sizeof(cfg->section)); - cfg->sectno++; - - if (cfg->lockto > -1 && cfg->sectno != cfg->lockto) { - break; - } - cfg->catno = 0; - cfg->lineno = 0; - *var = (char *) ""; - *val = (char *) ""; - return 1; - } else { - ftdm_copy_string(cfg->category, *var, sizeof(cfg->category)); - cfg->catno++; - } - continue; - } - - - - if (**var == '#' || **var == ';' || **var == '\n' || **var == '\r') { - continue; - } - - if (!strncmp(*var, "__END__", 7)) { - break; - } - - - if ((end = strchr(*var, ';')) && *(end+1) == *end) { - *end = '\0'; - end--; - } else if ((end = strchr(*var, '\n')) != 0) { - if (*(end - 1) == '\r') { - end--; - } - *end = '\0'; - } - - p = *var; - while ((*p == ' ' || *p == '\t') && p != end) { - *p = '\0'; - p++; - } - *var = p; - - - if ((*val = strchr(*var, '=')) == 0) { - ret = -1; - /* log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); */ - continue; - } else { - p = *val - 1; - *(*val) = '\0'; - (*val)++; - if (*(*val) == '>') { - *(*val) = '\0'; - (*val)++; - } - - while ((*p == ' ' || *p == '\t') && p != *var) { - *p = '\0'; - p--; - } - - p = *val; - while ((*p == ' ' || *p == '\t') && p != end) { - *p = '\0'; - p++; - } - *val = p; - ret = 1; - break; - } - } - - - return ret; - -} - -FT_DECLARE (int) ftdm_config_get_cas_bits(char *strvalue, unsigned char *outbits) -{ - char cas_bits[5]; - unsigned char bit = 0x8; - int x = 0; - char *double_colon = strchr(strvalue, ':'); - if (!double_colon) { - ftdm_log(FTDM_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", strvalue); - return -1; - } - double_colon++; - *outbits = 0; - cas_bits[4] = 0; - if (sscanf(double_colon, "%c%c%c%c", &cas_bits[0], &cas_bits[1], &cas_bits[2], &cas_bits[3]) != 4) { - ftdm_log(FTDM_LOG_ERROR, "Invalid CAS bits specified: '%s', :xxxx definition expected, where x is 1 or 0\n", double_colon); - return -1; - } - ftdm_log(FTDM_LOG_DEBUG, "CAS bits specification found: %s\n", cas_bits); - for (; cas_bits[x]; x++) { - if ('1' == cas_bits[x]) { - *outbits |= bit; - } else if ('0' != cas_bits[x]) { - ftdm_log(FTDM_LOG_ERROR, "Invalid CAS pattern specified: %s, just 0 or 1 allowed for each bit\n", - strvalue); - return -1; - } - bit >>= 1; - } - return 0; -} - -#define PARAMETERS_CHUNK_SIZE 20 -FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node_t **node, ftdm_conf_node_t *parent) -{ - ftdm_conf_node_t *newnode; - ftdm_conf_node_t *sibling = NULL; - - ftdm_assert_return(name != NULL, FTDM_FAIL, "null node name"); - - newnode = ftdm_calloc(1, sizeof(**node)); - if (!newnode) { - return FTDM_MEMERR; - } - - strncpy(newnode->name, name, sizeof(newnode->name)-1); - newnode->name[sizeof(newnode->name)-1] = 0; - - newnode->parameters = ftdm_calloc(PARAMETERS_CHUNK_SIZE, sizeof(*newnode->parameters)); - if (!newnode->parameters) { - ftdm_safe_free(newnode); - return FTDM_MEMERR; - } - newnode->t_parameters = PARAMETERS_CHUNK_SIZE; - - if (parent) { - /* store who my parent is */ - newnode->parent = parent; - - /* arrange them in FIFO order (newnode should be last) */ - if (!parent->child) { - /* we're the first node being added */ - parent->child = newnode; - } else { - if (!parent->last) { - /* we're the second node being added */ - parent->last = newnode; - parent->child->next = newnode; - newnode->prev = parent->child; - } else { - /* we're the third or Nth node to be added */ - sibling = parent->last; - sibling->next = newnode; - parent->last = newnode; - newnode->prev = sibling; - } - } - } - - *node = newnode; - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_conf_node_add_param(ftdm_conf_node_t *node, const char *param, const char *val) -{ - void *newparameters; - - ftdm_assert_return(param != NULL, FTDM_FAIL, "param is null"); - ftdm_assert_return(val != NULL, FTDM_FAIL, "val is null"); - - if (node->n_parameters == node->t_parameters) { - newparameters = ftdm_realloc(node->parameters, (node->t_parameters + PARAMETERS_CHUNK_SIZE) * sizeof(*node->parameters)); - if (!newparameters) { - return FTDM_MEMERR; - } - node->parameters = newparameters; - node->t_parameters = node->n_parameters + PARAMETERS_CHUNK_SIZE; - } - node->parameters[node->n_parameters].var = param; - node->parameters[node->n_parameters].val = val; - node->n_parameters++; - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node) -{ - ftdm_conf_node_t *curr = NULL; - ftdm_conf_node_t *child = node->child; - while (child) { - curr = child; - child = curr->next; - ftdm_conf_node_destroy(curr); - } - ftdm_free(node->parameters); - ftdm_free(node); - return FTDM_SUCCESS; -} - -FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len) -{ -#ifdef WIN32 - const char *ext = ".dll"; - //const char *EXT = ".DLL"; -#elif defined (MACOSX) || defined (DARWIN) - const char *ext = ".dylib"; - //const char *EXT = ".DYLIB"; -#else - const char *ext = ".so"; - //const char *EXT = ".SO"; -#endif - if (*name == *FTDM_PATH_SEPARATOR) { - snprintf(path, len, "%s%s", name, ext); - } else { - snprintf(path, len, "%s%s%s%s", g_ftdm_mod_dir, FTDM_PATH_SEPARATOR, name, ext); - } - return path; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_cpu_monitor.c b/libs/freetdm/src/ftdm_cpu_monitor.c deleted file mode 100644 index 1aa9b16c41..0000000000 --- a/libs/freetdm/src/ftdm_cpu_monitor.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * David Yat Sin - * - */ - -#ifdef WIN32 -# if (_WIN32_WINNT < 0x0501) -# error "Need to target at least Windows XP/Server 2003 because GetSystemTimes is needed" -# endif -# include -#else /* LINUX */ - -#include -#include -#include -#include -#include -#include -#include -#endif - -#include "private/ftdm_core.h" -#include "ftdm_cpu_monitor.h" -struct ftdm_cpu_monitor_stats -{ - /* bool, just used to retrieve the values for the first time and not calculate the percentage of idle time */ - int valid_last_times; - - /* last calculated percentage of idle time */ - double last_percentage_of_idle_time; - -#ifdef __linux__ - /* the cpu feature gets disabled on errors */ - int disabled; - - /* all of these are the Linux jiffies last retrieved count */ - unsigned long long last_user_time; - unsigned long long last_system_time; - unsigned long long last_idle_time; - - unsigned long long last_nice_time; - unsigned long long last_irq_time; - unsigned long long last_soft_irq_time; - unsigned long long last_io_wait_time; - unsigned long long last_steal_time; - - /* /proc/stat file descriptor used to retrieve the counters */ - int procfd; - int initd; -#elif defined (WIN32) || defined (WIN64) - __int64 i64LastUserTime; - __int64 i64LastKernelTime; - __int64 i64LastIdleTime; -#else -/* Unsupported */ -#endif -}; - -#ifdef __linux__ -static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p, - unsigned long long *user, - unsigned long long *nice, - unsigned long long *system, - unsigned long long *idle, - unsigned long long *iowait, - unsigned long long *irq, - unsigned long long *softirq, - unsigned long long *steal) -{ -// the output of proc should not change that often from one kernel to other -// see fs/proc/proc_misc.c or fs/proc/stat.c in the Linux kernel for more details -// also man 5 proc is useful. -#define CPU_ELEMENTS_1 7 // change this if you change the format string -#define CPU_INFO_FORMAT_1 "cpu %llu %llu %llu %llu %llu %llu %llu" - -#define CPU_ELEMENTS_2 8 // change this if you change the format string -#define CPU_INFO_FORMAT_2 "cpu %llu %llu %llu %llu %llu %llu %llu %llu" - -#define CPU_ELEMENTS_3 9 // change this if you change the format string -#define CPU_INFO_FORMAT_3 "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu" - - static const char procfile[] = "/proc/stat"; - int rc = 0; - int myerrno = 0; - int elements = 0; - const char *cpustr = NULL; - char statbuff[1024]; - unsigned long long guest = 0; - - if (!p->initd) { - p->procfd = open(procfile, O_RDONLY, 0); - if(p->procfd == -1) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open CPU statistics file %s: %s\n", procfile, strerror(myerrno)); - return FTDM_FAIL; - } - p->initd = 1; - } else { - lseek(p->procfd, 0L, SEEK_SET); - } - - rc = read(p->procfd, statbuff, sizeof(statbuff) - 1); - if (rc <= 0) { - myerrno = errno; - ftdm_log(FTDM_LOG_ERROR, "Failed to read CPU statistics file %s: %s\n", procfile, strerror(myerrno)); - return FTDM_FAIL; - } - - cpustr = strstr(statbuff, "cpu "); - if (!cpustr) { - ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: missing cpu string\n"); - return FTDM_FAIL; - } - - /* test each of the known formats starting from the bigger one */ - elements = sscanf(cpustr, CPU_INFO_FORMAT_3, user, nice, system, idle, iowait, irq, softirq, steal, &guest); - if (elements == CPU_ELEMENTS_3) { - user += guest; /* guest operating system's run in user space */ - return FTDM_SUCCESS; - } - - elements = sscanf(cpustr, CPU_INFO_FORMAT_2, user, nice, system, idle, iowait, irq, softirq, steal); - if (elements == CPU_ELEMENTS_2) { - return FTDM_SUCCESS; - } - - elements = sscanf(cpustr, CPU_INFO_FORMAT_1, user, nice, system, idle, iowait, irq, softirq); - if (elements == CPU_ELEMENTS_1) { - *steal = 0; - return FTDM_SUCCESS; - } - - ftdm_log(FTDM_LOG_ERROR, "Unexpected format for Linux proc cpu statistics:%s\n", cpustr); - return FTDM_FAIL; -} -#endif - -#ifdef __linux__ -FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor_stats *p, double *idle_percentage) -{ - unsigned long long user, nice, system, idle, iowait, irq, softirq, steal; - unsigned long long usertime, kerneltime, idletime, totaltime, halftime; - - *idle_percentage = 100.0; - if (p->disabled) { - return FTDM_FAIL; - } - if (ftdm_cpu_read_stats(p, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics - disabling cpu monitor\n"); - p->disabled = 1; - return FTDM_FAIL; - } - - if (!p->valid_last_times) { - // we dont strictly need to save all of them but I feel code is more clear if we do - p->valid_last_times = 1; - p->last_user_time = user; - p->last_nice_time = nice; - p->last_system_time = system; - p->last_irq_time = irq; - p->last_soft_irq_time = softirq; - p->last_io_wait_time = iowait; - p->last_steal_time = steal; - p->last_idle_time = idle; - p->last_percentage_of_idle_time = 100.0; - *idle_percentage = p->last_percentage_of_idle_time; - return FTDM_SUCCESS; - } - - usertime = (user - p->last_user_time) + (nice - p->last_nice_time); - kerneltime = (system - p->last_system_time) + (irq - p->last_irq_time) + (softirq - p->last_soft_irq_time); - kerneltime += (iowait - p->last_io_wait_time); - kerneltime += (steal - p->last_steal_time); - idletime = (idle - p->last_idle_time); - - totaltime = usertime + kerneltime + idletime; - - if (totaltime <= 0) { - // this may happen if not enough time has elapsed and the jiffies counters are the same than the last time we checked - // jiffies depend on timer interrupts which depend on the number of HZ compile time setting of the kernel - // typical configs set HZ to 100 (that means, 100 jiffies updates per second, that is one each 10ms) - // avoid an arithmetic exception and return the same values - *idle_percentage = p->last_percentage_of_idle_time; - return FTDM_SUCCESS; - } - - halftime = totaltime / 2UL; - - p->last_percentage_of_idle_time = ((100 * idletime + halftime) / totaltime); - *idle_percentage = p->last_percentage_of_idle_time; - - p->last_user_time = user; - p->last_nice_time = nice; - p->last_system_time = system; - p->last_irq_time = irq; - p->last_soft_irq_time = softirq; - p->last_io_wait_time = iowait; - p->last_steal_time = steal; - p->last_idle_time = idle; - - return FTDM_SUCCESS; -} - -#elif defined (__WINDOWS__) -FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage) -{ - FILETIME idleTime; - FILETIME kernelTime; - FILETIME userTime; - int64_t i64UserTime; - int64_t i64KernelTime; - int64_t i64IdleTime; - - if (!GetSystemTimes(&idleTime, &kernelTime, &userTime)) { - return FTDM_FAIL; - } - - i64UserTime = (int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32); - - i64KernelTime = (int64_t)kernelTime.dwLowDateTime | ((int64_t)kernelTime.dwHighDateTime << 32); - - i64IdleTime = (int64_t)idleTime.dwLowDateTime | ((int64_t)idleTime.dwHighDateTime << 32); - - if (p->valid_last_times) { - int64_t i64User = i64UserTime - p->i64LastUserTime; - int64_t i64Kernel = i64KernelTime - p->i64LastKernelTime; - int64_t i64Idle = i64IdleTime - p->i64LastIdleTime; - int64_t i64System = i64User + i64Kernel; - *idle_percentage = 100.0 * i64Idle / i64System; - } else { - *idle_percentage = 100.0; - p->valid_last_times = 1; - } - - /* Remember current value for the next call */ - p->i64LastUserTime = i64UserTime; - p->i64LastKernelTime = i64KernelTime; - p->i64LastIdleTime = i64IdleTime; - - /* Success */ - return FTDM_SUCCESS; -} -#else -/* Unsupported */ -FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage) -{ - *idle_percentage = 100.0; - return FTDM_FAIL; -} -#endif - -FT_DECLARE(struct ftdm_cpu_monitor_stats*) ftdm_new_cpu_monitor(void) -{ - return calloc(1, sizeof(struct ftdm_cpu_monitor_stats)); -} - -FT_DECLARE(void) ftdm_delete_cpu_monitor(struct ftdm_cpu_monitor_stats *p) -{ -#ifdef __linux__ - close(p->procfd); -#endif - free(p); -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_dso.c b/libs/freetdm/src/ftdm_dso.c deleted file mode 100755 index a646ed3469..0000000000 --- a/libs/freetdm/src/ftdm_dso.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Cross Platform dso/dll load abstraction - * Copyright(C) 2008 Michael Jerris - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so. - * - * This work is provided under this license on an "as is" basis, without warranty of any kind, - * either expressed or implied, including, without limitation, warranties that the covered code - * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire - * risk as to the quality and performance of the covered code is with you. Should any covered - * code prove defective in any respect, you (not the initial developer or any other contributor) - * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty - * constitutes an essential part of this license. No use of any covered code is authorized hereunder - * except under this disclaimer. - * - */ - -#include "private/ftdm_core.h" -#include "ftdm_dso.h" -#include -#include - -#ifdef WIN32 -#include -#include - - -FT_DECLARE(ftdm_status_t) ftdm_dso_destroy(ftdm_dso_lib_t *lib) { - if (lib && *lib) { - FreeLibrary(*lib); - *lib = NULL; - } - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_dso_lib_t) ftdm_dso_open(const char *path, char **err) { - HINSTANCE lib; - - lib = LoadLibraryEx(path, NULL, 0); - - if (!lib) { - LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - } - - if (!lib) { - DWORD error = GetLastError(); - char tmp[80]; - sprintf(tmp, "dll open error [%ul]\n", error); - *err = ftdm_strdup(tmp); - } - - return lib; -} - -FT_DECLARE(void*) ftdm_dso_func_sym(ftdm_dso_lib_t lib, const char *sym, char **err) { - FARPROC func = GetProcAddress(lib, sym); - if (!func) { - DWORD error = GetLastError(); - char tmp[80]; - sprintf(tmp, "dll sym error [%ul]\n", error); - *err = ftdm_strdup(tmp); - } - return (void *)(intptr_t)func; // this should really be addr - ftdm_dso_func_data -} - -#else - -/* -** {======================================================================== -** This is an implementation of loadlib based on the dlfcn interface. -** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, -** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least -** as an emulation layer on top of native functions. -** ========================================================================= -*/ - - -#include - -FT_DECLARE(ftdm_status_t) ftdm_dso_destroy(ftdm_dso_lib_t *lib) { - int rc; - if (lib && *lib) { - rc = dlclose(*lib); - if (rc) { - ftdm_log(FTDM_LOG_ERROR, "Failed to close lib %p: %s\n", *lib, dlerror()); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "lib %p was closed with success\n", *lib); - *lib = NULL; - return FTDM_SUCCESS; - } - ftdm_log(FTDM_LOG_ERROR, "Invalid pointer provided to ftdm_dso_destroy\n"); - return FTDM_FAIL; -} - -FT_DECLARE(ftdm_dso_lib_t) ftdm_dso_open(const char *path, char **err) { - void *lib = dlopen(path, RTLD_NOW | RTLD_LOCAL); - if (lib == NULL) { - *err = ftdm_strdup(dlerror()); - } - return lib; -} - -FT_DECLARE(void *) ftdm_dso_func_sym(ftdm_dso_lib_t lib, const char *sym, char **err) { - void *func = dlsym(lib, sym); - if (!func) { - *err = ftdm_strdup(dlerror()); - } - return func; -} -#endif - -/* }====================================================== */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c deleted file mode 100644 index 9adcd27509..0000000000 --- a/libs/freetdm/src/ftdm_io.c +++ /dev/null @@ -1,7027 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * David Yat Sin - * - */ -#define _GNU_SOURCE -#include "private/ftdm_core.h" -#include -#include -#ifdef WIN32 -#include -#endif -#ifdef FTDM_PIKA_SUPPORT -#include "ftdm_pika.h" -#endif -#include "ftdm_cpu_monitor.h" - -#ifndef localtime_r -struct tm *localtime_r(const time_t *clock, struct tm *result); -#endif - -#define FORCE_HANGUP_TIMER 30000 -#define FTDM_READ_TRACE_INDEX 0 -#define FTDM_WRITE_TRACE_INDEX 1 -#define MAX_CALLIDS 6000 -#define FTDM_HALF_DTMF_PAUSE 500 -#define FTDM_FULL_DTMF_PAUSE 1000 - -#define FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan) (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_DTMF_DETECTION)) - -ftdm_time_t time_last_throttle_log = 0; -ftdm_time_t time_current_throttle_log = 0; - -typedef struct val_str { - const char *str; - unsigned long long val; -} val_str_t; - -static val_str_t channel_flag_strs[] = { - { "configured" , FTDM_CHANNEL_CONFIGURED}, - { "ready", FTDM_CHANNEL_READY}, - { "open", FTDM_CHANNEL_OPEN}, - { "dtmf-detect", FTDM_CHANNEL_DTMF_DETECT}, - { "suppress-dtmf", FTDM_CHANNEL_SUPRESS_DTMF}, - { "transcode", FTDM_CHANNEL_TRANSCODE}, - { "buffer", FTDM_CHANNEL_BUFFER}, - { "in-thread", FTDM_CHANNEL_INTHREAD}, - { "wink", FTDM_CHANNEL_WINK}, - { "flash", FTDM_CHANNEL_FLASH}, - { "state-change", FTDM_CHANNEL_STATE_CHANGE}, - { "hold", FTDM_CHANNEL_HOLD}, - { "in-use", FTDM_CHANNEL_INUSE}, - { "off-hook", FTDM_CHANNEL_OFFHOOK}, - { "ringing", FTDM_CHANNEL_RINGING}, - { "progress-detect", FTDM_CHANNEL_PROGRESS_DETECT}, - { "callerid-detect", FTDM_CHANNEL_CALLERID_DETECT}, - { "outbound", FTDM_CHANNEL_OUTBOUND}, - { "suspended", FTDM_CHANNEL_SUSPENDED}, - { "3-way", FTDM_CHANNEL_3WAY}, - { "progress", FTDM_CHANNEL_PROGRESS}, - { "media", FTDM_CHANNEL_MEDIA}, - { "answered", FTDM_CHANNEL_ANSWERED}, - { "mute", FTDM_CHANNEL_MUTE}, - { "use-rx-gain", FTDM_CHANNEL_USE_RX_GAIN}, - { "use-tx-gain", FTDM_CHANNEL_USE_TX_GAIN}, - { "in-alarm", FTDM_CHANNEL_IN_ALARM}, - { "sig-up", FTDM_CHANNEL_SIG_UP}, - { "user-hangup", FTDM_CHANNEL_USER_HANGUP}, - { "rx-disabled", FTDM_CHANNEL_RX_DISABLED}, - { "tx-disabled", FTDM_CHANNEL_TX_DISABLED}, - { "call-started", FTDM_CHANNEL_CALL_STARTED}, - { "non-block", FTDM_CHANNEL_NONBLOCK}, - { "ind-ack-pending", FTDM_CHANNEL_IND_ACK_PENDING}, - { "blocking", FTDM_CHANNEL_BLOCKING}, - { "media", FTDM_CHANNEL_DIGITAL_MEDIA}, - { "native-sigbridge", FTDM_CHANNEL_NATIVE_SIGBRIDGE}, - { "sig-dtmf-detection", FTDM_CHANNEL_SIG_DTMF_DETECTION}, - { "invalid", FTDM_CHANNEL_MAX_FLAG}, -}; - -static val_str_t span_flag_strs[] = { - { "configured", FTDM_SPAN_CONFIGURED}, - { "started", FTDM_SPAN_STARTED}, - { "state-change", FTDM_SPAN_STATE_CHANGE}, - { "suspended", FTDM_SPAN_SUSPENDED}, - { "in-thread", FTDM_SPAN_IN_THREAD}, - { "stop-thread", FTDM_SPAN_STOP_THREAD}, - { "use-chan-queue", FTDM_SPAN_USE_CHAN_QUEUE}, - { "suggest-chan-id", FTDM_SPAN_SUGGEST_CHAN_ID}, - { "use-av-rate", FTDM_SPAN_USE_AV_RATE}, - { "power-saving", FTDM_SPAN_PWR_SAVING}, - { "signals-queue", FTDM_SPAN_USE_SIGNALS_QUEUE}, - { "proceed-state", FTDM_SPAN_USE_PROCEED_STATE}, - { "skip-state", FTDM_SPAN_USE_SKIP_STATES}, - { "non-stoppable", FTDM_SPAN_NON_STOPPABLE}, - { "use-transfer", FTDM_SPAN_USE_TRANSFER}, -}; - -static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data); -static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data); -static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan); -static ftdm_status_t ftdm_channel_sig_indicate(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_usrmsg_t *usrmsg); - -static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str); -static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val); - - -static int time_is_init = 0; - -static void time_init(void) -{ -#ifdef WIN32 - timeBeginPeriod(1); -#endif - time_is_init = 1; -} - -static void time_end(void) -{ -#ifdef WIN32 - timeEndPeriod(1); -#endif - time_is_init = 0; -} - -FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void) -{ -#ifdef WIN32 - return timeGetTime(); -#else - struct timeval tv; - gettimeofday(&tv, NULL); - return ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)); -#endif -} - -static void write_chan_io_dump(ftdm_io_dump_t *dump, char *dataptr, int dlen) -{ - int windex = dump->windex; - int avail = (int)dump->size - windex; - - if (!dump->buffer) { - return; - } - - if (dlen > avail) { - int diff = dlen - avail; - - ftdm_assert(diff < (int)dump->size, "Very small buffer or very big IO chunk!\n"); - - /* write only what we can and the rest at the beginning of the buffer */ - memcpy(&dump->buffer[windex], dataptr, avail); - memcpy(&dump->buffer[0], &dataptr[avail], diff); - windex = diff; - - /*ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p up to index %d\n\n", dump, windex);*/ - dump->wrapped = 1; - } else { - memcpy(&dump->buffer[windex], dataptr, dlen); - windex += dlen; - } - - if (windex == (int)dump->size) { - /*ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "wrapping around dump buffer %p\n", dump);*/ - windex = 0; - dump->wrapped = 1; - } - - dump->windex = windex; -} - -static void dump_chan_io_to_file(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, FILE *file) -{ - /* write the saved audio buffer */ - ftdm_size_t rc = 0; - ftdm_size_t towrite = 0; - - if (!dump->buffer) { - return; - } - - towrite = dump->size - dump->windex; - - if (dump->wrapped) { - rc = fwrite(&dump->buffer[dump->windex], 1, towrite, file); - if (rc != towrite) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %"FTDM_SIZE_FMT" out of %"FTDM_SIZE_FMT" bytes in io dump buffer: %s\n", - rc, towrite, strerror(errno)); - } - } - if (dump->windex) { - towrite = dump->windex; - rc = fwrite(&dump->buffer[0], 1, towrite, file); - if (rc != towrite) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "only wrote %"FTDM_SIZE_FMT" out of %"FTDM_SIZE_FMT" bytes in io dump buffer: %s\n", - rc, towrite, strerror(errno)); - } - } - dump->windex = 0; - dump->wrapped = 0; -} - -static void stop_chan_io_dump(ftdm_io_dump_t *dump) -{ - if (!dump->buffer) { - return; - } - ftdm_safe_free(dump->buffer); - memset(dump, 0, sizeof(*dump)); -} - -static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *dump, ftdm_size_t size) -{ - if (dump->buffer) { - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "IO dump is already started\n"); - return FTDM_FAIL; - } - memset(dump, 0, sizeof(*dump)); - dump->buffer = ftdm_malloc(size); - if (!dump->buffer) { - return FTDM_FAIL; - } - dump->size = size; - return FTDM_SUCCESS; -} - - -static void close_dtmf_debug_file(ftdm_channel_t *ftdmchan) -{ - if (ftdmchan->dtmfdbg.file) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "closing debug dtmf file\n"); - fclose(ftdmchan->dtmfdbg.file); - ftdmchan->dtmfdbg.file = NULL; - } -} - -static ftdm_status_t disable_dtmf_debug(ftdm_channel_t *ftdmchan) -{ - if (!ftdmchan->dtmfdbg.enabled) { - return FTDM_SUCCESS; - } - - if (!ftdmchan->rxdump.buffer) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "DTMF debug enabled but no rx dump?\n"); - return FTDM_FAIL; - } - - close_dtmf_debug_file(ftdmchan); - stop_chan_io_dump(&ftdmchan->rxdump); - ftdmchan->dtmfdbg.enabled = 0; - return FTDM_SUCCESS; -} - -typedef struct { - uint8_t enabled; - uint8_t running; - uint8_t alarm; - uint32_t interval; - uint8_t alarm_action_flags; - uint8_t set_alarm_threshold; - uint8_t clear_alarm_threshold; - ftdm_interrupt_t *interrupt; -} cpu_monitor_t; - -static struct { - ftdm_hash_t *interface_hash; - ftdm_hash_t *module_hash; - ftdm_hash_t *span_hash; - ftdm_hash_t *group_hash; - ftdm_mutex_t *mutex; - ftdm_mutex_t *span_mutex; - ftdm_mutex_t *group_mutex; - ftdm_sched_t *timingsched; - uint32_t span_index; - uint32_t group_index; - uint32_t running; - ftdm_span_t *spans; - ftdm_group_t *groups; - cpu_monitor_t cpu_monitor; - - ftdm_caller_data_t *call_ids[MAX_CALLIDS+1]; - ftdm_mutex_t *call_id_mutex; - uint32_t last_call_id; - char dtmfdebug_directory[1024]; -} globals; - -enum ftdm_enum_cpu_alarm_action_flags -{ - FTDM_CPU_ALARM_ACTION_WARN = (1 << 0), - FTDM_CPU_ALARM_ACTION_REJECT = (1 << 1) -}; - -/* enum lookup funcs */ -FTDM_ENUM_NAMES(TONEMAP_NAMES, TONEMAP_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_tonemap, ftdm_tonemap2str, ftdm_tonemap_t, TONEMAP_NAMES, FTDM_TONEMAP_INVALID) - -FTDM_ENUM_NAMES(OOB_NAMES, OOB_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t, OOB_NAMES, FTDM_OOB_INVALID) - -FTDM_ENUM_NAMES(TRUNK_TYPE_NAMES, TRUNK_TYPE_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t, TRUNK_TYPE_NAMES, FTDM_TRUNK_NONE) - -FTDM_ENUM_NAMES(TRUNK_MODE_NAMES, TRUNK_MODE_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_trunk_mode, ftdm_trunk_mode2str, ftdm_trunk_mode_t, TRUNK_MODE_NAMES, FTDM_TRUNK_MODE_INVALID) - -FTDM_ENUM_NAMES(START_TYPE_NAMES, START_TYPE_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t, START_TYPE_NAMES, FTDM_ANALOG_START_NA) - -FTDM_ENUM_NAMES(SIGNAL_NAMES, SIGNAL_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t, SIGNAL_NAMES, FTDM_SIGEVENT_INVALID) - -FTDM_ENUM_NAMES(MDMF_TYPE_NAMES, MDMF_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_mdmf_type, ftdm_mdmf_type2str, ftdm_mdmf_type_t, MDMF_TYPE_NAMES, MDMF_INVALID) - -FTDM_ENUM_NAMES(CHAN_TYPE_NAMES, CHAN_TYPE_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t, CHAN_TYPE_NAMES, FTDM_CHAN_TYPE_COUNT) - -FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID) - -FTDM_ENUM_NAMES(TRACE_DIR_NAMES, TRACE_DIR_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_trace_dir, ftdm_trace_dir2str, ftdm_trace_dir_t, TRACE_DIR_NAMES, FTDM_TRACE_DIR_INVALID) - -FTDM_ENUM_NAMES(TRACE_TYPE_NAMES, TRACE_TYPE_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_trace_type, ftdm_trace_type2str, ftdm_trace_type_t, TRACE_TYPE_NAMES, FTDM_TRACE_TYPE_INVALID) - -FTDM_ENUM_NAMES(TON_NAMES, TON_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t, TON_NAMES, FTDM_TON_INVALID) - -FTDM_ENUM_NAMES(NPI_NAMES, NPI_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t, NPI_NAMES, FTDM_NPI_INVALID) - -FTDM_ENUM_NAMES(PRESENTATION_NAMES, PRESENTATION_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t, PRESENTATION_NAMES, FTDM_PRES_INVALID) - -FTDM_ENUM_NAMES(SCREENING_NAMES, SCREENING_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t, SCREENING_NAMES, FTDM_SCREENING_INVALID) - -FTDM_ENUM_NAMES(BEARER_CAP_NAMES, BEARER_CAP_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t, BEARER_CAP_NAMES, FTDM_BEARER_CAP_INVALID) - -FTDM_ENUM_NAMES(USER_LAYER1_PROT_NAMES, USER_LAYER1_PROT_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t, USER_LAYER1_PROT_NAMES, FTDM_USER_LAYER1_PROT_INVALID) - -FTDM_ENUM_NAMES(CALLING_PARTY_CATEGORY_NAMES, CALLING_PARTY_CATEGORY_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t, CALLING_PARTY_CATEGORY_NAMES, FTDM_CPC_INVALID) - -FTDM_ENUM_NAMES(INDICATION_NAMES, INDICATION_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_channel_indication, ftdm_channel_indication2str, ftdm_channel_indication_t, INDICATION_NAMES, FTDM_CHANNEL_INDICATE_INVALID) - -FTDM_ENUM_NAMES(TRANSFER_RESPONSE_NAMES, TRANSFER_RESPONSE_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_transfer_response, ftdm_transfer_response2str, ftdm_transfer_response_t, TRANSFER_RESPONSE_NAMES, FTDM_TRANSFER_RESPONSE_INVALID) - -static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name); - -static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) -{ - ftdm_unused_arg(file); - ftdm_unused_arg(func); - ftdm_unused_arg(line); - ftdm_unused_arg(level); - ftdm_unused_arg(fmt); -} - - -const char *FTDM_LEVEL_NAMES[9] = { - "EMERG", - "ALERT", - "CRIT", - "ERROR", - "WARNING", - "NOTICE", - "INFO", - "DEBUG", - NULL -}; - -static int ftdm_log_level = FTDM_LOG_LEVEL_DEBUG; - -static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) -{ - char data[1024]; - va_list ap; - - if (level < 0 || level > 7) { - level = 7; - } - if (level > ftdm_log_level) { - return; - } - - va_start(ap, fmt); - - vsnprintf(data, sizeof(data), fmt, ap); - - fprintf(stderr, "[%s] %s:%d %s() %s", FTDM_LEVEL_NAMES[level], file, line, func, data); - - va_end(ap); - -} - -static __inline__ void *ftdm_std_malloc(void *pool, ftdm_size_t size) -{ - void *ptr = malloc(size); - ftdm_unused_arg(pool); - ftdm_assert_return(ptr != NULL, NULL, "Out of memory\n"); - return ptr; -} - -static __inline__ void *ftdm_std_calloc(void *pool, ftdm_size_t elements, ftdm_size_t size) -{ - void *ptr = calloc(elements, size); - ftdm_unused_arg(pool); - ftdm_assert_return(ptr != NULL, NULL, "Out of memory\n"); - return ptr; -} - -static __inline__ void *ftdm_std_realloc(void *pool, void *buff, ftdm_size_t size) -{ - buff = realloc(buff, size); - ftdm_unused_arg(pool); - ftdm_assert_return(buff != NULL, NULL, "Out of memory\n"); - return buff; -} - -static __inline__ void ftdm_std_free(void *pool, void *ptr) -{ - ftdm_unused_arg(pool); - ftdm_assert_return(ptr != NULL, , "Attempted to free null pointer"); - free(ptr); -} - -FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan) -{ - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) { - if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) { - /* If the ec is disabled on idle, we need to enable it unless is a digital call */ - if (caller_data->bearer_capability != FTDM_BEARER_CAP_UNRESTRICTED) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec for call in channel state %s\n", ftdm_channel_state2str(chan->state)); - ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL); - } - } else { - /* If the ec is enabled on idle, we do nothing unless is a digital call that needs it disabled */ - if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec for digital call in channel state %s\n", ftdm_channel_state2str(chan->state)); - ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL); - } - } - } -} - -FT_DECLARE(void) ftdm_set_echocancel_call_end(ftdm_channel_t *chan) -{ - if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) { - if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec on call end in channel state %s\n", ftdm_channel_state2str(chan->state)); - ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL); - } else { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec back on call end in channel state %s\n", ftdm_channel_state2str(chan->state)); - ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL); - } - } -} - -FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler = -{ - /*.pool =*/ NULL, - /*.malloc =*/ ftdm_std_malloc, - /*.calloc =*/ ftdm_std_calloc, - /*.realloc =*/ ftdm_std_realloc, - /*.free =*/ ftdm_std_free -}; - -FT_DECLARE_DATA ftdm_crash_policy_t g_ftdm_crash_policy = FTDM_CRASH_NEVER; - -static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t *caller_data) -{ - if (!caller_data) { - ftdm_log(FTDM_LOG_CRIT, "Error: trying to set caller data, but no caller_data!\n"); - return FTDM_FAIL; - } - - if (caller_data->dnis.plan >= FTDM_NPI_INVALID) { - caller_data->dnis.plan = span->default_caller_data.dnis.plan; - } - - if (caller_data->dnis.type >= FTDM_TON_INVALID) { - caller_data->dnis.type = span->default_caller_data.dnis.type; - } - - if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) { - caller_data->cid_num.plan = span->default_caller_data.cid_num.plan; - } - - if (caller_data->cid_num.type >= FTDM_TON_INVALID) { - caller_data->cid_num.type = span->default_caller_data.cid_num.type; - } - - if (caller_data->ani.plan >= FTDM_NPI_INVALID) { - caller_data->ani.plan = span->default_caller_data.ani.plan; - } - - if (caller_data->ani.type >= FTDM_TON_INVALID) { - caller_data->ani.type = span->default_caller_data.ani.type; - } - - if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) { - caller_data->rdnis.plan = span->default_caller_data.rdnis.plan; - } - - if (caller_data->rdnis.type >= FTDM_NPI_INVALID) { - caller_data->rdnis.type = span->default_caller_data.rdnis.type; - } - - if (caller_data->bearer_capability >= FTDM_BEARER_CAP_INVALID) { - caller_data->bearer_capability = span->default_caller_data.bearer_capability; - } - - if (caller_data->bearer_layer1 >= FTDM_USER_LAYER1_PROT_INVALID) { - caller_data->bearer_layer1 = span->default_caller_data.bearer_layer1; - } - - if (FTDM_FAIL == ftdm_is_number(caller_data->cid_num.digits)) { - ftdm_log(FTDM_LOG_DEBUG, "dropping caller id number %s since we only accept digits\n", caller_data->cid_num.digits); - caller_data->cid_num.digits[0] = '\0'; - } - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data) -{ - ftdm_status_t err = FTDM_SUCCESS; - if (!ftdmchan) { - ftdm_log(FTDM_LOG_CRIT, "trying to set caller data, but no ftdmchan!\n"); - return FTDM_FAIL; - } - if ((err = ftdm_set_caller_data(ftdmchan->span, caller_data)) != FTDM_SUCCESS) { - return err; - } - ftdmchan->caller_data = *caller_data; - if (ftdmchan->caller_data.bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA); - } - return FTDM_SUCCESS; -} - -FT_DECLARE_DATA ftdm_logger_t ftdm_log = null_logger; - -FT_DECLARE(void) ftdm_global_set_crash_policy(ftdm_crash_policy_t policy) -{ - g_ftdm_crash_policy |= policy; -} - -FT_DECLARE(ftdm_status_t) ftdm_global_set_memory_handler(ftdm_memory_handler_t *handler) -{ - if (!handler) { - return FTDM_FAIL; - } - if (!handler->malloc) { - return FTDM_FAIL; - } - if (!handler->calloc) { - return FTDM_FAIL; - } - if (!handler->free) { - return FTDM_FAIL; - } - memcpy(&g_ftdm_mem_handler, handler, sizeof(*handler)); - return FTDM_SUCCESS; -} - -FT_DECLARE(void) ftdm_global_set_logger(ftdm_logger_t logger) -{ - if (logger) { - ftdm_log = logger; - } else { - ftdm_log = null_logger; - } -} - -FT_DECLARE(void) ftdm_global_set_default_logger(int level) -{ - if (level < 0 || level > 7) { - level = 7; - } - - ftdm_log = default_logger; - ftdm_log_level = level; -} - -FT_DECLARE_NONSTD(int) ftdm_hash_equalkeys(void *k1, void *k2) -{ - return strcmp((char *) k1, (char *) k2) ? 0 : 1; -} - -FT_DECLARE_NONSTD(uint32_t) ftdm_hash_hashfromstring(void *ky) -{ - unsigned char *str = (unsigned char *) ky; - uint32_t hash = 0; - int c; - - while ((c = *str++)) { - hash = c + (hash << 6) + (hash << 16) - hash; - } - - return hash; -} - -static ftdm_status_t ftdm_channel_destroy(ftdm_channel_t *ftdmchan) -{ - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CONFIGURED)) { - - while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) { - ftdm_log(FTDM_LOG_INFO, "Waiting for thread to exit on channel %u:%u\n", ftdmchan->span_id, ftdmchan->chan_id); - ftdm_sleep(500); - } - - ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); - ftdm_buffer_destroy(&ftdmchan->pre_buffer); - ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - - ftdm_buffer_destroy(&ftdmchan->digit_buffer); - ftdm_buffer_destroy(&ftdmchan->gen_dtmf_buffer); - ftdm_buffer_destroy(&ftdmchan->dtmf_buffer); - ftdm_buffer_destroy(&ftdmchan->fsk_buffer); - ftdmchan->pre_buffer_size = 0; - - ftdm_safe_free(ftdmchan->dtmf_hangup_buf); - - if (ftdmchan->tone_session.buffer) { - teletone_destroy_session(&ftdmchan->tone_session); - memset(&ftdmchan->tone_session, 0, sizeof(ftdmchan->tone_session)); - } - - - if (ftdmchan->span->fio->channel_destroy) { - ftdm_log(FTDM_LOG_INFO, "Closing channel %s:%u:%u fd:%d\n", ftdmchan->span->type, ftdmchan->span_id, ftdmchan->chan_id, ftdmchan->sockfd); - if (ftdmchan->span->fio->channel_destroy(ftdmchan) == FTDM_SUCCESS) { - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_CONFIGURED); - } else { - ftdm_log(FTDM_LOG_ERROR, "Error Closing channel %u:%u fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, ftdmchan->sockfd); - } - } - - ftdm_mutex_destroy(&ftdmchan->mutex); - ftdm_mutex_destroy(&ftdmchan->pre_buffer_mutex); - if (ftdmchan->state_completed_interrupt) { - ftdm_interrupt_destroy(&ftdmchan->state_completed_interrupt); - } - } - - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span) -{ - ftdm_status_t status = FTDM_SUCCESS; - unsigned j; - - /* The signaling must be already stopped (this is just a sanity check, should never happen) */ - ftdm_assert_return(!ftdm_test_flag(span, FTDM_SPAN_STARTED), FTDM_FAIL, "Signaling for span %s has not been stopped, refusing to destroy span\n"); - - ftdm_mutex_lock(span->mutex); - - /* destroy the channels */ - ftdm_clear_flag(span, FTDM_SPAN_CONFIGURED); - for(j = 1; j <= span->chan_count && span->channels[j]; j++) { - ftdm_channel_t *cur_chan = span->channels[j]; - if (cur_chan) { - if (ftdm_test_flag(cur_chan, FTDM_CHANNEL_CONFIGURED)) { - ftdm_channel_destroy(cur_chan); - } - ftdm_safe_free(cur_chan); - cur_chan = NULL; - } - } - - /* destroy the I/O for the span */ - if (span->fio && span->fio->span_destroy) { - ftdm_log(FTDM_LOG_INFO, "Destroying span %u type (%s)\n", span->span_id, span->type); - if (span->fio->span_destroy(span) != FTDM_SUCCESS) { - status = FTDM_FAIL; - } - } - - /* destroy final basic resources of the span data structure */ - if (span->pendingchans) { - ftdm_queue_destroy(&span->pendingchans); - } - if (span->pendingsignals) { - ftdm_sigmsg_t *sigmsg = NULL; - while ((sigmsg = ftdm_queue_dequeue(span->pendingsignals))) { - ftdm_sigmsg_free(&sigmsg); - } - ftdm_queue_destroy(&span->pendingsignals); - } - ftdm_mutex_unlock(span->mutex); - ftdm_mutex_destroy(&span->mutex); - - /* Give the span a chance to destroy its own signaling data */ - if (span->destroy) { - span->destroy(span); - } else if (span->signal_data) { - /* We take care of their dirty business ... */ - ftdm_free(span->signal_data); - } - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_get_alarms(ftdm_channel_t *ftdmchan, ftdm_alarm_flag_t *alarmbits) -{ - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(alarmbits != NULL, FTDM_EINVAL, "null alarmbits argument\n"); - ftdm_assert_return(ftdmchan != NULL, FTDM_EINVAL, "null channel argument\n"); - ftdm_assert_return(ftdmchan->span != NULL, FTDM_EINVAL, "null span\n"); - ftdm_assert_return(ftdmchan->span->fio != NULL, FTDM_EINVAL, "null io\n"); - - *alarmbits = FTDM_ALARM_NONE; - - if (!ftdmchan->span->fio->get_alarms) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No get_alarms interface for this channel\n"); - return FTDM_ENOSYS; - } - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CONFIGURED)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot get alarms from an unconfigured channel\n"); - return FTDM_EINVAL; - } - - ftdm_channel_lock(ftdmchan); - - if ((status = ftdmchan->span->fio->get_alarms(ftdmchan)) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to get alarms from channel\n"); - goto done; - } - - *ftdmchan->last_error = '\0'; - *alarmbits = ftdmchan->alarm_flags; - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RED)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RED/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_YELLOW)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "YELLOW/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RAI)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RAI/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_BLUE)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "BLUE/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_AIS)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "AIS/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_GENERAL)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "GENERAL"); - } - *(ftdmchan->last_error + strlen(ftdmchan->last_error) - 1) = '\0'; - -done: - - ftdm_channel_unlock(ftdmchan); - - return status; -} - -static void ftdm_span_add(ftdm_span_t *span) -{ - ftdm_span_t *sp; - ftdm_mutex_lock(globals.span_mutex); - for (sp = globals.spans; sp && sp->next; sp = sp->next); - if (sp) { - sp->next = span; - } else { - globals.spans = span; - } - hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_FREE_VALUE); - ftdm_mutex_unlock(globals.span_mutex); -} - -FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span) -{ - ftdm_status_t status = FTDM_SUCCESS; - - ftdm_mutex_lock(span->mutex); - - if (ftdm_test_flag(span, FTDM_SPAN_NON_STOPPABLE)) { - status = FTDM_NOTIMPL; - goto done; - } - - if (!ftdm_test_flag(span, FTDM_SPAN_STARTED)) { - status = FTDM_EINVAL; - goto done; - } - - if (!span->stop) { - status = FTDM_ENOSYS; - goto done; - } - - /* Stop SIG */ - status = span->stop(span); - if (status == FTDM_SUCCESS) { - ftdm_clear_flag(span, FTDM_SPAN_STARTED); - } - - /* Stop I/O */ - if (span->fio && span->fio->span_stop) { - status = span->fio->span_stop(span); - } -done: - ftdm_mutex_unlock(span->mutex); - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_create(const char *iotype, const char *name, ftdm_span_t **span) -{ - ftdm_span_t *new_span = NULL; - ftdm_io_interface_t *fio = NULL; - ftdm_status_t status = FTDM_FAIL; - char buf[128] = ""; - - ftdm_assert_return(iotype != NULL, FTDM_FAIL, "No IO type provided\n"); - ftdm_assert_return(name != NULL, FTDM_FAIL, "No span name provided\n"); - - *span = NULL; - - fio = ftdm_global_get_io_interface(iotype, FTDM_TRUE); - if (!fio) { - ftdm_log(FTDM_LOG_CRIT, "failure creating span, no such I/O type '%s'\n", iotype); - return FTDM_FAIL; - } - - if (!fio->configure_span) { - ftdm_log(FTDM_LOG_CRIT, "failure creating span, no configure_span method for I/O type '%s'\n", iotype); - return FTDM_FAIL; - } - - ftdm_mutex_lock(globals.mutex); - if (globals.span_index < FTDM_MAX_SPANS_INTERFACE) { - new_span = ftdm_calloc(sizeof(*new_span), 1); - - ftdm_assert(new_span, "allocating span failed\n"); - - status = ftdm_mutex_create(&new_span->mutex); - ftdm_assert(status == FTDM_SUCCESS, "mutex creation failed\n"); - - ftdm_set_flag(new_span, FTDM_SPAN_CONFIGURED); - new_span->span_id = ++globals.span_index; - new_span->fio = fio; - ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_DIAL], "%(1000,0,350,440)", FTDM_TONEMAP_LEN); - ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_RING], "%(2000,4000,440,480)", FTDM_TONEMAP_LEN); - ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_BUSY], "%(500,500,480,620)", FTDM_TONEMAP_LEN); - ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_ATTN], "%(100,100,1400,2060,2450,2600)", FTDM_TONEMAP_LEN); - new_span->trunk_type = FTDM_TRUNK_NONE; - new_span->trunk_mode = FTDM_TRUNK_MODE_CPE; - new_span->data_type = FTDM_TYPE_SPAN; - - ftdm_mutex_lock(globals.span_mutex); - if (!ftdm_strlen_zero(name) && hashtable_search(globals.span_hash, (void *)name)) { - ftdm_log(FTDM_LOG_WARNING, "name %s is already used, substituting 'span%d' as the name\n", name, new_span->span_id); - name = NULL; - } - ftdm_mutex_unlock(globals.span_mutex); - - if (!name) { - snprintf(buf, sizeof(buf), "span%d", new_span->span_id); - name = buf; - } - new_span->name = ftdm_strdup(name); - new_span->type = ftdm_strdup(iotype); - ftdm_span_add(new_span); - *span = new_span; - status = FTDM_SUCCESS; - } - ftdm_mutex_unlock(globals.mutex); - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void) -{ - ftdm_span_t *span; - uint32_t i = 0, j; - - ftdm_mutex_lock(globals.span_mutex); - for (span = globals.spans; span; span = span->next) { - if (ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) { - for(j = 1; j <= span->chan_count && span->channels[j]; j++) { - ftdm_channel_t *toclose = span->channels[j]; - if (ftdm_test_flag(toclose, FTDM_CHANNEL_INUSE)) { - ftdm_channel_close(&toclose); - } - i++; - } - } - } - ftdm_mutex_unlock(globals.span_mutex); - - return i ? FTDM_SUCCESS : FTDM_FAIL; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_load_tones(ftdm_span_t *span, const char *mapname) -{ - ftdm_config_t cfg; - char *var, *val; - int x = 0; - - if (!ftdm_config_open_file(&cfg, "tones.conf")) { - snprintf(span->last_error, sizeof(span->last_error), "error loading tones."); - return FTDM_FAIL; - } - - while (ftdm_config_next_pair(&cfg, &var, &val)) { - int detect = 0; - - if (!strcasecmp(cfg.category, mapname) && var && val) { - uint32_t index; - char *name = NULL; - - if (!strncasecmp(var, "detect-", 7)) { - name = var + 7; - detect = 1; - } else if (!strncasecmp(var, "generate-", 9)) { - name = var + 9; - } else { - ftdm_log(FTDM_LOG_WARNING, "Unknown tone name %s\n", var); - continue; - } - - index = ftdm_str2ftdm_tonemap(name); - - if (index >= FTDM_TONEMAP_INVALID || index == FTDM_TONEMAP_NONE) { - ftdm_log(FTDM_LOG_WARNING, "Unknown tone name %s\n", name); - } else { - if (detect) { - char *p = val, *next; - int i = 0; - do { - teletone_process_t this; - next = strchr(p, ','); - this = (teletone_process_t)atof(p); - span->tone_detect_map[index].freqs[i++] = this; - if (next) { - p = next + 1; - } - } while (next); - ftdm_log(FTDM_LOG_DEBUG, "added tone detect [%s] = [%s]\n", name, val); - } else { - ftdm_log(FTDM_LOG_DEBUG, "added tone generation [%s] = [%s]\n", name, val); - ftdm_copy_string(span->tone_map[index], val, sizeof(span->tone_map[index])); - } - x++; - } - } - } - - ftdm_config_close_file(&cfg); - - if (!x) { - snprintf(span->last_error, sizeof(span->last_error), "error loading tones."); - return FTDM_FAIL; - } - - return FTDM_SUCCESS; - -} - -#define FTDM_SLINEAR_MAX_VALUE 32767 -#define FTDM_SLINEAR_MIN_VALUE -32767 -static void reset_gain_table(uint8_t *gain_table, float new_gain, ftdm_codec_t codec_gain) -{ - /* sample value */ - uint8_t sv = 0; - /* linear gain factor */ - float lingain = 0; - /* linear value for each table sample */ - float linvalue = 0; - /* amplified (or attenuated in case of negative amplification) sample value */ - int ampvalue = 0; - - /* gain tables are only for alaw and ulaw */ - if (codec_gain != FTDM_CODEC_ALAW && codec_gain != FTDM_CODEC_ULAW) { - ftdm_log(FTDM_LOG_DEBUG, "Not resetting gain table because codec is not ALAW or ULAW but %d\n", codec_gain); - return; - } - - if (!new_gain) { - /* for a 0.0db gain table, each alaw/ulaw sample value is left untouched (0 ==0, 1 == 1, 2 == 2 etc)*/ - sv = 0; - while (1) { - gain_table[sv] = sv; - if (sv == (FTDM_GAINS_TABLE_SIZE-1)) { - break; - } - sv++; - } - return; - } - - /* use the 20log rule to increase the gain: http://en.wikipedia.org/wiki/Gain, http:/en.wipedia.org/wiki/20_log_rule#Definitions */ - lingain = (float)pow(10.0, new_gain/ 20.0); - sv = 0; - while (1) { - /* get the linear value for this alaw/ulaw sample value */ - linvalue = codec_gain == FTDM_CODEC_ALAW ? (float)alaw_to_linear(sv) : (float)ulaw_to_linear(sv); - - /* multiply the linear value and the previously calculated linear gain */ - ampvalue = (int)(linvalue * lingain); - - /* chop it if goes beyond the limits */ - if (ampvalue > FTDM_SLINEAR_MAX_VALUE) { - ampvalue = FTDM_SLINEAR_MAX_VALUE; - } - - if (ampvalue < FTDM_SLINEAR_MIN_VALUE) { - ampvalue = FTDM_SLINEAR_MIN_VALUE; - } - gain_table[sv] = codec_gain == FTDM_CODEC_ALAW ? linear_to_alaw(ampvalue) : linear_to_ulaw(ampvalue); - if (sv == (FTDM_GAINS_TABLE_SIZE-1)) { - break; - } - sv++; - } -} - -FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t sockfd, ftdm_chan_type_t type, ftdm_channel_t **chan) -{ - unsigned char i = 0; - if (span->chan_count < FTDM_MAX_CHANNELS_SPAN) { - ftdm_channel_t *new_chan = span->channels[++span->chan_count]; - - if (!new_chan) { -#ifdef FTDM_DEBUG_CHAN_MEMORY - void *chanmem = NULL; - int pages = 1; - int pagesize = sysconf(_SC_PAGE_SIZE); - if (sizeof(*new_chan) > pagesize) { - pages = sizeof(*new_chan)/pagesize; - pages++; - } - ftdm_log(FTDM_LOG_DEBUG, "Allocating %d pages of %d bytes for channel of size %d\n", pages, pagesize, sizeof(*new_chan)); - if (posix_memalign(&chanmem, pagesize, pagesize*pages)) { - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "Channel pages allocated start at mem %p\n", chanmem); - memset(chanmem, 0, sizeof(*new_chan)); - new_chan = chanmem; -#else - if (!(new_chan = ftdm_calloc(1, sizeof(*new_chan)))) { - return FTDM_FAIL; - } -#endif - span->channels[span->chan_count] = new_chan; - } - - new_chan->type = type; - new_chan->sockfd = sockfd; - new_chan->fio = span->fio; - new_chan->span_id = span->span_id; - new_chan->chan_id = span->chan_count; - new_chan->span = span; - new_chan->fds[FTDM_READ_TRACE_INDEX] = -1; - new_chan->fds[FTDM_WRITE_TRACE_INDEX] = -1; - new_chan->data_type = FTDM_TYPE_CHANNEL; - if (!new_chan->dtmf_on) { - new_chan->dtmf_on = FTDM_DEFAULT_DTMF_ON; - } - - if (!new_chan->dtmf_off) { - new_chan->dtmf_off = FTDM_DEFAULT_DTMF_OFF; - } - - ftdm_mutex_create(&new_chan->mutex); - ftdm_mutex_create(&new_chan->pre_buffer_mutex); - - ftdm_buffer_create(&new_chan->digit_buffer, 128, 128, 0); - ftdm_buffer_create(&new_chan->gen_dtmf_buffer, 128, 128, 0); - - new_chan->dtmf_hangup_buf = ftdm_calloc (span->dtmf_hangup_len + 1, sizeof (char)); - - /* set 0.0db gain table */ - i = 0; - while (1) { - new_chan->txgain_table[i] = i; - new_chan->rxgain_table[i] = i; - if (i == (sizeof(new_chan->txgain_table)-1)) { - break; - } - i++; - } - - ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY); - new_chan->state = FTDM_CHANNEL_STATE_DOWN; - new_chan->state_status = FTDM_STATE_STATUS_COMPLETED; - *chan = new_chan; - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_find_by_name(const char *name, ftdm_span_t **span) -{ - ftdm_status_t status = FTDM_FAIL; - - ftdm_mutex_lock(globals.span_mutex); - if (!ftdm_strlen_zero(name)) { - if ((*span = hashtable_search(globals.span_hash, (void *)name))) { - status = FTDM_SUCCESS; - } else { - int span_id = atoi(name); - - ftdm_span_find(span_id, span); - if (*span) { - status = FTDM_SUCCESS; - } - } - } - ftdm_mutex_unlock(globals.span_mutex); - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_find(uint32_t id, ftdm_span_t **span) -{ - ftdm_span_t *fspan = NULL, *sp; - - if (id > FTDM_MAX_SPANS_INTERFACE) { - return FTDM_FAIL; - } - - ftdm_mutex_lock(globals.span_mutex); - for (sp = globals.spans; sp; sp = sp->next) { - if (sp->span_id == id) { - fspan = sp; - break; - } - } - ftdm_mutex_unlock(globals.span_mutex); - - if (!fspan || !ftdm_test_flag(fspan, FTDM_SPAN_CONFIGURED)) { - return FTDM_FAIL; - } - - *span = fspan; - - return FTDM_SUCCESS; - -} - -FT_DECLARE(ftdm_status_t) ftdm_span_poll_event(ftdm_span_t *span, uint32_t ms, short *poll_events) -{ - assert(span->fio != NULL); - - if (span->fio->poll_event) { - return span->fio->poll_event(span, ms, poll_events); - } else { - ftdm_log(FTDM_LOG_ERROR, "poll_event method not implemented in module %s!", span->fio->name); - } - - return FTDM_NOTIMPL; -} - -/* handle oob events and send the proper SIGEVENT signal to user, when applicable */ -static __inline__ ftdm_status_t ftdm_event_handle_oob(ftdm_event_t *event) -{ - ftdm_sigmsg_t sigmsg; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_channel_t *fchan = event->channel; - ftdm_span_t *span = fchan->span; - - memset(&sigmsg, 0, sizeof(sigmsg)); - sigmsg.span_id = span->span_id; - sigmsg.chan_id = fchan->chan_id; - sigmsg.channel = fchan; - switch (event->enum_id) { - case FTDM_OOB_ALARM_CLEAR: - { - sigmsg.event_id = FTDM_SIGEVENT_ALARM_CLEAR; - ftdm_clear_flag_locked(fchan, FTDM_CHANNEL_IN_ALARM); - status = ftdm_span_send_signal(span, &sigmsg); - } - break; - case FTDM_OOB_ALARM_TRAP: - { - sigmsg.event_id = FTDM_SIGEVENT_ALARM_TRAP; - ftdm_set_flag_locked(fchan, FTDM_CHANNEL_IN_ALARM); - status = ftdm_span_send_signal(span, &sigmsg); - } - break; - default: - /* NOOP */ - break; - } - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t **event) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_assert_return(span->fio != NULL, FTDM_FAIL, "No I/O module attached to this span!\n"); - - if (!span->fio->next_event) { - ftdm_log(FTDM_LOG_ERROR, "next_event method not implemented in module %s!", span->fio->name); - return FTDM_NOTIMPL; - } - - status = span->fio->next_event(span, event); - if (status != FTDM_SUCCESS) { - return status; - } - - status = ftdm_event_handle_oob(*event); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failed to handle event %d\n", (*event)->e_type); - } - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm_event_t **event) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_span_t *span = ftdmchan->span; - ftdm_assert_return(span->fio != NULL, FTDM_FAIL, "No I/O module attached to this span!\n"); - - ftdm_channel_lock(ftdmchan); - - if (!span->fio->channel_next_event) { - ftdm_log(FTDM_LOG_ERROR, "channel_next_event method not implemented in module %s!\n", span->fio->name); - status = FTDM_NOTIMPL; - goto done; - } - - if (ftdm_test_io_flag(ftdmchan, FTDM_CHANNEL_IO_EVENT)) { - ftdm_clear_io_flag(ftdmchan, FTDM_CHANNEL_IO_EVENT); - } - - status = span->fio->channel_next_event(ftdmchan, event); - if (status != FTDM_SUCCESS) { - goto done; - } - - status = ftdm_event_handle_oob(*event); - if (status != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "failed to handle event %d\n", (*event)->e_type); - } - -done: - ftdm_channel_unlock(ftdmchan); - return status; -} - -static ftdm_status_t ftdmchan_fsk_write_sample(int16_t *buf, ftdm_size_t buflen, void *user_data) -{ - ftdm_channel_t *ftdmchan = (ftdm_channel_t *) user_data; - ftdm_buffer_write(ftdmchan->fsk_buffer, buf, buflen * 2); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_send_fsk_data(ftdm_channel_t *ftdmchan, ftdm_fsk_data_state_t *fsk_data, float db_level) -{ - struct ftdm_fsk_modulator fsk_trans; - - if (!ftdmchan->fsk_buffer) { - ftdm_buffer_create(&ftdmchan->fsk_buffer, 128, 128, 0); - } else { - ftdm_buffer_zero(ftdmchan->fsk_buffer); - } - - if (ftdmchan->token_count > 1) { - ftdm_fsk_modulator_init(&fsk_trans, FSK_BELL202, ftdmchan->rate, fsk_data, db_level, 80, 5, 0, ftdmchan_fsk_write_sample, ftdmchan); - ftdm_fsk_modulator_send_all((&fsk_trans)); - } else { - ftdm_fsk_modulator_init(&fsk_trans, FSK_BELL202, ftdmchan->rate, fsk_data, db_level, 180, 5, 300, ftdmchan_fsk_write_sample, ftdmchan); - ftdm_fsk_modulator_send_all((&fsk_trans)); - ftdmchan->buffer_delay = 3500 / ftdmchan->effective_interval; - } - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_clear_token(ftdm_channel_t *ftdmchan, const char *token) -{ - ftdm_status_t status = FTDM_FAIL; - - ftdm_mutex_lock(ftdmchan->mutex); - if (token == NULL) { - memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens)); - ftdmchan->token_count = 0; - } else if (*token != '\0') { - char tokens[FTDM_MAX_TOKENS][FTDM_TOKEN_STRLEN]; - int32_t i, count = ftdmchan->token_count; - memcpy(tokens, ftdmchan->tokens, sizeof(tokens)); - memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens)); - ftdmchan->token_count = 0; - - for (i = 0; i < count; i++) { - if (strcmp(tokens[i], token)) { - ftdm_copy_string(ftdmchan->tokens[ftdmchan->token_count], tokens[i], sizeof(ftdmchan->tokens[ftdmchan->token_count])); - ftdmchan->token_count++; - } - } - - status = FTDM_SUCCESS; - } - ftdm_mutex_unlock(ftdmchan->mutex); - - return status; -} - -FT_DECLARE(void) ftdm_channel_rotate_tokens(ftdm_channel_t *ftdmchan) -{ - if (ftdmchan->token_count) { - memmove(ftdmchan->tokens[1], ftdmchan->tokens[0], ftdmchan->token_count * FTDM_TOKEN_STRLEN); - ftdm_copy_string(ftdmchan->tokens[0], ftdmchan->tokens[ftdmchan->token_count], FTDM_TOKEN_STRLEN); - *ftdmchan->tokens[ftdmchan->token_count] = '\0'; - } -} - -FT_DECLARE(void) ftdm_channel_replace_token(ftdm_channel_t *ftdmchan, const char *old_token, const char *new_token) -{ - unsigned int i; - - if (ftdmchan->token_count) { - for(i = 0; i < ftdmchan->token_count; i++) { - if (!strcmp(ftdmchan->tokens[i], old_token)) { - ftdm_copy_string(ftdmchan->tokens[i], new_token, FTDM_TOKEN_STRLEN); - break; - } - } - } -} - -FT_DECLARE(void) ftdm_channel_set_private(ftdm_channel_t *ftdmchan, void *pvt) -{ - ftdmchan->user_private = pvt; -} - -FT_DECLARE(void *) ftdm_channel_get_private(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->user_private; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_token_count(const ftdm_channel_t *ftdmchan) -{ - uint32_t count; - ftdm_mutex_lock(ftdmchan->mutex); - count = ftdmchan->token_count; - ftdm_mutex_unlock(ftdmchan->mutex); - return count; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_io_interval(const ftdm_channel_t *ftdmchan) -{ - uint32_t count; - ftdm_mutex_lock(ftdmchan->mutex); - count = ftdmchan->effective_interval; - ftdm_mutex_unlock(ftdmchan->mutex); - return count; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_io_packet_len(const ftdm_channel_t *ftdmchan) -{ - uint32_t count; - ftdm_mutex_lock(ftdmchan->mutex); - count = ftdmchan->packet_len; - ftdm_mutex_unlock(ftdmchan->mutex); - return count; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_type(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->type; -} - -FT_DECLARE(ftdm_codec_t) ftdm_channel_get_codec(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->effective_codec; -} - -FT_DECLARE(const char *) ftdm_channel_get_token(const ftdm_channel_t *ftdmchan, uint32_t tokenid) -{ - const char *token = NULL; - ftdm_mutex_lock(ftdmchan->mutex); - - if (ftdmchan->token_count <= tokenid) { - ftdm_mutex_unlock(ftdmchan->mutex); - return NULL; - } - - token = ftdmchan->tokens[tokenid]; - ftdm_mutex_unlock(ftdmchan->mutex); - return token; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_add_token(ftdm_channel_t *ftdmchan, char *token, int end) -{ - ftdm_status_t status = FTDM_FAIL; - - ftdm_mutex_lock(ftdmchan->mutex); - if (ftdmchan->token_count < FTDM_MAX_TOKENS) { - if (end) { - ftdm_copy_string(ftdmchan->tokens[ftdmchan->token_count++], token, FTDM_TOKEN_STRLEN); - } else { - memmove(ftdmchan->tokens[1], ftdmchan->tokens[0], ftdmchan->token_count * FTDM_TOKEN_STRLEN); - ftdm_copy_string(ftdmchan->tokens[0], token, FTDM_TOKEN_STRLEN); - ftdmchan->token_count++; - } - status = FTDM_SUCCESS; - } - ftdm_mutex_unlock(ftdmchan->mutex); - - return status; -} - - -FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group) -{ - return group->group_id; -} - -FT_DECLARE(ftdm_status_t) ftdm_group_channel_use_count(ftdm_group_t *group, uint32_t *count) -{ - uint32_t j; - - *count = 0; - - if (!group) { - return FTDM_FAIL; - } - - for(j = 0; j < group->chan_count && group->channels[j]; j++) { - if (group->channels[j]) { - if (ftdm_test_flag(group->channels[j], FTDM_CHANNEL_INUSE)) { - (*count)++; - } - } - } - - return FTDM_SUCCESS; -} - -static __inline__ int chan_is_avail(ftdm_channel_t *check) -{ - if ((check->span->signal_type == FTDM_SIGTYPE_M2UA) || - (check->span->signal_type == FTDM_SIGTYPE_NONE)) { - if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) || - ftdm_test_flag(check, FTDM_CHANNEL_INUSE) || - ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) || - ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) || - check->state != FTDM_CHANNEL_STATE_DOWN) { - return 0; - } - } else { - if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) || - !ftdm_test_flag(check, FTDM_CHANNEL_SIG_UP) || - ftdm_test_flag(check, FTDM_CHANNEL_INUSE) || - ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) || - ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) || - check->state != FTDM_CHANNEL_STATE_DOWN) { - return 0; - } - } - /* release guard time check */ - if (check->span->sig_release_guard_time_ms && check->last_release_time) { - ftdm_time_t time_diff = (ftdm_current_time_in_ms() - check->last_release_time); - if (time_diff < check->span->sig_release_guard_time_ms) { - return 0; - } - /* circuit now available for outbound dialing */ - check->last_release_time = 0; - ftdm_log_chan(check, FTDM_LOG_DEBUG, "Channel is now available, release guard timer expired %" FTDM_UINT64_FMT "ms ago\n", (time_diff - check->span->sig_release_guard_time_ms)); - } - return 1; -} - -static __inline__ int chan_voice_is_avail(ftdm_channel_t *check) -{ - if (!FTDM_IS_VOICE_CHANNEL(check)) { - return 0; - } - return chan_is_avail(check); -} - -static __inline__ int request_voice_channel(ftdm_channel_t *check, ftdm_channel_t **ftdmchan, - ftdm_caller_data_t *caller_data, ftdm_hunt_direction_t direction) -{ - ftdm_status_t status; - if (chan_voice_is_avail(check)) { - /* unlocked testing passed, try again with the channel locked */ - ftdm_mutex_lock(check->mutex); - if (chan_voice_is_avail(check)) { - if (check->span && check->span->channel_request) { - /* I am only unlocking here cuz this function is called - * sometimes with the group or span lock held and were - * blocking anyone hunting for channels available and - * I believe teh channel_request() function may take - * a bit of time. However channel_request is a callback - * used by boost and may be only a few other old sig mods - * and it should be deprecated */ - ftdm_mutex_unlock(check->mutex); - ftdm_set_caller_data(check->span, caller_data); - status = check->span->channel_request(check->span, check->chan_id, - direction, caller_data, ftdmchan); - if (status == FTDM_SUCCESS) { - return 1; - } - } else { - status = ftdm_channel_open_chan(check); - if (status == FTDM_SUCCESS) { - *ftdmchan = check; - ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND); -#if 0 - ftdm_mutex_unlock(check->mutex); -#endif - return 1; - } - } - } - ftdm_mutex_unlock(check->mutex); - } - return 0; -} - -static void __inline__ calculate_best_rate(ftdm_channel_t *check, ftdm_channel_t **best_rated, int *best_rate) -{ - if (ftdm_test_flag(check->span, FTDM_SPAN_USE_AV_RATE)) { - ftdm_mutex_lock(check->mutex); - if (ftdm_test_flag(check, FTDM_CHANNEL_INUSE)) { - /* twiddle */ - } else if (ftdm_test_flag(check, FTDM_CHANNEL_SIG_UP)) { - /* twiddle */ - } else if (check->availability_rate > *best_rate){ - /* the channel is not in use and the signaling status is down, - * it is a potential candidate to place a call */ - *best_rated = check; - *best_rate = check->availability_rate; - } - ftdm_mutex_unlock(check->mutex); - } -} - -static ftdm_status_t __inline__ get_best_rated(ftdm_channel_t **fchan, ftdm_channel_t *best_rated) -{ - ftdm_status_t status; - - if (!best_rated) { - return FTDM_FAIL; - } - - ftdm_mutex_lock(best_rated->mutex); - - if (ftdm_test_flag(best_rated, FTDM_CHANNEL_INUSE)) { - ftdm_mutex_unlock(best_rated->mutex); - return FTDM_FAIL; - } - - ftdm_log_chan_msg(best_rated, FTDM_LOG_DEBUG, "I may not be available but I had the best availability rate, trying to open I/O now\n"); - - status = ftdm_channel_open_chan(best_rated); - if (status != FTDM_SUCCESS) { - ftdm_mutex_unlock(best_rated->mutex); - return FTDM_FAIL; - } - *fchan = best_rated; - ftdm_set_flag(best_rated, FTDM_CHANNEL_OUTBOUND); -#if 0 - ftdm_mutex_unlock(best_rated->mutex); -#endif - return FTDM_SUCCESS; -} - -static uint32_t __inline__ rr_next(uint32_t last, uint32_t min, uint32_t max, ftdm_hunt_direction_t direction) -{ - uint32_t next = min; - - ftdm_log(FTDM_LOG_DEBUG, "last = %d, min = %d, max = %d\n", last, min, max); - - if (direction == FTDM_HUNT_RR_UP) { - next = (last >= max) ? min : ++last; - } else { - next = (last <= min) ? max : --last; - } - return next; -} - - -FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan) -{ - int availability = -1; - ftdm_channel_lock(ftdmchan); - if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_AV_RATE)) { - availability = ftdmchan->availability_rate; - } - ftdm_channel_unlock(ftdmchan); - return availability; -} - -static ftdm_status_t _ftdm_channel_open_by_group(uint32_t group_id, ftdm_hunt_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_channel_t *check = NULL; - ftdm_channel_t *best_rated = NULL; - ftdm_group_t *group = NULL; - int best_rate = 0; - uint32_t i = 0; - uint32_t count = 0; - uint32_t first_channel = 0; - - if (group_id) { - ftdm_group_find(group_id, &group); - } - - if (!group) { - ftdm_log(FTDM_LOG_ERROR, "Group %d not defined!\n", group_id); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - ftdm_group_channel_use_count(group, &count); - - if (count >= group->chan_count) { - ftdm_log(FTDM_LOG_WARNING, "All circuits are busy (%d channels used out of %d available).\n", count, group->chan_count); - *ftdmchan = NULL; - return FTDM_FAIL; - } - - - if (direction == FTDM_HUNT_BOTTOM_UP) { - i = 0; - } else if (direction == FTDM_HUNT_RR_DOWN || direction == FTDM_HUNT_RR_UP) { - i = rr_next(group->last_used_index, 0, group->chan_count - 1, direction); - first_channel = i; - } else { - i = group->chan_count-1; - } - - ftdm_mutex_lock(group->mutex); - for (;;) { - - if (!(check = group->channels[i])) { - status = FTDM_FAIL; - break; - } - - if (request_voice_channel(check, ftdmchan, caller_data, direction)) { - status = FTDM_SUCCESS; - if (direction == FTDM_HUNT_RR_UP || direction == FTDM_HUNT_RR_DOWN) { - group->last_used_index = i; - } - break; - } - - calculate_best_rate(check, &best_rated, &best_rate); - - if (direction == FTDM_HUNT_BOTTOM_UP) { - if (i >= (group->chan_count - 1)) { - break; - } - i++; - } else if (direction == FTDM_HUNT_RR_DOWN || direction == FTDM_HUNT_RR_UP) { - if (check == best_rated) { - group->last_used_index = i; - } - i = rr_next(i, 0, group->chan_count - 1, direction); - if (first_channel == i) { - break; - } - } else { - if (i == 0) { - break; - } - i--; - } - } - - if (status == FTDM_FAIL) { - status = get_best_rated(ftdmchan, best_rated); - } - - ftdm_mutex_unlock(group->mutex); - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_hunt_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) -{ - ftdm_status_t status; - status = _ftdm_channel_open_by_group(group_id, direction, caller_data, ftdmchan); - if (status == FTDM_SUCCESS) { - ftdm_channel_t *fchan = *ftdmchan; - ftdm_channel_unlock(fchan); - } - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_channel_use_count(ftdm_span_t *span, uint32_t *count) -{ - uint32_t j; - - *count = 0; - - if (!span || !ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) { - return FTDM_FAIL; - } - - for(j = 1; j <= span->chan_count && span->channels[j]; j++) { - if (span->channels[j]) { - if (ftdm_test_flag(span->channels[j], FTDM_CHANNEL_INUSE)) { - (*count)++; - } - } - } - - return FTDM_SUCCESS; -} - -/* Hunt a channel by span, if successful the channel is returned locked */ -static ftdm_status_t _ftdm_channel_open_by_span(uint32_t span_id, ftdm_hunt_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_channel_t *check = NULL; - ftdm_channel_t *best_rated = NULL; - ftdm_span_t *span = NULL; - int best_rate = 0; - uint32_t i = 0; - uint32_t count = 0; - uint32_t first_channel = 0; - - *ftdmchan = NULL; - - if (!span_id) { - ftdm_log(FTDM_LOG_CRIT, "No span supplied\n"); - return FTDM_FAIL; - } - - ftdm_span_find(span_id, &span); - - if (!span || !ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) { - ftdm_log(FTDM_LOG_CRIT, "span %d not defined or configured!\n", span_id); - return FTDM_FAIL; - } - - ftdm_span_channel_use_count(span, &count); - - if (count >= span->chan_count) { - ftdm_log(FTDM_LOG_WARNING, "All circuits are busy: active=%i max=%i.\n", count, span->chan_count); - return FTDM_FAIL; - } - - if (span->channel_request && !ftdm_test_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID)) { - ftdm_set_caller_data(span, caller_data); - return span->channel_request(span, 0, direction, caller_data, ftdmchan); - } - - ftdm_mutex_lock(span->mutex); - - if (direction == FTDM_HUNT_BOTTOM_UP) { - i = 1; - } else if (direction == FTDM_HUNT_RR_DOWN || direction == FTDM_HUNT_RR_UP) { - i = rr_next(span->last_used_index, 1, span->chan_count, direction); - first_channel = i; - } else { - i = span->chan_count; - } - - for(;;) { - - if (direction == FTDM_HUNT_BOTTOM_UP) { - if (i > span->chan_count) { - break; - } - } else { - if (i == 0) { - break; - } - } - - if (!(check = span->channels[i])) { - status = FTDM_FAIL; - break; - } - - if (request_voice_channel(check, ftdmchan, caller_data, direction)) { - status = FTDM_SUCCESS; - if (direction == FTDM_HUNT_RR_UP || direction == FTDM_HUNT_RR_DOWN) { - span->last_used_index = i; - } - break; - } - - calculate_best_rate(check, &best_rated, &best_rate); - - if (direction == FTDM_HUNT_BOTTOM_UP) { - i++; - } else if (direction == FTDM_HUNT_RR_DOWN || direction == FTDM_HUNT_RR_UP) { - if (check == best_rated) { - span->last_used_index = i; - } - i = rr_next(i, 1, span->chan_count, direction); - if (first_channel == i) { - break; - } - } else { - i--; - } - } - - if (status == FTDM_FAIL) { - status = get_best_rated(ftdmchan, best_rated); - } - - ftdm_mutex_unlock(span->mutex); - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_hunt_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) -{ - ftdm_status_t status; - status = _ftdm_channel_open_by_span(span_id, direction, caller_data, ftdmchan); - if (status == FTDM_SUCCESS) { - ftdm_channel_t *fchan = *ftdmchan; - ftdm_channel_unlock(fchan); - } - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan) -{ - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "invalid ftdmchan pointer\n"); - - ftdm_mutex_lock(ftdmchan->mutex); - - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is suspended\n"); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is suspended\n"); - goto done; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) && !ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n"); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is alarmed\n"); - goto done; - } - - if (globals.cpu_monitor.alarm && - globals.cpu_monitor.alarm_action_flags & FTDM_CPU_ALARM_ACTION_REJECT) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "CPU usage alarm is on - refusing to open channel\n"); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "CPU usage alarm is on - refusing to open channel\n"); - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_SWITCH_CONGESTION; - goto done; - } - } - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY)) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Channel is not ready"); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is not ready\n"); - goto done; - } - - status = ftdmchan->fio->open(ftdmchan); - if (status == FTDM_SUCCESS) { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OPEN | FTDM_CHANNEL_INUSE); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "IO open failed: %d\n", status); - } - -done: - - ftdm_mutex_unlock(ftdmchan->mutex); - - return status; -} - -static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan, uint8_t physical) -{ - ftdm_channel_t *check = NULL; - ftdm_span_t *span = NULL; - ftdm_channel_t *best_rated = NULL; - ftdm_status_t status = FTDM_FAIL; - int best_rate = 0; - - *ftdmchan = NULL; - - ftdm_mutex_lock(globals.mutex); - - ftdm_span_find(span_id, &span); - - if (!span) { - ftdm_log(FTDM_LOG_CRIT, "Could not find span!\n"); - goto done; - } - - if (!ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) { - ftdm_log(FTDM_LOG_CRIT, "Span %d is not configured\n", span_id); - goto done; - } - - if (span->channel_request) { - ftdm_log(FTDM_LOG_ERROR, "Individual channel selection not implemented on this span.\n"); - goto done; - } - - if (physical) { /* Open by physical */ - ftdm_channel_t *fchan = NULL; - ftdm_iterator_t *citer = NULL; - ftdm_iterator_t *curr = NULL; - - if (chan_id < 1) { - ftdm_log(FTDM_LOG_ERROR, "Invalid physical channel %d to open in span %d\n", chan_id, span_id); - status = FTDM_FAIL; - goto done; - } - - citer = ftdm_span_get_chan_iterator(span, NULL); - if (!citer) { - status = ENOMEM; - goto done; - } - - for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) { - fchan = ftdm_iterator_current(curr); - if (fchan->physical_chan_id == chan_id) { - check = fchan; - break; - } - } - - ftdm_iterator_free(citer); - if (!check) { - ftdm_log(FTDM_LOG_CRIT, "Wow, no physical channel %d in span %d\n", chan_id, span_id); - goto done; - } - } else { /* Open by logical */ - if (chan_id < 1 || chan_id > span->chan_count) { - ftdm_log(FTDM_LOG_ERROR, "Invalid channel %d to open in span %d\n", chan_id, span_id); - goto done; - } - - if (!(check = span->channels[chan_id])) { - ftdm_log(FTDM_LOG_CRIT, "Wow, no channel %d in span %d\n", chan_id, span_id); - goto done; - } - } - - ftdm_channel_lock(check); - - if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { - /* let them know is already open, but return the channel anyway */ - status = FTDM_EBUSY; - *ftdmchan = check; - goto unlockchan; - } - - /* The following if's and gotos replace a big if (this || this || this || this) else { nothing; } */ - - /* if it is not a voice channel, nothing else to check to open it */ - if (!FTDM_IS_VOICE_CHANNEL(check)) { - goto openchan; - } - - /* if it's an FXS device with a call active and has callwaiting enabled, we allow to open it twice */ - if (check->type == FTDM_CHAN_TYPE_FXS - && check->token_count == 1 - && ftdm_channel_test_feature(check, FTDM_CHANNEL_FEATURE_CALLWAITING)) { - goto openchan; - } - - /* if channel is available, time to open it */ - if (chan_is_avail(check)) { - goto openchan; - } - - /* not available, but still might be available ... */ - calculate_best_rate(check, &best_rated, &best_rate); - if (best_rated) { - goto openchan; - } - - /* channel is unavailable, do not open the channel */ - goto unlockchan; - -openchan: - if (!ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { - status = check->fio->open(check); - if (status == FTDM_SUCCESS) { - ftdm_set_flag(check, FTDM_CHANNEL_OPEN); - } - } else { - status = FTDM_SUCCESS; - } - ftdm_set_flag(check, FTDM_CHANNEL_INUSE); - ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND); - *ftdmchan = check; - - /* we've got the channel, do not unlock it */ - goto done; - -unlockchan: - ftdm_channel_unlock(check); - -done: - ftdm_mutex_unlock(globals.mutex); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open channel %d:%d\n", span_id, chan_id); - } - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) -{ - ftdm_status_t status; - status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 0); - if (status == FTDM_SUCCESS) { - ftdm_channel_t *fchan = *ftdmchan; - ftdm_channel_unlock(fchan); - } - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) -{ - ftdm_status_t status; - status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 1); - if (status == FTDM_SUCCESS) { - ftdm_channel_t *fchan = *ftdmchan; - ftdm_channel_unlock(fchan); - } - return status; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_id(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->chan_id; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_ph_id(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->physical_chan_id; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_span_id(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->span_id; -} - -FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->span; -} - -FT_DECLARE(const char *) ftdm_channel_get_span_name(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->span->name; -} - -FT_DECLARE(void) ftdm_span_set_trunk_type(ftdm_span_t *span, ftdm_trunk_type_t type) -{ - span->trunk_type = type; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_set_blocking_mode(const ftdm_span_t *span, ftdm_bool_t enabled) -{ - ftdm_channel_t *fchan = NULL; - ftdm_iterator_t *citer = NULL; - ftdm_iterator_t *curr = NULL; - - citer = ftdm_span_get_chan_iterator(span, NULL); - if (!citer) { - return FTDM_ENOMEM; - } - - for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) { - fchan = ftdm_iterator_current(curr); - if (enabled) { - ftdm_clear_flag_locked(fchan, FTDM_CHANNEL_NONBLOCK); - } else { - ftdm_set_flag_locked(fchan, FTDM_CHANNEL_NONBLOCK); - } - } - ftdm_iterator_free(citer); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_trunk_type_t) ftdm_span_get_trunk_type(const ftdm_span_t *span) -{ - return span->trunk_type; -} - -FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span) -{ - return ftdm_trunk_type2str(span->trunk_type); -} - -FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode) -{ - span->trunk_mode = mode; -} - -FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span) -{ - return span->trunk_mode; -} - -FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span) -{ - return ftdm_trunk_mode2str(span->trunk_mode); -} - -FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span) -{ - return span->span_id; -} - -FT_DECLARE(const char *) ftdm_span_get_name(const ftdm_span_t *span) -{ - return span->name; -} - -FT_DECLARE(const char *) ftdm_channel_get_name(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->chan_name; -} - -FT_DECLARE(const char *) ftdm_channel_get_number(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->chan_number; -} - -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_hold(const ftdm_channel_t *ftdmchan) -{ - ftdm_bool_t condition; - ftdm_channel_lock(ftdmchan); - condition = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD) ? FTDM_TRUE : FTDM_FALSE; - ftdm_channel_unlock(ftdmchan); - return condition; -} - -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_answered(const ftdm_channel_t *ftdmchan) -{ - ftdm_bool_t condition = FTDM_FALSE; - - ftdm_channel_lock(ftdmchan); - condition = (ftdmchan->state == FTDM_CHANNEL_STATE_UP) ? FTDM_TRUE : FTDM_FALSE; - ftdm_channel_unlock(ftdmchan); - - return condition; -} - -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_busy(const ftdm_channel_t *ftdmchan) -{ - ftdm_bool_t condition = FTDM_FALSE; - - ftdm_channel_lock(ftdmchan); - condition = (ftdmchan->state == FTDM_CHANNEL_STATE_BUSY) ? FTDM_TRUE : FTDM_FALSE; - ftdm_channel_unlock(ftdmchan); - - return condition; -} - -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_hangup(const ftdm_channel_t *ftdmchan) -{ - ftdm_bool_t condition = FTDM_FALSE; - - ftdm_channel_lock(ftdmchan); - condition = (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) - ? FTDM_TRUE : FTDM_FALSE; - ftdm_channel_unlock(ftdmchan); - - return condition; -} - -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_done(const ftdm_channel_t *ftdmchan) -{ - ftdm_bool_t condition = FTDM_FALSE; - - ftdm_channel_lock(ftdmchan); - condition = (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) ? FTDM_TRUE : FTDM_FALSE; - ftdm_channel_unlock(ftdmchan); - - return condition; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status; - ftdm_channel_lock(ftdmchan); - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_HOLD); - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALTONE, 0, usrmsg); - ftdm_channel_unlock(ftdmchan); - - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status; - - ftdm_channel_lock(ftdmchan); - - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 0, usrmsg); - - ftdm_channel_unlock(ftdmchan); - - return status; -} - -FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *fchan, ftdm_channel_indication_t indication, ftdm_status_t status) -{ - ftdm_sigmsg_t msg; - - if (!ftdm_test_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING)) { - return; - } - - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Acknowledging indication %s in state %s (rc = %d)\n", - ftdm_channel_indication2str(indication), ftdm_channel_state2str(fchan->state), status); - ftdm_clear_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING); - memset(&msg, 0, sizeof(msg)); - msg.channel = fchan; - msg.event_id = FTDM_SIGEVENT_INDICATION_COMPLETED; - msg.ev_data.indication_completed.indication = indication; - msg.ev_data.indication_completed.status = status; - ftdm_span_send_signal(fchan->span, &msg); -} - -/*! Answer call without locking the channel. The caller must have locked first */ -static ftdm_status_t _ftdm_channel_call_answer_nl(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status = FTDM_SUCCESS; - - if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) { - /* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn - * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so - * use FTDM_SPAN_USE_SKIP_STATES for now while we update the sig modules */ - - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1, usrmsg); - if (status != FTDM_SUCCESS) { - status = FTDM_ECANCELED; - goto done; - } - } - - /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n"); - status = FTDM_ECANCELED; - goto done; - } - - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1, usrmsg); - if (status != FTDM_SUCCESS) { - status = FTDM_ECANCELED; - goto done; - } - } - - /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n"); - status = FTDM_ECANCELED; - goto done; - } - } - - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1, usrmsg); - if (status != FTDM_SUCCESS) { - status = FTDM_ECANCELED; - goto done; - } - -done: - - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status; - - /* we leave the locking up to ftdm_channel_call_indicate, DO NOT lock here since ftdm_channel_call_indicate expects - * the lock recursivity to be 1 */ - status = _ftdm_channel_call_indicate(file, func, line, ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, usrmsg); - - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_transfer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, const char* arg, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status; - ftdm_usrmsg_t *msg = NULL; - ftdm_bool_t free_msg = FTDM_FALSE; - - if (!usrmsg) { - msg = ftdm_calloc(1, sizeof(*msg)); - ftdm_assert_return(msg, FTDM_FAIL, "Failed to allocate usr msg"); - memset(msg, 0, sizeof(*msg)); - free_msg = FTDM_TRUE; - } else { - msg = usrmsg; - } - - ftdm_usrmsg_add_var(msg, "transfer_arg", arg); - /* we leave the locking up to ftdm_channel_call_indicate, DO NOT lock here since ftdm_channel_call_indicate expects - * the lock recursivity to be 1 */ - status = _ftdm_channel_call_indicate(file, func, line, ftdmchan, FTDM_CHANNEL_INDICATE_TRANSFER, msg); - if (free_msg == FTDM_TRUE) { - ftdm_safe_free(msg); - } - return status; -} - -/* lock must be acquired by the caller! */ -static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *func, int line, ftdm_channel_t *chan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status = FTDM_SUCCESS; - - /* In native sigbridge mode we ignore hangup requests from the user and hangup only when the signaling module decides it */ - if (ftdm_test_flag(chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE) && chan->state != FTDM_CHANNEL_STATE_TERMINATING) { - - ftdm_log_chan_ex(chan, file, func, line, FTDM_LOG_LEVEL_DEBUG, - "Ignoring hangup in channel in state %s (native bridge enabled)\n", ftdm_channel_state2str(chan->state)); - ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP); - goto done; - } - - if (chan->state != FTDM_CHANNEL_STATE_DOWN) { - if (chan->state == FTDM_CHANNEL_STATE_HANGUP) { - /* make user's life easier, and just ignore double hangup requests */ - return FTDM_SUCCESS; - } - if (chan->hangup_timer) { - ftdm_sched_cancel_timer(globals.timingsched, chan->hangup_timer); - } - ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP); - /* if a state change requested by the user was pending, a hangup certainly cancels that request */ - if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_channel_cancel_state(file, func, line, chan); - } - status = ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1, usrmsg); - } else { - /* the signaling stack did not touch the state, - * core is responsible from clearing flags and stuff, however, because ftmod_analog - * is a bitch in a serious need of refactoring, we also check whether the channel is open - * to avoid an spurious warning about the channel not being open. This is because ftmod_analog - * does not follow our convention of sending SIGEVENT_STOP and waiting for the user to move - * to HANGUP (implicitly through ftdm_channel_call_hangup(), as soon as ftmod_analog is fixed - * this check can be removed */ - if (ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { - ftdm_channel_close(&chan); - } - } - -done: - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t cause, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status = FTDM_SUCCESS; - ftdm_channel_lock(ftdmchan); - - ftdmchan->caller_data.hangup_cause = cause; - - status = _ftdm_channel_call_hangup_nl(file, func, line, ftdmchan, usrmsg); - - ftdm_channel_unlock(ftdmchan); - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status = FTDM_SUCCESS; - - ftdm_channel_lock(ftdmchan); - - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; - - status = _ftdm_channel_call_hangup_nl(file, func, line, ftdmchan, usrmsg); - - ftdm_channel_unlock(ftdmchan); - return status; -} - -FT_DECLARE(const char *) ftdm_channel_get_last_error(const ftdm_channel_t *ftdmchan) -{ - return ftdmchan->last_error; -} - -FT_DECLARE(const char *) ftdm_span_get_last_error(const ftdm_span_t *span) -{ - return span->last_error; -} - -FT_DECLARE(ftdm_caller_data_t *) ftdm_channel_get_caller_data(ftdm_channel_t *ftdmchan) -{ - return &ftdmchan->caller_data; -} - -FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint32_t chanid) -{ - ftdm_channel_t *chan; - ftdm_mutex_lock(span->mutex); - if (chanid == 0 || chanid > span->chan_count) { - ftdm_mutex_unlock(span->mutex); - return NULL; - } - chan = span->channels[chanid]; - ftdm_mutex_unlock(span->mutex); - return chan; -} - -FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid) -{ - ftdm_channel_t *chan = NULL; - ftdm_channel_t *fchan = NULL; - ftdm_iterator_t *citer = NULL; - ftdm_iterator_t *curr = NULL; - - ftdm_mutex_lock(span->mutex); - if (chanid == 0) { - ftdm_mutex_unlock(span->mutex); - return NULL; - } - - citer = ftdm_span_get_chan_iterator(span, NULL); - if (!citer) { - ftdm_mutex_unlock(span->mutex); - return NULL; - } - - for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) { - fchan = ftdm_iterator_current(curr); - if (fchan->physical_chan_id == chanid) { - chan = fchan; - break; - } - } - - ftdm_iterator_free(citer); - - ftdm_mutex_unlock(span->mutex); - return chan; -} - -FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span) -{ - uint32_t count; - ftdm_mutex_lock(span->mutex); - count = span->chan_count; - ftdm_mutex_unlock(span->mutex); - return count; -} - -FT_DECLARE(uint32_t) ftdm_channel_get_ph_span_id(const ftdm_channel_t *ftdmchan) -{ - uint32_t id; - ftdm_channel_lock(ftdmchan); - id = ftdmchan->physical_span_id; - ftdm_channel_unlock(ftdmchan); - return id; -} - -/* - * Every user requested indication *MUST* be acknowledged with the proper status (ftdm_status_t) - * However, if the indication fails before we notify the signaling stack, we don't need to ack - * but if we already notified the signaling stack about the indication, the signaling stack is - * responsible for the acknowledge. Bottom line is, whenever this function returns FTDM_SUCCESS - * someone *MUST* acknowledge the indication, either the signaling stack, this function or the core - * at some later point - * */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status = FTDM_SUCCESS; - - ftdm_assert_return(ftdmchan, FTDM_FAIL, "Null channel\n"); - - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Indicating %s in state %s\n", - ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); - - ftdm_channel_lock(ftdmchan); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, - "Ignoring indication %s in channel in state %s (native bridge enabled)\n", - ftdm_channel_indication2str(indication), - ftdm_channel_state2str(ftdmchan->state)); - status = FTDM_SUCCESS; - goto done; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING)) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n", - ftdm_channel_indication2str(indication), - ftdm_channel_indication2str(ftdmchan->indication), - ftdm_channel_state2str(ftdmchan->state)); - status = FTDM_EBUSY; - goto done; - } - - ftdmchan->indication = indication; - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING); - } - - if (indication != FTDM_CHANNEL_INDICATE_FACILITY && - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in outgoing channel in state %s\n", - ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); - status = FTDM_EINVAL; - goto done; - } - - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Ignoring indication %s because the call is in %s state\n", - ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); - status = FTDM_ECANCELED; - goto done; - } - - switch (indication) { - /* FIXME: ring and busy cannot be used with all signaling stacks - * (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */ - case FTDM_CHANNEL_INDICATE_RINGING: - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RINGING, 1, usrmsg); - break; - case FTDM_CHANNEL_INDICATE_BUSY: - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1, usrmsg); - break; - case FTDM_CHANNEL_INDICATE_PROCEED: - if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE) || - ftdmchan->state >= FTDM_CHANNEL_STATE_PROCEED) { - ftdm_ack_indication(ftdmchan, indication, status); - goto done; - } - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROCEED, 1, usrmsg); - break; - case FTDM_CHANNEL_INDICATE_PROGRESS: - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1, usrmsg); - break; - case FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA: - if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) { - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1, usrmsg); - if (status != FTDM_SUCCESS) { - goto done; - } - } - - /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_ex_msg(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Ignoring progress media because the call is terminating\n"); - goto done; - } - } - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1, usrmsg); - break; - case FTDM_CHANNEL_INDICATE_ANSWER: - status = _ftdm_channel_call_answer_nl(file, func, line, ftdmchan, usrmsg); - break; - case FTDM_CHANNEL_INDICATE_TRANSFER: - if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_TRANSFER)) { - ftdm_log_chan_ex_msg(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Transfer not supported\n"); - status = FTDM_EINVAL; - goto done; - } - status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_TRANSFER, 1, usrmsg); - break; - default: - /* See if signalling module can provide this indication */ - status = ftdm_channel_sig_indicate(ftdmchan, indication, usrmsg); - break; - } - -done: - ftdm_channel_unlock(ftdmchan); - - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); - - ftdm_channel_lock(ftdmchan); - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 1, usrmsg); - ftdm_channel_unlock(ftdmchan); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel) -{ - ftdm_status_t status = FTDM_SUCCESS; - int rc = 0; - ftdm_span_t *span = NULL; - ftdm_channel_t *ftdmchan = NULL; - unsigned span_id = 0; - unsigned chan_id = 0; - - *out_span = NULL; - *out_channel = NULL; - - if (!string_id) { - ftdm_log(FTDM_LOG_ERROR, "Cannot parse NULL channel id string\n"); - status = FTDM_EINVAL; - goto done; - } - - rc = sscanf(string_id, "%u:%u", &span_id, &chan_id); - if (rc != 2) { - ftdm_log(FTDM_LOG_ERROR, "Failed to parse channel id string '%s'\n", string_id); - status = FTDM_EINVAL; - goto done; - } - - status = ftdm_span_find(span_id, &span); - if (status != FTDM_SUCCESS || !span) { - ftdm_log(FTDM_LOG_ERROR, "Failed to find span for channel id string '%s'\n", string_id); - status = FTDM_EINVAL; - goto done; - } - - if (chan_id > (FTDM_MAX_CHANNELS_SPAN+1) || !(ftdmchan = span->channels[chan_id])) { - ftdm_log(FTDM_LOG_ERROR, "Invalid channel id string '%s'\n", string_id); - status = FTDM_EINVAL; - goto done; - } - - status = FTDM_SUCCESS; - *out_span = span; - *out_channel = ftdmchan; -done: - return status; -} - -/* this function MUST be called with the channel lock held with lock recursivity of 1 exactly, - * and the caller must be aware we might unlock the channel for a brief period of time and then lock it again */ -static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - const char *var = NULL; - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); - ftdm_assert_return(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), FTDM_FAIL, "Call place, but outbound flag not set\n"); - - if (!ftdmchan->span->outgoing_call) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "outgoing_call method not implemented in this span!\n"); - status = FTDM_ENOSYS; - goto done; - } - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot place call in channel that is not open!\n"); - goto done; - } - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot place call in non outbound channel in state %s!\n", ftdm_channel_state2str(ftdmchan->state)); - goto done; - } - - status = ftdmchan->span->outgoing_call(ftdmchan); - if (status == FTDM_BREAK) { - /* the signaling module detected glare on time */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Glare detected, you should hunt in another channel!\n"); - goto done; - } - - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to place call!\n"); - goto done; - } - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED); - ftdm_call_set_call_id(ftdmchan, &ftdmchan->caller_data); - var = ftdm_usrmsg_get_var(usrmsg, "sigbridge_peer"); - if (var) { - ftdm_span_t *peer_span = NULL; - ftdm_channel_t *peer_chan = NULL; - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE); - ftdm_get_channel_from_string(var, &peer_span, &peer_chan); - if (peer_chan) { - ftdm_set_flag(peer_chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE); - } - } - - /* if the signaling stack left the channel in state down on success, is expecting us to move to DIALING */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALING, 1, usrmsg); - } else { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALING, 0, usrmsg); - } - } else if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE) && - !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) { - - ftdm_channel_unlock(ftdmchan); - - ftdm_interrupt_wait(ftdmchan->state_completed_interrupt, 500); - - ftdm_channel_lock(ftdmchan); - } - -done: - ftdm_unused_arg(file); - ftdm_unused_arg(func); - ftdm_unused_arg(line); - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status; - ftdm_channel_lock(ftdmchan); - - /* be aware that _ftdm_channl_call_place_nl can unlock/lock the channel quickly if working in blocking mode */ - status = _ftdm_channel_call_place_nl(file, func, line, ftdmchan, usrmsg); - - ftdm_channel_unlock(ftdmchan); - return status; -} - -FT_DECLARE(ftdm_status_t) _ftdm_call_place(const char *file, const char *func, int line, - ftdm_caller_data_t *caller_data, ftdm_hunting_scheme_t *hunting, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status = FTDM_SUCCESS; - ftdm_channel_t *fchan = NULL; - - ftdm_assert_return(caller_data, FTDM_EINVAL, "Invalid caller data\n"); - ftdm_assert_return(hunting, FTDM_EINVAL, "Invalid hunting scheme\n"); - - if (hunting->mode == FTDM_HUNT_SPAN) { - status = _ftdm_channel_open_by_span(hunting->mode_data.span.span_id, - hunting->mode_data.span.direction, caller_data, &fchan); - } else if (hunting->mode == FTDM_HUNT_GROUP) { - status = _ftdm_channel_open_by_group(hunting->mode_data.group.group_id, - hunting->mode_data.group.direction, caller_data, &fchan); - } else if (hunting->mode == FTDM_HUNT_CHAN) { - status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan, 0); - } else { - ftdm_log(FTDM_LOG_ERROR, "Cannot make outbound call with invalid hunting mode %d\n", hunting->mode); - return FTDM_EINVAL; - } - - if (status != FTDM_SUCCESS) { - return FTDM_EBUSY; - } - - /* we have a locked channel and are not afraid of using it! */ - if (hunting->result_cb) { - status = hunting->result_cb(fchan, caller_data); - if (status != FTDM_SUCCESS) { - status = FTDM_ECANCELED; - goto done; - } - } - - ftdm_channel_set_caller_data(fchan, caller_data); - - /* be aware that _ftdm_channl_call_place_nl can unlock/lock the channel quickly if working in blocking mode */ - status = _ftdm_channel_call_place_nl(file, func, line, fchan, usrmsg); - if (status != FTDM_SUCCESS) { - _ftdm_channel_call_hangup_nl(file, func, line, fchan, usrmsg); - goto done; - } - - /* let the user know which channel was picked and which call id was generated */ - caller_data->fchan = fchan; - caller_data->call_id = fchan->caller_data.call_id; -done: - ftdm_channel_unlock(fchan); - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_set_sig_status(ftdm_channel_t *fchan, ftdm_signaling_status_t sigstatus) -{ - ftdm_status_t res; - - ftdm_assert_return(fchan != NULL, FTDM_FAIL, "Null channel\n"); - ftdm_assert_return(fchan->span != NULL, FTDM_FAIL, "Null span\n"); - ftdm_assert_return(fchan->span->set_channel_sig_status != NULL, FTDM_ENOSYS, "Not implemented\n"); - - ftdm_channel_lock(fchan); - - res = fchan->span->set_channel_sig_status(fchan, sigstatus); - - ftdm_channel_unlock(fchan); - - return res; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_get_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *sigstatus) -{ - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel\n"); - ftdm_assert_return(ftdmchan->span != NULL, FTDM_FAIL, "Null span\n"); - ftdm_assert_return(sigstatus != NULL, FTDM_FAIL, "Null sig status parameter\n"); - - if (ftdmchan->span->get_channel_sig_status) { - ftdm_status_t res; - ftdm_channel_lock(ftdmchan); - res = ftdmchan->span->get_channel_sig_status(ftdmchan, sigstatus); - ftdm_channel_unlock(ftdmchan); - return res; - } else { - /* don't log error here, it can be called just to test if its supported */ - return FTDM_NOTIMPL; - } -} - -FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signaling_status_t sigstatus) -{ - ftdm_assert_return(span != NULL, FTDM_FAIL, "Null span\n"); - - if (sigstatus == FTDM_SIG_STATE_DOWN) { - ftdm_log(FTDM_LOG_WARNING, "The user is not allowed to set the signaling status to DOWN, valid states are UP or SUSPENDED\n"); - return FTDM_FAIL; - } - - if (span->set_span_sig_status) { - return span->set_span_sig_status(span, sigstatus); - } else { - ftdm_log(FTDM_LOG_ERROR, "set_span_sig_status method not implemented!\n"); - return FTDM_FAIL; - } -} - -FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *sigstatus) -{ - ftdm_assert_return(span != NULL, FTDM_FAIL, "Null span\n"); - ftdm_assert_return(sigstatus != NULL, FTDM_FAIL, "Null sig status parameter\n"); - - if (span->get_span_sig_status) { - return span->get_span_sig_status(span, sigstatus); - } else { - return FTDM_FAIL; - } -} - -static ftdm_status_t ftdm_channel_sig_indicate(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_usrmsg_t *usrmsg) -{ - ftdm_status_t status = FTDM_FAIL; - if (ftdmchan->span->indicate) { - - ftdm_channel_save_usrmsg(ftdmchan, usrmsg); - - status = ftdmchan->span->indicate(ftdmchan, indication); - if (status == FTDM_NOTIMPL) { - ftdm_log(FTDM_LOG_WARNING, "Do not know how to indicate %s\n", ftdm_channel_indication2str(indication)); - } else if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_WARNING, "Failed to indicate %s\n", ftdm_channel_indication2str(indication)); - } else { /* SUCCESS */ - ftdm_ack_indication(ftdmchan, indication, FTDM_SUCCESS); - } - ftdm_usrmsg_free(&ftdmchan->usrmsg); - } else { - return FTDM_NOTIMPL; - } - return status; -} - - -/* this function must be called with the channel lock */ -static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) -{ - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n"); - - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_FLASH); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RINGING); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_PROGRESS_DETECT); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_3WAY); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_PROGRESS); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_MEDIA); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE); - ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); - ftdm_buffer_destroy(&ftdmchan->pre_buffer); - ftdmchan->pre_buffer_size = 0; - ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - - if (ftdmchan->hangup_timer) { - ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer); - } - - ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; - ftdmchan->state = FTDM_CHANNEL_STATE_DOWN; - ftdmchan->state_status = FTDM_STATE_STATUS_COMPLETED; - - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_DEBUG_DTMF, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); - - if (FTDM_IS_VOICE_CHANNEL(ftdmchan) && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED)) { - ftdm_sigmsg_t sigmsg; - memset(&sigmsg, 0, sizeof(sigmsg)); - sigmsg.span_id = ftdmchan->span_id; - sigmsg.chan_id = ftdmchan->chan_id; - sigmsg.channel = ftdmchan; - sigmsg.event_id = FTDM_SIGEVENT_RELEASED; - ftdm_span_send_signal(ftdmchan->span, &sigmsg); - ftdm_call_clear_call_id(&ftdmchan->caller_data); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED); - } - - if (ftdmchan->txdrops || ftdmchan->rxdrops) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", - ftdmchan->txdrops, ftdmchan->rxdrops); - } - - memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD); - - memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens)); - ftdmchan->token_count = 0; - - ftdm_channel_flush_dtmf(ftdmchan); - - if (ftdmchan->gen_dtmf_buffer) { - ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer); - } - - if (ftdmchan->dtmf_buffer) { - ftdm_buffer_zero(ftdmchan->dtmf_buffer); - } - - if (ftdmchan->digit_buffer) { - ftdm_buffer_zero(ftdmchan->digit_buffer); - } - - if (!ftdmchan->dtmf_on) { - ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON; - } - - if (!ftdmchan->dtmf_off) { - ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF; - } - - memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) { - ftdmchan->effective_codec = ftdmchan->native_codec; - ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE); - } - - if (ftdmchan->span->sig_release_guard_time_ms) { - ftdmchan->last_release_time = ftdm_current_time_in_ms(); - } - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_use(ftdm_channel_t *ftdmchan) -{ - - ftdm_assert(ftdmchan != NULL, "Null channel\n"); - - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INUSE); - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan) -{ - ftdm_channel_t *check; - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel double pointer provided!\n"); - ftdm_assert_return(*ftdmchan != NULL, FTDM_FAIL, "null channel pointer provided!\n"); - - check = *ftdmchan; - *ftdmchan = NULL; - - if (ftdm_test_flag(check, FTDM_CHANNEL_CONFIGURED)) { - ftdm_mutex_lock(check->mutex); - if (!ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { - ftdm_log_chan_msg(check, FTDM_LOG_WARNING, "Channel not opened, proceeding anyway\n"); - } - status = check->fio->close(check); - ftdm_assert(status == FTDM_SUCCESS, "Failed to close channel!\n"); - ftdm_channel_done(check); - *ftdmchan = NULL; - check->ring_count = 0; - ftdm_mutex_unlock(check->mutex); - } - - return status; -} - -static ftdm_status_t ftdmchan_activate_dtmf_buffer(ftdm_channel_t *ftdmchan) -{ - if (!ftdmchan->dtmf_buffer) { - if (ftdm_buffer_create(&ftdmchan->dtmf_buffer, 1024, 3192, 0) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to allocate DTMF Buffer!\n"); - return FTDM_FAIL; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Created DTMF buffer\n"); - } - } - - - if (!ftdmchan->tone_session.buffer) { - memset(&ftdmchan->tone_session, 0, sizeof(ftdmchan->tone_session)); - teletone_init_session(&ftdmchan->tone_session, 0, NULL, NULL); - } - - ftdmchan->tone_session.rate = ftdmchan->rate; - ftdmchan->tone_session.duration = ftdmchan->dtmf_on * (ftdmchan->tone_session.rate / 1000); - ftdmchan->tone_session.wait = ftdmchan->dtmf_off * (ftdmchan->tone_session.rate / 1000); - ftdmchan->tone_session.volume = -7; - - /* - ftdmchan->tone_session.debug = 1; - ftdmchan->tone_session.debug_stream = stdout; - */ - - return FTDM_SUCCESS; -} - -/* - * ftdmchan_activate_dtmf_buffer to initialize ftdmchan->dtmf_buffer should be called prior to - * calling ftdm_insert_dtmf_pause - */ -static ftdm_status_t ftdm_insert_dtmf_pause(ftdm_channel_t *ftdmchan, ftdm_size_t pausems) -{ - void *data = NULL; - ftdm_size_t datalen = pausems * sizeof(uint16_t); - - data = ftdm_malloc(datalen); - ftdm_assert(data, "Failed to allocate memory\n"); - - memset(data, FTDM_SILENCE_VALUE(ftdmchan), datalen); - - ftdm_buffer_write(ftdmchan->dtmf_buffer, data, datalen); - ftdm_safe_free(data); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_command_t command, void *obj) -{ - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n"); - ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No IO attached to channel\n"); - - ftdm_channel_lock(ftdmchan); - - switch (command) { - - case FTDM_COMMAND_ENABLE_CALLERID_DETECT: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_CALLERID)) { - if (ftdm_fsk_demod_init(&ftdmchan->fsk, ftdmchan->rate, ftdmchan->fsk_buf, sizeof(ftdmchan->fsk_buf)) != FTDM_SUCCESS) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - GOTO_STATUS(done, FTDM_FAIL); - } - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_DISABLE_CALLERID_DETECT: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_CALLERID)) { - ftdm_fsk_demod_destroy(&ftdmchan->fsk); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_TRACE_INPUT: - { - char *path = FTDM_COMMAND_OBJ_CHAR_P; - if (ftdmchan->fds[FTDM_READ_TRACE_INDEX] > 0) { - close(ftdmchan->fds[FTDM_READ_TRACE_INDEX]); - ftdmchan->fds[FTDM_READ_TRACE_INDEX] = -1; - } - if ((ftdmchan->fds[FTDM_READ_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC - | FTDM_O_BINARY, S_IRUSR | S_IWUSR)) > -1) { - ftdm_log(FTDM_LOG_DEBUG, "Tracing channel %u:%u input to [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, path); - GOTO_STATUS(done, FTDM_SUCCESS); - } - - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - GOTO_STATUS(done, FTDM_FAIL); - } - break; - case FTDM_COMMAND_TRACE_OUTPUT: - { - char *path = (char *) obj; - if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > 0) { - close(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX]); - ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = -1; - } - if ((ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC - | FTDM_O_BINARY, S_IRUSR | S_IWUSR)) > -1) { - ftdm_log(FTDM_LOG_DEBUG, "Tracing channel %u:%u output to [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, path); - GOTO_STATUS(done, FTDM_SUCCESS); - } - - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - GOTO_STATUS(done, FTDM_FAIL); - } - break; - case FTDM_COMMAND_TRACE_END_ALL: - { - if (ftdmchan->fds[FTDM_READ_TRACE_INDEX] > 0) { - close(ftdmchan->fds[FTDM_READ_TRACE_INDEX]); - ftdmchan->fds[FTDM_READ_TRACE_INDEX] = -1; - } - if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > 0) { - close(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX]); - ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = -1; - } - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Enable DTMF debugging */ - case FTDM_COMMAND_ENABLE_DEBUG_DTMF: - { - if (ftdmchan->dtmfdbg.enabled) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot enable debug DTMF again\n"); - GOTO_STATUS(done, FTDM_FAIL); - } - if (ftdmchan->rxdump.buffer) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot debug DTMF if Rx dumping is already enabled\n"); - GOTO_STATUS(done, FTDM_FAIL); - } - if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, FTDM_IO_DUMP_DEFAULT_BUFF_SIZE) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to enable rx dump for DTMF debugging\n"); - GOTO_STATUS(done, FTDM_FAIL); - } - ftdmchan->dtmfdbg.enabled = 1; - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled DTMF debugging\n"); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Disable DTMF debugging (if not disabled explicitly, it is disabled automatically when calls hangup) */ - case FTDM_COMMAND_DISABLE_DEBUG_DTMF: - { - if (!ftdmchan->dtmfdbg.enabled) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DTMF debug is already disabled\n"); - GOTO_STATUS(done, FTDM_SUCCESS); - } - if (disable_dtmf_debug(ftdmchan) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to disable DTMF debug\n"); - GOTO_STATUS(done, FTDM_FAIL); - } - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Start dumping all input to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ - case FTDM_COMMAND_ENABLE_INPUT_DUMP: - { - ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; - if (ftdmchan->rxdump.buffer) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Input dump is already enabled\n"); - GOTO_STATUS(done, FTDM_FAIL); - } - if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump of size %"FTDM_SIZE_FMT"\n", size); - GOTO_STATUS(done, FTDM_FAIL); - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %"FTDM_SIZE_FMT"\n", size); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Stop dumping all input to a circular buffer. */ - case FTDM_COMMAND_DISABLE_INPUT_DUMP: - { - if (!ftdmchan->rxdump.buffer) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable input dump\n"); - GOTO_STATUS(done, FTDM_SUCCESS); - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled input dump of size %"FTDM_SIZE_FMT"\n", - ftdmchan->rxdump.size); - stop_chan_io_dump(&ftdmchan->rxdump); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Start dumping all output to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ - case FTDM_COMMAND_ENABLE_OUTPUT_DUMP: - { - ftdm_size_t size = obj ? FTDM_COMMAND_OBJ_SIZE : FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; - if (ftdmchan->txdump.buffer) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Output dump is already enabled\n"); - GOTO_STATUS(done, FTDM_FAIL); - } - if (start_chan_io_dump(ftdmchan, &ftdmchan->txdump, size) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump of size %"FTDM_SIZE_FMT"\n", size); - GOTO_STATUS(done, FTDM_FAIL); - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %"FTDM_SIZE_FMT"\n", size); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Stop dumping all output to a circular buffer. */ - case FTDM_COMMAND_DISABLE_OUTPUT_DUMP: - { - if (!ftdmchan->txdump.buffer) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable output dump\n"); - GOTO_STATUS(done, FTDM_SUCCESS); - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled output dump of size %"FTDM_SIZE_FMT"\n", ftdmchan->rxdump.size); - stop_chan_io_dump(&ftdmchan->txdump); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Dump the current input circular buffer to the specified FILE* structure */ - case FTDM_COMMAND_DUMP_INPUT: - { - if (!obj) { - GOTO_STATUS(done, FTDM_FAIL); - } - if (!ftdmchan->rxdump.buffer) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped input to file %p, input dump is not enabled\n", obj); - GOTO_STATUS(done, FTDM_FAIL); - } - dump_chan_io_to_file(ftdmchan, &ftdmchan->rxdump, obj); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %"FTDM_SIZE_FMT" to file %p\n", ftdmchan->rxdump.size, obj); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - /*!< Dump the current output circular buffer to the specified FILE* structure */ - case FTDM_COMMAND_DUMP_OUTPUT: - { - if (!obj) { - GOTO_STATUS(done, FTDM_FAIL); - } - if (!ftdmchan->txdump.buffer) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped output to file %p, output dump is not enabled\n", obj); - GOTO_STATUS(done, FTDM_FAIL); - } - dump_chan_io_to_file(ftdmchan, &ftdmchan->txdump, obj); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %"FTDM_SIZE_FMT" to file %p\n", ftdmchan->txdump.size, obj); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - - case FTDM_COMMAND_SET_INTERVAL: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL)) { - ftdmchan->effective_interval = FTDM_COMMAND_OBJ_INT; - if (ftdmchan->effective_interval == ftdmchan->native_interval) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_BUFFER); - } else { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_BUFFER); - } - ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_GET_INTERVAL: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL)) { - FTDM_COMMAND_OBJ_INT = ftdmchan->effective_interval; - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_SET_CODEC: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_CODECS)) { - ftdmchan->effective_codec = FTDM_COMMAND_OBJ_INT; - - if (ftdmchan->effective_codec == ftdmchan->native_codec) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE); - } else { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE); - } - ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - - case FTDM_COMMAND_SET_NATIVE_CODEC: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_CODECS)) { - ftdmchan->effective_codec = ftdmchan->native_codec; - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE); - ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - - case FTDM_COMMAND_GET_CODEC: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_CODECS)) { - FTDM_COMMAND_OBJ_INT = ftdmchan->effective_codec; - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_GET_NATIVE_CODEC: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_CODECS)) { - FTDM_COMMAND_OBJ_INT = ftdmchan->native_codec; - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_ENABLE_PROGRESS_DETECT: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_PROGRESS)) { - /* if they don't have thier own, use ours */ - ftdm_channel_clear_detected_tones(ftdmchan); - ftdm_channel_clear_needed_tones(ftdmchan); - teletone_multi_tone_init(&ftdmchan->span->tone_finder[FTDM_TONEMAP_DIAL], &ftdmchan->span->tone_detect_map[FTDM_TONEMAP_DIAL]); - teletone_multi_tone_init(&ftdmchan->span->tone_finder[FTDM_TONEMAP_RING], &ftdmchan->span->tone_detect_map[FTDM_TONEMAP_RING]); - teletone_multi_tone_init(&ftdmchan->span->tone_finder[FTDM_TONEMAP_BUSY], &ftdmchan->span->tone_detect_map[FTDM_TONEMAP_BUSY]); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS_DETECT); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_DISABLE_PROGRESS_DETECT: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_PROGRESS)) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_PROGRESS_DETECT); - ftdm_channel_clear_detected_tones(ftdmchan); - ftdm_channel_clear_needed_tones(ftdmchan); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_ENABLE_DTMF_DETECT: - { - /* if they don't have thier own, use ours */ - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan)) { - teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled software DTMF detector\n"); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - } - break; - case FTDM_COMMAND_DISABLE_DTMF_DETECT: - { - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan)) { - teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n"); - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - } - break; - case FTDM_COMMAND_SET_PRE_BUFFER_SIZE: - { - int val = FTDM_COMMAND_OBJ_INT; - - if (val < 0) { - val = 0; - } - - ftdmchan->pre_buffer_size = val * 8; - - ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); - if (!ftdmchan->pre_buffer_size) { - ftdm_buffer_destroy(&ftdmchan->pre_buffer); - } else if (!ftdmchan->pre_buffer) { - ftdm_buffer_create(&ftdmchan->pre_buffer, 1024, ftdmchan->pre_buffer_size, 0); - } - ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - - GOTO_STATUS(done, FTDM_SUCCESS); - - } - break; - case FTDM_COMMAND_GET_DTMF_ON_PERIOD: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) { - FTDM_COMMAND_OBJ_INT = ftdmchan->dtmf_on; - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_GET_DTMF_OFF_PERIOD: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) { - FTDM_COMMAND_OBJ_INT = ftdmchan->dtmf_on; - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - case FTDM_COMMAND_SET_DTMF_ON_PERIOD: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) { - int val = FTDM_COMMAND_OBJ_INT; - if (val > 10 && val < 1000) { - ftdmchan->dtmf_on = val; - GOTO_STATUS(done, FTDM_SUCCESS); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "invalid value %d range 10-1000", val); - GOTO_STATUS(done, FTDM_FAIL); - } - } - } - break; - case FTDM_COMMAND_SET_DTMF_OFF_PERIOD: - { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) { - int val = FTDM_COMMAND_OBJ_INT; - if (val > 10 && val < 1000) { - ftdmchan->dtmf_off = val; - GOTO_STATUS(done, FTDM_SUCCESS); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "invalid value %d range 10-1000", val); - GOTO_STATUS(done, FTDM_FAIL); - } - } - } - break; - case FTDM_COMMAND_SEND_DTMF: - { - char *digits = FTDM_COMMAND_OBJ_CHAR_P; - if (ftdmchan->span->sig_send_dtmf) { - status = ftdmchan->span->sig_send_dtmf(ftdmchan, digits); - GOTO_STATUS(done, status); - } else if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) { - - if ((status = ftdmchan_activate_dtmf_buffer(ftdmchan)) != FTDM_SUCCESS) { - GOTO_STATUS(done, status); - } - - ftdm_buffer_write(ftdmchan->gen_dtmf_buffer, digits, strlen(digits)); - - GOTO_STATUS(done, FTDM_SUCCESS); - } - } - break; - - case FTDM_COMMAND_DISABLE_ECHOCANCEL: - { - ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); - ftdm_buffer_destroy(&ftdmchan->pre_buffer); - ftdmchan->pre_buffer_size = 0; - ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - } - break; - - case FTDM_COMMAND_SET_RX_GAIN: - { - if (!FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set rx gain in non-voice channel of type: %s\n", ftdm_chan_type2str(ftdmchan->type)); - GOTO_STATUS(done, FTDM_FAIL); - } - ftdmchan->rxgain = FTDM_COMMAND_OBJ_FLOAT; - reset_gain_table(ftdmchan->rxgain_table, ftdmchan->rxgain, ftdmchan->native_codec); - if (ftdmchan->rxgain == 0.0) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN); - } else { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN); - } - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - case FTDM_COMMAND_GET_RX_GAIN: - { - FTDM_COMMAND_OBJ_FLOAT = ftdmchan->rxgain; - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - case FTDM_COMMAND_SET_TX_GAIN: - { - if (!FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - ftdm_log(FTDM_LOG_ERROR, "Cannot set tx gain in non-voice channel of type: %s\n", ftdm_chan_type2str(ftdmchan->type)); - GOTO_STATUS(done, FTDM_FAIL); - } - ftdmchan->txgain = FTDM_COMMAND_OBJ_FLOAT; - reset_gain_table(ftdmchan->txgain_table, ftdmchan->txgain, ftdmchan->native_codec); - if (ftdmchan->txgain == 0.0) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USE_TX_GAIN); - } else { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_USE_TX_GAIN); - } - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - case FTDM_COMMAND_GET_TX_GAIN: - { - FTDM_COMMAND_OBJ_FLOAT = ftdmchan->txgain; - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - case FTDM_COMMAND_GET_IOSTATS: - { - if (!obj) { - GOTO_STATUS(done, FTDM_EINVAL); - } - memcpy(obj, &ftdmchan->iostats, sizeof(ftdmchan->iostats)); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - case FTDM_COMMAND_SWITCH_IOSTATS: - { - ftdm_bool_t enable = *(ftdm_bool_t *)obj; - if (enable) { - ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); - } else { - ftdm_channel_clear_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); - } - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - default: - break; - } - - if (!ftdmchan->fio->command) { - ftdm_log(FTDM_LOG_ERROR, "no command function defined by the I/O freetdm module!\n"); - GOTO_STATUS(done, FTDM_FAIL); - } - - status = ftdmchan->fio->command(ftdmchan, command, obj); - - if (status == FTDM_NOTIMPL) { - ftdm_log(FTDM_LOG_ERROR, "I/O backend does not support command %d!\n", command); - } - -done: - ftdm_channel_unlock(ftdmchan); - - return status; - -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_wait(ftdm_channel_t *ftdmchan, ftdm_wait_flag_t *flags, int32_t to) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel\n"); - ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "Null io interface\n"); - ftdm_assert_return(ftdmchan->fio->wait != NULL, FTDM_NOTIMPL, "wait method not implemented\n"); - - status = ftdmchan->fio->wait(ftdmchan, flags, to); - if (status == FTDM_TIMEOUT) { - /* make sure the flags are cleared on timeout */ - *flags = 0; - } - return status; -} - -/*******************************/ -FIO_CODEC_FUNCTION(fio_slin2ulaw) -{ - int16_t sln_buf[512] = {0}, *sln = sln_buf; - uint8_t *lp = data; - uint32_t i; - ftdm_size_t len = *datalen; - - if (max > len) { - max = len; - } - - memcpy(sln, data, max); - - for(i = 0; i < max; i++) { - *lp++ = linear_to_ulaw(*sln++); - } - - *datalen = max / 2; - - return FTDM_SUCCESS; - -} - - -FIO_CODEC_FUNCTION(fio_ulaw2slin) -{ - int16_t *sln = data; - uint8_t law[1024] = {0}, *lp = law; - uint32_t i; - ftdm_size_t len = *datalen; - - if (max > len) { - max = len; - } - - memcpy(law, data, max); - - for(i = 0; i < max; i++) { - *sln++ = ulaw_to_linear(*lp++); - } - - *datalen = max * 2; - - return FTDM_SUCCESS; -} - -FIO_CODEC_FUNCTION(fio_slin2alaw) -{ - int16_t sln_buf[512] = {0}, *sln = sln_buf; - uint8_t *lp = data; - uint32_t i; - ftdm_size_t len = *datalen; - - if (max > len) { - max = len; - } - - memcpy(sln, data, max); - - for(i = 0; i < max; i++) { - *lp++ = linear_to_alaw(*sln++); - } - - *datalen = max / 2; - - return FTDM_SUCCESS; - -} - - -FIO_CODEC_FUNCTION(fio_alaw2slin) -{ - int16_t *sln = data; - uint8_t law[1024] = {0}, *lp = law; - uint32_t i; - ftdm_size_t len = *datalen; - - if (max > len) { - max = len; - } - - memcpy(law, data, max); - - for(i = 0; i < max; i++) { - *sln++ = alaw_to_linear(*lp++); - } - - *datalen = max * 2; - - return FTDM_SUCCESS; -} - -FIO_CODEC_FUNCTION(fio_ulaw2alaw) -{ - ftdm_size_t len = *datalen; - uint32_t i; - uint8_t *lp = data; - - if (max > len) { - max = len; - } - - for(i = 0; i < max; i++) { - *lp = ulaw_to_alaw(*lp); - lp++; - } - - return FTDM_SUCCESS; -} - -FIO_CODEC_FUNCTION(fio_alaw2ulaw) -{ - ftdm_size_t len = *datalen; - uint32_t i; - uint8_t *lp = data; - - if (max > len) { - max = len; - } - - for(i = 0; i < max; i++) { - *lp = alaw_to_ulaw(*lp); - lp++; - } - - return FTDM_SUCCESS; -} - -/******************************/ - -FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan) -{ - uint32_t i; - - memset(ftdmchan->detected_tones, 0, sizeof(ftdmchan->detected_tones[0]) * FTDM_TONEMAP_INVALID); - - for (i = 1; i < FTDM_TONEMAP_INVALID; i++) { - ftdmchan->span->tone_finder[i].tone_count = 0; - } -} - -FT_DECLARE(void) ftdm_channel_clear_needed_tones(ftdm_channel_t *ftdmchan) -{ - memset(ftdmchan->needed_tones, 0, sizeof(ftdmchan->needed_tones[0]) * FTDM_TONEMAP_INVALID); -} - -FT_DECLARE(ftdm_size_t) ftdm_channel_dequeue_dtmf(ftdm_channel_t *ftdmchan, char *dtmf, ftdm_size_t len) -{ - ftdm_size_t bytes = 0; - - assert(ftdmchan != NULL); - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY)) { - return 0; - } - - if (ftdmchan->digit_buffer && ftdm_buffer_inuse(ftdmchan->digit_buffer)) { - ftdm_mutex_lock(ftdmchan->mutex); - if ((bytes = ftdm_buffer_read(ftdmchan->digit_buffer, dtmf, len)) > 0) { - *(dtmf + bytes) = '\0'; - } - ftdm_mutex_unlock(ftdmchan->mutex); - } - - return bytes; -} - -FT_DECLARE(void) ftdm_channel_flush_dtmf(ftdm_channel_t *ftdmchan) -{ - if (ftdmchan->digit_buffer && ftdm_buffer_inuse(ftdmchan->digit_buffer)) { - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_buffer_zero(ftdmchan->digit_buffer); - ftdm_mutex_unlock(ftdmchan->mutex); - } -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, const char *dtmf) -{ - ftdm_status_t status; - register ftdm_size_t len, inuse; - ftdm_size_t wr = 0; - const char *p; - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n"); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s (debug = %d)\n", dtmf, ftdmchan->dtmfdbg.enabled); - - if (ftdmchan->span->sig_queue_dtmf && (ftdmchan->span->sig_queue_dtmf(ftdmchan, dtmf) == FTDM_BREAK)) { - /* Signalling module wants to absorb this DTMF event */ - return FTDM_SUCCESS; - } - - if (!ftdmchan->dtmfdbg.enabled) { - goto skipdebug; - } - - if (!ftdmchan->dtmfdbg.file) { - struct tm currtime; - time_t currsec; - char dfile[1138]; - - currsec = time(NULL); - -#ifdef WIN32 - _tzset(); - _localtime64_s(&currtime, &currsec); -#else - localtime_r(&currsec, &currtime); -#endif - - if (ftdm_strlen_zero(globals.dtmfdebug_directory)) { - snprintf(dfile, sizeof(dfile), "dtmf-s%dc%d-20%d-%d-%d-%d%d%d.%s", - ftdmchan->span_id, ftdmchan->chan_id, - currtime.tm_year-100, currtime.tm_mon+1, currtime.tm_mday, - currtime.tm_hour, currtime.tm_min, currtime.tm_sec, ftdmchan->native_codec == FTDM_CODEC_ULAW ? "ulaw" : ftdmchan->native_codec == FTDM_CODEC_ALAW ? "alaw" : "sln"); - } else { - snprintf(dfile, sizeof(dfile), "%s/dtmf-s%dc%d-20%d-%d-%d-%d%d%d.%s", - globals.dtmfdebug_directory, - ftdmchan->span_id, ftdmchan->chan_id, - currtime.tm_year-100, currtime.tm_mon+1, currtime.tm_mday, - currtime.tm_hour, currtime.tm_min, currtime.tm_sec, ftdmchan->native_codec == FTDM_CODEC_ULAW ? "ulaw" : ftdmchan->native_codec == FTDM_CODEC_ALAW ? "alaw" : "sln"); - } - ftdmchan->dtmfdbg.file = fopen(dfile, "wb"); - if (!ftdmchan->dtmfdbg.file) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "failed to open debug dtmf file %s\n", dfile); - } else { - ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, ftdmchan->dtmfdbg.file); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped initial DTMF output to %s\n", dfile); - } - } else { - ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT; - } - -skipdebug: - - if (ftdmchan->pre_buffer) { - ftdm_buffer_zero(ftdmchan->pre_buffer); - } - - ftdm_mutex_lock(ftdmchan->mutex); - - inuse = ftdm_buffer_inuse(ftdmchan->digit_buffer); - len = strlen(dtmf); - - if (len + inuse > ftdm_buffer_len(ftdmchan->digit_buffer)) { - ftdm_buffer_toss(ftdmchan->digit_buffer, strlen(dtmf)); - } - - if (ftdmchan->span->dtmf_hangup_len) { - for (p = dtmf; ftdm_is_dtmf(*p); p++) { - memmove (ftdmchan->dtmf_hangup_buf, ftdmchan->dtmf_hangup_buf + 1, ftdmchan->span->dtmf_hangup_len - 1); - ftdmchan->dtmf_hangup_buf[ftdmchan->span->dtmf_hangup_len - 1] = *p; - if (!strcmp(ftdmchan->dtmf_hangup_buf, ftdmchan->span->dtmf_hangup)) { - ftdm_log(FTDM_LOG_DEBUG, "DTMF hangup detected.\n"); - - ftdm_channel_set_state(__FILE__, __FTDM_FUNC__, __LINE__, ftdmchan, FTDM_CHANNEL_STATE_HANGUP, 0, NULL); - break; - } - } - } - - p = dtmf; - while (wr < len && p) { - if (ftdm_is_dtmf(*p)) { - wr++; - } else { - break; - } - p++; - } - - status = ftdm_buffer_write(ftdmchan->digit_buffer, dtmf, wr) ? FTDM_SUCCESS : FTDM_FAIL; - ftdm_mutex_unlock(ftdmchan->mutex); - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_raw_write (ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen) -{ - int dlen = (int) *datalen; - - if (ftdm_test_io_flag(ftdmchan, FTDM_CHANNEL_IO_WRITE)) { - ftdm_clear_io_flag(ftdmchan, FTDM_CHANNEL_IO_WRITE); - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED)) { - ftdmchan->txdrops++; - if (ftdmchan->txdrops <= 10) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot write in channel with tx disabled\n"); - } - if (ftdmchan->txdrops == 10) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Too many tx drops, not printing anymore\n"); - } - return FTDM_FAIL; - } - if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > -1) { - if ((write(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX], data, dlen)) != dlen) { - ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %d bytes\n", dlen); - } - } - write_chan_io_dump(&ftdmchan->txdump, data, dlen); - return ftdmchan->fio->write(ftdmchan, data, datalen); -} - -FT_DECLARE(ftdm_status_t) ftdm_raw_read (ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen) -{ - ftdm_status_t status; - - if (ftdm_test_io_flag(ftdmchan, FTDM_CHANNEL_IO_READ)) { - ftdm_clear_io_flag(ftdmchan, FTDM_CHANNEL_IO_READ); - } - status = ftdmchan->fio->read(ftdmchan, data, datalen); - - if (status == FTDM_SUCCESS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN) - && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) { - ftdm_size_t i = 0; - unsigned char *rdata = data; - for (i = 0; i < *datalen; i++) { - rdata[i] = ftdmchan->rxgain_table[rdata[i]]; - } - } - - if (status == FTDM_SUCCESS && ftdmchan->fds[FTDM_READ_TRACE_INDEX] > -1) { - ftdm_size_t dlen = *datalen; - if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, (int)dlen) != dlen) { - ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %"FTDM_SIZE_FMT" bytes\n", dlen); - } - } - - if (status == FTDM_SUCCESS && ftdmchan->span->sig_read) { - ftdmchan->span->sig_read(ftdmchan, data, *datalen); - } - - if (status == FTDM_SUCCESS) { - ftdm_size_t dlen = *datalen; - ftdm_size_t rc = 0; - - write_chan_io_dump(&ftdmchan->rxdump, data, (int)dlen); - - /* if dtmf debug is enabled and initialized, write there too */ - if (ftdmchan->dtmfdbg.file) { - rc = fwrite(data, 1, dlen, ftdmchan->dtmfdbg.file); - if (rc != dlen) { - ftdm_log(FTDM_LOG_WARNING, "DTMF debugger wrote only %"FTDM_SIZE_FMT" out of %"FTDM_SIZE_FMT" bytes: %s\n", - rc, *datalen, strerror(errno)); - } - ftdmchan->dtmfdbg.closetimeout--; - if (!ftdmchan->dtmfdbg.closetimeout) { - close_dtmf_debug_file(ftdmchan); - } - } - } - return status; -} - -/* This function takes care of automatically generating DTMF or FSK tones when needed */ -static ftdm_status_t handle_tone_generation(ftdm_channel_t *ftdmchan) -{ - /* - * datalen: size in bytes of the chunk of data the user requested to read (this function - * is called from the ftdm_channel_read function) - * dblen: size currently in use in any of the tone generation buffers (data available in the buffer) - * gen_dtmf_buffer: buffer holding the raw ASCII digits that the user requested to generate - * dtmf_buffer: raw linear tone data generated by teletone to be written to the devices - * fsk_buffer: raw linear FSK modulated data for caller id - */ - ftdm_buffer_t *buffer = NULL; - ftdm_size_t dblen = 0; - int wrote = 0; - - if (ftdmchan->gen_dtmf_buffer && (dblen = ftdm_buffer_inuse(ftdmchan->gen_dtmf_buffer))) { - char digits[128] = ""; - char *cur; - int x = 0; - - if (dblen > sizeof(digits) - 1) { - dblen = sizeof(digits) - 1; - } - - if (ftdm_buffer_read(ftdmchan->gen_dtmf_buffer, digits, dblen) && !ftdm_strlen_zero_buf(digits)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generating DTMF [%s]\n", digits); - - cur = digits; - - for (; *cur; cur++) { - if (*cur == 'F') { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLASH, NULL); - } else if (*cur == 'w') { - ftdm_insert_dtmf_pause(ftdmchan, FTDM_HALF_DTMF_PAUSE); - } else if (*cur == 'W') { - ftdm_insert_dtmf_pause(ftdmchan, FTDM_FULL_DTMF_PAUSE); - } else { - if ((wrote = teletone_mux_tones(&ftdmchan->tone_session, &ftdmchan->tone_session.TONES[(int)*cur]))) { - ftdm_buffer_write(ftdmchan->dtmf_buffer, ftdmchan->tone_session.buffer, wrote * 2); - x++; - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Problem adding DTMF sequence [%s]\n", digits); - return FTDM_FAIL; - } - } - if (x) { - ftdmchan->skip_read_frames = (wrote / (ftdmchan->effective_interval * 8)) + 4; - } - } - } - } - - if (!ftdmchan->buffer_delay || --ftdmchan->buffer_delay == 0) { - /* time to pick a buffer, either the dtmf or fsk buffer */ - if (ftdmchan->dtmf_buffer && (dblen = ftdm_buffer_inuse(ftdmchan->dtmf_buffer))) { - buffer = ftdmchan->dtmf_buffer; - } else if (ftdmchan->fsk_buffer && (dblen = ftdm_buffer_inuse(ftdmchan->fsk_buffer))) { - buffer = ftdmchan->fsk_buffer; - } - } - - /* if we picked a buffer, time to read from it and write the linear data to the device */ - if (buffer) { - uint8_t auxbuf[1024]; - ftdm_size_t dlen = ftdmchan->packet_len; - ftdm_size_t len, br, max = sizeof(auxbuf); - - /* if the codec is not linear, then data is really twice as much cuz - tone generation is done in linear (we assume anything different than linear is G.711) */ - if (ftdmchan->native_codec != FTDM_CODEC_SLIN) { - dlen *= 2; - } - - /* we do not expect the user chunks to be bigger than auxbuf */ - ftdm_assert((dlen <= sizeof(auxbuf)), "Unexpected size for user data chunk size\n"); - - /* dblen is the size in use for dtmf_buffer or fsk_buffer, and dlen is the size - * of the io chunks to write, we pick the smaller one */ - len = dblen > dlen ? dlen : dblen; - - /* we can't read more than the size of our auxiliary buffer */ - ftdm_assert((len <= sizeof(auxbuf)), "Unexpected size to read into auxbuf\n"); - - br = ftdm_buffer_read(buffer, auxbuf, len); - - /* the amount read can't possibly be bigger than what we requested */ - ftdm_assert((br <= len), "Unexpected size read from tone generation buffer\n"); - - /* if we read less than the chunk size, we must fill in with silence the rest */ - if (br < dlen) { - memset(auxbuf + br, 0, dlen - br); - } - - /* finally we convert to the native format for the channel if necessary */ - if (ftdmchan->native_codec != FTDM_CODEC_SLIN) { - if (ftdmchan->native_codec == FTDM_CODEC_ULAW) { - fio_slin2ulaw(auxbuf, max, &dlen); - } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW) { - fio_slin2alaw(auxbuf, max, &dlen); - } - } - - /* write the tone to the channel */ - return ftdm_raw_write(ftdmchan, auxbuf, &dlen); - } - - return FTDM_SUCCESS; - -} - - -FT_DECLARE(void) ftdm_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t divisor) -{ - int16_t x; - uint32_t i; - int sum_rnd = 0; - int16_t rnd2 = (int16_t) ftdm_current_time_in_ms() * (int16_t) (intptr_t) data; - - assert(divisor); - - for (i = 0; i < samples; i++, sum_rnd = 0) { - for (x = 0; x < 6; x++) { - rnd2 = rnd2 * 31821U + 13849U; - sum_rnd += rnd2 ; - } - //switch_normalize_to_16bit(sum_rnd); - *data = (int16_t) ((int16_t) sum_rnd / (int) divisor); - - data++; - } -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen) -{ - fio_codec_t codec_func = NULL; - ftdm_size_t max = *datalen; - - handle_tone_generation(ftdmchan); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) { - goto done; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) { - if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - codec_func = fio_ulaw2slin; - } else if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_ALAW) { - codec_func = fio_ulaw2alaw; - } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - codec_func = fio_alaw2slin; - } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW && ftdmchan->effective_codec == FTDM_CODEC_ULAW) { - codec_func = fio_alaw2ulaw; - } - - if (codec_func) { - codec_func(data, max, datalen); - } else { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!"); - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "no codec function to perform transcoding from %d to %d\n", ftdmchan->native_codec, ftdmchan->effective_codec); - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT) || - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS_DETECT) || - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) { - - uint8_t sln_buf[1024] = {0}; - int16_t *sln; - ftdm_size_t slen = 0; - - if (ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - sln = data; - slen = *datalen / 2; - } else { - ftdm_size_t len = *datalen; - uint32_t i; - uint8_t *lp = data; - - slen = sizeof(sln_buf) / 2; - if (len > slen) { - len = slen; - } - - sln = (int16_t *) sln_buf; - for(i = 0; i < len; i++) { - if (ftdmchan->effective_codec == FTDM_CODEC_ULAW) { - *sln++ = ulaw_to_linear(*lp++); - } else if (ftdmchan->effective_codec == FTDM_CODEC_ALAW) { - *sln++ = alaw_to_linear(*lp++); - } else { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!"); - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "invalid effective codec %d\n", ftdmchan->effective_codec); - goto done; - } - } - sln = (int16_t *) sln_buf; - slen = len; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) { - if (ftdm_fsk_demod_feed(&ftdmchan->fsk, sln, slen) != FTDM_SUCCESS) { - ftdm_size_t type, mlen; - char str[128], *sp; - - while(ftdm_fsk_data_parse(&ftdmchan->fsk, &type, &sp, &mlen) == FTDM_SUCCESS) { - *(str+mlen) = '\0'; - ftdm_copy_string(str, sp, ++mlen); - ftdm_clean_string(str); - - ftdm_log(FTDM_LOG_DEBUG, "FSK: TYPE %s LEN %"FTDM_SIZE_FMT" VAL [%s]\n", - ftdm_mdmf_type2str(type), mlen-1, str); - - switch(type) { - case MDMF_DDN: - case MDMF_PHONE_NUM: - { - if (mlen > sizeof(ftdmchan->caller_data.ani)) { - mlen = sizeof(ftdmchan->caller_data.ani); - } - ftdm_set_string(ftdmchan->caller_data.ani.digits, str); - ftdm_set_string(ftdmchan->caller_data.cid_num.digits, ftdmchan->caller_data.ani.digits); - } - break; - case MDMF_NO_NUM: - { - ftdm_set_string(ftdmchan->caller_data.ani.digits, *str == 'P' ? "private" : "unknown"); - ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.ani.digits); - } - break; - case MDMF_PHONE_NAME: - { - if (mlen > sizeof(ftdmchan->caller_data.cid_name)) { - mlen = sizeof(ftdmchan->caller_data.cid_name); - } - ftdm_set_string(ftdmchan->caller_data.cid_name, str); - } - break; - case MDMF_NO_NAME: - { - ftdm_set_string(ftdmchan->caller_data.cid_name, *str == 'P' ? "private" : "unknown"); - } - case MDMF_DATETIME: - { - if (mlen > sizeof(ftdmchan->caller_data.cid_date)) { - mlen = sizeof(ftdmchan->caller_data.cid_date); - } - ftdm_set_string(ftdmchan->caller_data.cid_date, str); - } - break; - } - } - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_CALLERID_DETECT, NULL); - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_PROGRESS_DETECT) && !ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_PROGRESS)) { - uint32_t i; - - for (i = 1; i < FTDM_TONEMAP_INVALID; i++) { - if (ftdmchan->span->tone_finder[i].tone_count) { - if (ftdmchan->needed_tones[i] && teletone_multi_tone_detect(&ftdmchan->span->tone_finder[i], sln, (int)slen)) { - if (++ftdmchan->detected_tones[i]) { - ftdmchan->needed_tones[i] = 0; - ftdmchan->detected_tones[0]++; - } - } - } - } - } - - if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan) && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT)) { - teletone_hit_type_t hit; - char digit_char; - uint32_t dur; - - if ((hit = teletone_dtmf_detect(&ftdmchan->dtmf_detect, sln, (int)slen)) == TT_HIT_END) { - teletone_dtmf_get(&ftdmchan->dtmf_detect, &digit_char, &dur); - - if (ftdmchan->state == FTDM_CHANNEL_STATE_CALLWAITING && (digit_char == 'D' || digit_char == 'A')) { - ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++; - } else { - char digit_str[2] = { 0 }; - - digit_str[0] = digit_char; - - ftdm_channel_queue_dtmf(ftdmchan, digit_str); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF)) { - ftdmchan->skip_read_frames = 20; - } - } - } - } - } - - if (ftdmchan->skip_read_frames > 0 || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_MUTE)) { - - ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); - if (ftdmchan->pre_buffer && ftdm_buffer_inuse(ftdmchan->pre_buffer)) { - ftdm_buffer_zero(ftdmchan->pre_buffer); - } - ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - - memset(data, FTDM_SILENCE_VALUE(ftdmchan), *datalen); - - if (ftdmchan->skip_read_frames > 0) { - ftdmchan->skip_read_frames--; - } - } else { - ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); - if (ftdmchan->pre_buffer_size && ftdmchan->pre_buffer) { - ftdm_buffer_write(ftdmchan->pre_buffer, data, *datalen); - if (ftdm_buffer_inuse(ftdmchan->pre_buffer) >= ftdmchan->pre_buffer_size) { - ftdm_buffer_read(ftdmchan->pre_buffer, data, *datalen); - } else { - memset(data, FTDM_SILENCE_VALUE(ftdmchan), *datalen); - } - } - ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - } - -done: - return FTDM_SUCCESS; -} - - -FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen) -{ - - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "ftdmchan is null\n"); - ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No I/O module attached to ftdmchan\n"); - - ftdm_channel_lock(ftdmchan); - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot read from channel that is not open\n"); - status = FTDM_FAIL; - goto done; - } - - if (!ftdmchan->fio->read) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "read method not implemented\n"); - status = FTDM_FAIL; - goto done; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED)) { - ftdmchan->rxdrops++; - if (ftdmchan->rxdrops <= 10) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot read from channel with rx disabled\n"); - } - if (ftdmchan->rxdrops == 10) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "too many rx drops, not logging anymore\n"); - } - status = FTDM_FAIL; - goto done; - } - status = ftdm_raw_read(ftdmchan, data, datalen); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "raw I/O read filed\n"); - goto done; - } - - status = ftdm_channel_process_media(ftdmchan, data, datalen); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to process media\n"); - } -done: - ftdm_channel_unlock(ftdmchan); - return status; -} - - -FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t datasize, ftdm_size_t *datalen) -{ - ftdm_status_t status = FTDM_SUCCESS; - fio_codec_t codec_func = NULL; - ftdm_size_t max = datasize; - unsigned int i = 0; - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel on write!\n"); - ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "null I/O on write!\n"); - - ftdm_channel_lock(ftdmchan); - - if (!ftdmchan->buffer_delay && - ((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) || - (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer)))) { - /* generating some kind of tone at the moment (see handle_tone_generation), - * we ignore user data ... */ - goto done; - } - - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot write in channel not open\n"); - status = FTDM_FAIL; - goto done; - } - - if (!ftdmchan->fio->write) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "write method not implemented\n"); - status = FTDM_FAIL; - goto done; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) { - goto do_write; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) { - if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - codec_func = fio_slin2ulaw; - } else if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_ALAW) { - codec_func = fio_alaw2ulaw; - } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - codec_func = fio_slin2alaw; - } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW && ftdmchan->effective_codec == FTDM_CODEC_ULAW) { - codec_func = fio_ulaw2alaw; - } - - if (codec_func) { - status = codec_func(data, max, datalen); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Do not know how to handle transcoding from %d to %d\n", - ftdmchan->effective_codec, ftdmchan->native_codec); - status = FTDM_FAIL; - goto done; - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_TX_GAIN) - && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) { - unsigned char *wdata = data; - for (i = 0; i < *datalen; i++) { - wdata[i] = ftdmchan->txgain_table[wdata[i]]; - } - } - -do_write: - - if (ftdmchan->span->sig_write) { - status = ftdmchan->span->sig_write(ftdmchan, data, *datalen); - if (status == FTDM_BREAK) { - /* signaling module decided to drop user frame */ - status = FTDM_SUCCESS; - goto done; - } - } - - status = ftdm_raw_write(ftdmchan, data, datalen); - -done: - ftdm_channel_unlock(ftdmchan); - - return status; -} - -FT_DECLARE(ftdm_iterator_t *) ftdm_get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter) -{ - int allocated = 0; - if (iter) { - if (iter->type != type) { - ftdm_log(FTDM_LOG_ERROR, "Cannot switch iterator types\n"); - return NULL; - } - allocated = iter->allocated; - memset(iter, 0, sizeof(*iter)); - iter->type = type; - iter->allocated = allocated; - return iter; - } - - iter = ftdm_calloc(1, sizeof(*iter)); - if (!iter) { - return NULL; - } - iter->type = type; - iter->allocated = 1; - return iter; -} - -FT_DECLARE(ftdm_iterator_t *) ftdm_get_span_iterator(ftdm_iterator_t *iter) -{ - if (!(iter = ftdm_get_iterator(FTDM_ITERATOR_SPANS, iter))) { - return NULL; - } - - iter->pvt.hashiter = hashtable_first(globals.span_hash); - return iter; -} - -FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter) -{ - if (!span->chan_count) { - return NULL; - } - if (!(iter = ftdm_get_iterator(FTDM_ITERATOR_CHANS, iter))) { - return NULL; - } - iter->pvt.chaniter.index = 1; - iter->pvt.chaniter.span = span; - return iter; -} - -FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter) -{ - ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); - - switch (iter->type) { - case FTDM_ITERATOR_VARS: - case FTDM_ITERATOR_SPANS: - if (!iter->pvt.hashiter) { - return NULL; - } - iter->pvt.hashiter = hashtable_next(iter->pvt.hashiter); - if (!iter->pvt.hashiter) { - return NULL; - } - return iter; - case FTDM_ITERATOR_CHANS: - ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); - if (iter->pvt.chaniter.index == iter->pvt.chaniter.span->chan_count) { - return NULL; - } - iter->pvt.chaniter.index++; - return iter; - default: - break; - } - - ftdm_assert_return(0, NULL, "Unknown iterator type\n"); - return NULL; -} - -FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter) -{ - const void *key = NULL; - void *val = NULL; - - ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); - - switch (iter->type) { - case FTDM_ITERATOR_VARS: - hashtable_this(iter->pvt.hashiter, &key, NULL, &val); - /* I decided to return the key instead of the value since the value can be retrieved using the key */ - return (void *)key; - case FTDM_ITERATOR_SPANS: - hashtable_this(iter->pvt.hashiter, &key, NULL, &val); - return (void *)val; - case FTDM_ITERATOR_CHANS: - ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); - ftdm_assert_return(iter->pvt.chaniter.index <= iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n"); - return iter->pvt.chaniter.span->channels[iter->pvt.chaniter.index]; - default: - break; - } - - ftdm_assert_return(0, NULL, "Unknown iterator type\n"); - return NULL; -} - -FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter) -{ - /* it's valid to pass a NULL iterator, do not return failure */ - if (!iter) { - return FTDM_SUCCESS; - } - - if (!iter->allocated) { - memset(iter, 0, sizeof(*iter)); - return FTDM_SUCCESS; - } - - ftdm_assert_return(iter->type, FTDM_FAIL, "Cannot free invalid iterator\n"); - ftdm_safe_free(iter); - - return FTDM_SUCCESS; -} - - -static const char *print_neg_char[] = { "", "!" }; -static const char *print_flag_state[] = { "OFF", "ON" }; - -static void print_channels_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *inspan, uint32_t inchan_id, uint64_t flagval, int not, int *count) -{ - ftdm_bool_t neg = !!not; - const char *negind = print_neg_char[neg]; - const char *flagname; - uint64_t flag = ((uint64_t)1 << flagval); - int mycount = 0; - - flagname = ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"); - - ftdm_mutex_lock(globals.mutex); - - if (inspan) { - ftdm_iterator_t *c_iter, *c_cur; - - c_iter = ftdm_span_get_chan_iterator(inspan, NULL); - - for (c_cur = c_iter; c_cur; c_cur = ftdm_iterator_next(c_cur)) { - ftdm_channel_t *fchan; - ftdm_bool_t cond; - - fchan = ftdm_iterator_current(c_cur); - if (inchan_id && inchan_id != fchan->chan_id) { - continue; - } - - cond = !!ftdm_test_flag(fchan, flag); - if (neg ^ cond) { - mycount++; - } - - stream->write_function(stream, "[s%dc%d][%d:%d] flag %s%"FTDM_UINT64_FMT"(%s%s) %s\n", - fchan->span_id, fchan->chan_id, - fchan->physical_span_id, fchan->physical_chan_id, - negind, flagval, negind, flagname, - print_flag_state[cond]); - } - - ftdm_iterator_free(c_iter); - - } else { - ftdm_iterator_t *s_iter, *s_cur; - - s_iter = ftdm_get_span_iterator(NULL); - - for (s_cur = s_iter; s_cur; s_cur = ftdm_iterator_next(s_cur)) { - ftdm_iterator_t *c_iter, *c_cur; - ftdm_span_t *span; - - span = ftdm_iterator_current(s_cur); - if (!span) { - break; - } - - c_iter = ftdm_span_get_chan_iterator(span, NULL); - - for (c_cur = c_iter; c_cur; c_cur = ftdm_iterator_next(c_cur)) { - ftdm_channel_t *fchan; - - fchan = ftdm_iterator_current(c_cur); - - if (neg ^ !!ftdm_test_flag(fchan, flag)) { - stream->write_function(stream, "[s%dc%d][%d:%d] flag %s%"FTDM_UINT64_FMT"(%s%s)\n", - fchan->span_id, fchan->chan_id, - fchan->physical_span_id, fchan->physical_chan_id, - negind, flagval, negind, flagname); - mycount++; - } - } - - ftdm_iterator_free(c_iter); - } - - ftdm_iterator_free(s_iter); - } - - *count = mycount; - ftdm_mutex_unlock(globals.mutex); -} - -static void print_spans_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *inspan, uint64_t flagval, int not, int *count) -{ - ftdm_bool_t neg = !!not; - const char *negind = print_neg_char[neg]; - const char *flagname; - uint64_t flag = ((uint64_t)1 << flagval); - int mycount = 0; - - flagname = ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"); - - ftdm_mutex_lock(globals.mutex); - - if (inspan) { - ftdm_bool_t cond; - - cond = !!ftdm_test_flag(inspan, flag); - if (neg ^ cond) { - mycount++; - } - - stream->write_function(stream, "[s%d] flag %s%"FTDM_UINT64_FMT"(%s%s) %s\n", - inspan->span_id, negind, flagval, negind, flagname, - print_flag_state[cond]); - } else { - ftdm_iterator_t *s_iter, *s_cur; - - s_iter = ftdm_get_span_iterator(NULL); - - for (s_cur = s_iter; s_cur; s_cur = ftdm_iterator_next(s_cur)) { - ftdm_span_t *span; - - span = ftdm_iterator_current(s_cur); - if (!span) { - break; - } - - if (neg ^ !!ftdm_test_flag(span, flag)) { - stream->write_function(stream, "[s%d] flag %s%"FTDM_UINT64_FMT"(%s%s)\n", - span->span_id, negind, flagval, negind, flagname); - mycount++; - } - } - - ftdm_iterator_free(s_iter); - } - - *count = mycount; - ftdm_mutex_unlock(globals.mutex); -} - -static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count) -{ - ftdm_iterator_t *s_iter, *s_cur; - ftdm_bool_t neg = !!not; - int mycount = 0; - - s_iter = ftdm_get_span_iterator(NULL); - - ftdm_mutex_lock(globals.mutex); - - for (s_cur = s_iter; s_cur; s_cur = ftdm_iterator_next(s_cur)) { - ftdm_iterator_t *c_iter, *c_cur; - ftdm_span_t *span; - - span = ftdm_iterator_current(s_cur); - if (!span) { - break; - } - - c_iter = ftdm_span_get_chan_iterator(span, NULL); - - for (c_cur = c_iter ; c_cur; c_cur = ftdm_iterator_next(c_cur)) { - ftdm_channel_t *fchan = ftdm_iterator_current(c_cur); - - if (neg ^ (fchan->state == state)) { - stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n", - fchan->span_id, fchan->chan_id, - fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state)); - mycount++; - } - } - - ftdm_iterator_free(c_iter); - } - - *count = mycount; - ftdm_mutex_unlock(globals.mutex); - - ftdm_iterator_free(s_iter); -} - -static void print_core_usage(ftdm_stream_handle_t *stream) -{ - stream->write_function(stream, - "--------------------------------------------------------------------------------\n" - "ftdm core state [!] - List all channels in or not in the given state\n" - "ftdm core flag [!] [] [] - List all channels with the given flag value set\n" - "ftdm core spanflag [!] [] - List all spans with the given span flag value set\n" - "ftdm core calls - List all known calls to the FreeTDM core\n" - "--------------------------------------------------------------------------------\n"); -} - - -static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val) -{ - ftdm_size_t i; - for (i = 0; i < array_size; i++) { - if (!strcasecmp(val_str_table[i].str, str)) { - return val_str_table[i].val; - } - } - return default_val; -} - -static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str) -{ - ftdm_size_t i; - for (i = 0; i < array_size; i++) { - if (val_str_table[i].val == val) { - return val_str_table[i].str; - } - } - return default_str; -} - -static void print_channel_flag_values(ftdm_stream_handle_t *stream) -{ - int i; - for (i = 0; i < ftdm_array_len(channel_flag_strs); i++) { - stream->write_function(stream, "%s\n", channel_flag_strs[i].str); - } -} - -static void print_span_flag_values(ftdm_stream_handle_t *stream) -{ - int i; - for (i = 0; i < ftdm_array_len(span_flag_strs); i++) { - stream->write_function(stream, "%s\n", span_flag_strs[i].str); - } -} - -/** - * Compute log2 of 64bit integer v - * - * Bit Twiddling Hacks - * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog - */ -static int ftdm_log2_64(uint64_t v) -{ - unsigned int shift; - uint64_t r; - - r = (v > 0xFFFFFFFF) << 5; v >>= r; - shift = (v > 0xFFFF ) << 4; v >>= shift; r |= shift; - shift = (v > 0xFF ) << 3; v >>= shift; r |= shift; - shift = (v > 0xF ) << 2; v >>= shift; r |= shift; - shift = (v > 0x3 ) << 1; v >>= shift; r |= shift; - - return ((int)(r | (v >> 1))); -} - -static char *handle_core_command(const char *cmd) -{ - char *mycmd = NULL; - int argc = 0; - int count = 0; - int not = 0; - char *argv[10] = { 0 }; - char *flag = NULL; - uint64_t flagval = 0; - ftdm_channel_t *fchan = NULL; - ftdm_span_t *fspan = NULL; - ftdm_stream_handle_t stream = { 0 }; - - FTDM_STANDARD_STREAM(stream); - - if (!ftdm_strlen_zero(cmd)) { - mycmd = ftdm_strdup(cmd); - argc = ftdm_separate_string(mycmd, ' ', argv, ftdm_array_len(argv)); - } else { - print_core_usage(&stream); - goto done; - } - - if (!argc) { - print_core_usage(&stream); - goto done; - } - - if (!strcasecmp(argv[0], "state")) { - ftdm_channel_state_t st = FTDM_CHANNEL_STATE_INVALID; - char *state = NULL; - - if (argc < 2) { - stream.write_function(&stream, "core state command requires an argument\n"); - print_core_usage(&stream); - goto done; - } - - state = argv[1]; - if (state[0] == '!') { - not = 1; - state++; - } - - for (st = FTDM_CHANNEL_STATE_DOWN; st < FTDM_CHANNEL_STATE_INVALID; st++) { - if (!strcasecmp(state, ftdm_channel_state2str(st))) { - break; - } - } - if (st == FTDM_CHANNEL_STATE_INVALID) { - stream.write_function(&stream, "invalid state %s\n", state); - goto done; - } - print_channels_by_state(&stream, st, not, &count); - stream.write_function(&stream, "\nTotal channels %s state %s: %d\n", - not ? "not in" : "in", ftdm_channel_state2str(st), count); - } else if (!strcasecmp(argv[0], "flag")) { - uint32_t chan_id = 0; - - if (argc < 2) { - stream.write_function(&stream, "core flag command requires an argument\n"); - print_core_usage(&stream); - goto done; - } - - flag = argv[1]; - if (flag[0] == '!') { - not = 1; - flag++; - } - - if (isalpha(flag[0])) { - flagval = ftdm_str2val(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), FTDM_CHANNEL_MAX_FLAG); - if (flagval == FTDM_CHANNEL_MAX_FLAG) { - stream.write_function(&stream, "\nInvalid channel flag value. Possible channel flags:\n"); - print_channel_flag_values(&stream); - goto done; - } - flagval = ftdm_log2_64(flagval); - } else { - flagval = atoi(flag); - } - - /* Specific span specified */ - if (argv[2]) { - ftdm_span_find_by_name(argv[2], &fspan); - if (!fspan) { - stream.write_function(&stream, "-ERR span:%s not found\n", argv[2]); - goto done; - } - } - - /* Specific channel specified */ - if (argv[3]) { - chan_id = atoi(argv[3]); - if (chan_id == 0 || chan_id >= ftdm_span_get_chan_count(fspan)) { - stream.write_function(&stream, "-ERR invalid channel %u\n", chan_id); - goto done; - } - } - - print_channels_by_flag(&stream, fspan, chan_id, flagval, not, &count); - stream.write_function(&stream, "\nTotal channels %s flag %"FTDM_UINT64_FMT": %d\n", not ? "without" : "with", flagval, count); - } else if (!strcasecmp(argv[0], "spanflag")) { - if (argc < 2) { - stream.write_function(&stream, "core spanflag command requires an argument\n"); - print_core_usage(&stream); - goto done; - } - - flag = argv[1]; - if (flag[0] == '!') { - not = 1; - flag++; - } - - if (isalpha(flag[0])) { - flagval = ftdm_str2val(flag, span_flag_strs, ftdm_array_len(span_flag_strs), FTDM_SPAN_MAX_FLAG); - if (flagval == FTDM_SPAN_MAX_FLAG) { - stream.write_function(&stream, "\nInvalid span flag value. Possible span flags\n"); - print_span_flag_values(&stream); - goto done; - } - flagval = ftdm_log2_64(flagval); - } else { - flagval = atoi(flag); - } - - /* Specific span specified */ - if (argv[2]) { - ftdm_span_find_by_name(argv[2], &fspan); - if (!fspan) { - stream.write_function(&stream, "-ERR span:%s not found\n", argv[2]); - goto done; - } - } - - print_spans_by_flag(&stream, fspan, flagval, not, &count); - if (!fspan) { - stream.write_function(&stream, "\nTotal spans %s flag %"FTDM_UINT64_FMT": %d\n", not ? "without" : "with", flagval, count); - } - } else if (!strcasecmp(argv[0], "calls")) { - uint32_t current_call_id = 0; - - ftdm_mutex_lock(globals.call_id_mutex); - for (current_call_id = 0; current_call_id <= MAX_CALLIDS; current_call_id++) { - ftdm_caller_data_t *calldata = NULL; - - if (!globals.call_ids[current_call_id]) { - continue; - } - - calldata = globals.call_ids[current_call_id]; - fchan = calldata->fchan; - if (fchan) { - stream.write_function(&stream, "Call %u on channel %d:%d\n", current_call_id, - fchan->span_id, fchan->chan_id); - } else { - stream.write_function(&stream, "Call %u without a channel?\n", current_call_id); - } - count++; - } - ftdm_mutex_unlock(globals.call_id_mutex); - stream.write_function(&stream, "\nTotal calls: %d\n", count); - } else { - stream.write_function(&stream, "invalid core command %s\n", argv[0]); - print_core_usage(&stream); - } - -done: - ftdm_safe_free(mycmd); - - return stream.data; -} - -FT_DECLARE(char *) ftdm_api_execute(const char *cmd) -{ - ftdm_io_interface_t *fio = NULL; - char *dup = NULL, *p; - char *rval = NULL; - char *type = NULL; - - dup = ftdm_strdup(cmd); - if ((p = strchr(dup, ' '))) { - *p++ = '\0'; - cmd = p; - } else { - cmd = ""; - } - - type = dup; - - if (!strcasecmp(type, "core")) { - return handle_core_command(cmd); - } - - fio = ftdm_global_get_io_interface(type, FTDM_TRUE); - if (fio && fio->api) { - ftdm_stream_handle_t stream = { 0 }; - ftdm_status_t status; - FTDM_STANDARD_STREAM(stream); - - status = fio->api(&stream, cmd); - if (status != FTDM_SUCCESS) { - ftdm_safe_free(stream.data); - } else { - rval = (char *) stream.data; - } - } - - ftdm_safe_free(dup); - - return rval; -} - -static ftdm_status_t ftdm_set_channels_gains(ftdm_span_t *span, int currindex, float rxgain, float txgain) -{ - unsigned chan_index = 0; - - if (!span->chan_count) { - ftdm_log(FTDM_LOG_ERROR, "Failed to set channel gains because span %s has no channels\n", span->name); - return FTDM_FAIL; - } - - for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) { - if (!FTDM_IS_VOICE_CHANNEL(span->channels[chan_index])) { - continue; - } - if (ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_RX_GAIN, &rxgain) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - if (ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_TX_GAIN, &txgain) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_report_initial_channels_alarms(ftdm_span_t *span) -{ - ftdm_channel_t *fchan = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_alarm_flag_t alarmbits; - ftdm_event_t fake_event; - ftdm_iterator_t *citer = ftdm_span_get_chan_iterator(span, NULL); - - if (!citer) { - status = FTDM_ENOMEM; - goto done; - } - - memset(&fake_event, 0, sizeof(fake_event)); - fake_event.e_type = FTDM_EVENT_OOB; - - for (curr = citer; curr; curr = ftdm_iterator_next(curr)) { - fchan = ftdm_iterator_current(curr); - status = ftdm_channel_get_alarms(fchan, &alarmbits); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Failed to initialize alarms\n"); - continue; - } - fake_event.channel = fchan; - fake_event.enum_id = fchan->alarm_flags ? FTDM_OOB_ALARM_TRAP : FTDM_OOB_ALARM_CLEAR; - ftdm_event_handle_oob(&fake_event); - } - -done: - - ftdm_iterator_free(citer); - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const char* str, ftdm_channel_config_t *chan_config, unsigned *configured) -{ - int currindex; - unsigned chan_index = 0; - - ftdm_assert_return(span != NULL, FTDM_EINVAL, "span is null\n"); - ftdm_assert_return(chan_config != NULL, FTDM_EINVAL, "config is null\n"); - ftdm_assert_return(configured != NULL, FTDM_EINVAL, "configured pointer is null\n"); - ftdm_assert_return(span->fio != NULL, FTDM_EINVAL, "span with no I/O configured\n"); - ftdm_assert_return(span->fio->configure_span != NULL, FTDM_NOTIMPL, "span I/O with no channel configuration implemented\n"); - - currindex = span->chan_count; - *configured = 0; - *configured = span->fio->configure_span(span, str, chan_config->type, chan_config->name, chan_config->number); - if (!*configured) { - ftdm_log(FTDM_LOG_ERROR, "%d:Failed to configure span\n", span->span_id); - return FTDM_FAIL; - } - - if (chan_config->group_name[0]) { - if (ftdm_group_add_channels(span, currindex, chan_config->group_name) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%d:Failed to add channels to group %s\n", span->span_id, chan_config->group_name); - return FTDM_FAIL; - } - } - - if (ftdm_set_channels_gains(span, currindex, chan_config->rxgain, chan_config->txgain) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%d:Failed to set channel gains\n", span->span_id); - return FTDM_FAIL; - } - - for (chan_index = currindex + 1; chan_index <= span->chan_count; chan_index++) { - if (chan_config->iostats) { - ftdm_channel_set_feature(span->channels[chan_index], FTDM_CHANNEL_FEATURE_IO_STATS); - } - - if (!FTDM_IS_VOICE_CHANNEL(span->channels[chan_index])) { - continue; - } - - if (chan_config->debugdtmf) { - span->channels[chan_index]->dtmfdbg.requested = 1; - } - - span->channels[chan_index]->dtmfdetect.duration_ms = chan_config->dtmfdetect_ms; - if (chan_config->dtmf_on_start) { - span->channels[chan_index]->dtmfdetect.trigger_on_start = 1; - } - if (chan_config->dtmf_time_on) { - ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_DTMF_ON_PERIOD, &chan_config->dtmf_time_on); - } - if (chan_config->dtmf_time_off) { - ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_DTMF_OFF_PERIOD, &chan_config->dtmf_time_off); - } - } - - return FTDM_SUCCESS; -} - - -static ftdm_status_t load_config(void) -{ - const char cfg_name[] = "freetdm.conf"; - ftdm_config_t cfg; - char *var, *val; - int catno = -1; - int intparam = 0; - ftdm_span_t *span = NULL; - unsigned configured = 0, d = 0; - ftdm_analog_start_type_t tmp; - ftdm_size_t len = 0; - ftdm_channel_config_t chan_config; - ftdm_status_t ret = FTDM_SUCCESS; - - memset(&chan_config, 0, sizeof(chan_config)); - sprintf(chan_config.group_name, "__default"); - - if (!ftdm_config_open_file(&cfg, cfg_name)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open configuration file %s\n", cfg_name); - return FTDM_FAIL; - } - - ftdm_log(FTDM_LOG_DEBUG, "Reading FreeTDM configuration file\n"); - - while (ftdm_config_next_pair(&cfg, &var, &val)) { - if (*cfg.category == '#') { - if (cfg.catno != catno) { - ftdm_log(FTDM_LOG_DEBUG, "Skipping %s\n", cfg.category); - catno = cfg.catno; - } - } else if (!strncasecmp(cfg.category, "span", 4)) { - if (cfg.catno != catno) { - char *type = cfg.category + 4; - char *name; - - if (*type == ' ') { - type++; - } - - ftdm_log(FTDM_LOG_DEBUG, "found config for span\n"); - catno = cfg.catno; - - if (ftdm_strlen_zero(type)) { - ftdm_log(FTDM_LOG_CRIT, "failure creating span, no type specified.\n"); - span = NULL; - continue; - } - - if ((name = strchr(type, ' '))) { - *name++ = '\0'; - } - - /* Verify if trunk_type was specified for previous span */ - if (span && span->trunk_type == FTDM_TRUNK_NONE) { - ftdm_log(FTDM_LOG_ERROR, "trunk_type not specified for span %d (%s)\n", span->span_id, span->name); - ret = FTDM_FAIL; - goto done; - } - - if (ftdm_span_create(type, name, &span) == FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_DEBUG, "created span %d (%s) of type %s\n", span->span_id, span->name, type); - d = 0; - /* it is confusing that parameters from one span affect others, so let's clear them */ - memset(&chan_config, 0, sizeof(chan_config)); - sprintf(chan_config.group_name, "__default"); - /* default to storing iostats */ - chan_config.iostats = FTDM_TRUE; - } else { - ftdm_log(FTDM_LOG_CRIT, "failure creating span of type %s\n", type); - span = NULL; - continue; - } - } - - if (!span) { - continue; - } - - ftdm_log(FTDM_LOG_DEBUG, "span %d [%s]=[%s]\n", span->span_id, var, val); - - if (!strcasecmp(var, "trunk_type")) { - ftdm_trunk_type_t trtype = ftdm_str2ftdm_trunk_type(val); - ftdm_span_set_trunk_type(span, trtype); - ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s'\n", ftdm_trunk_type2str(trtype)); - } else if (!strcasecmp(var, "trunk_mode")) { - ftdm_trunk_mode_t trmode = ftdm_str2ftdm_trunk_mode(val); - ftdm_span_set_trunk_mode(span, trmode); - ftdm_log(FTDM_LOG_DEBUG, "setting trunk mode to '%s'\n", ftdm_trunk_mode2str(trmode)); - } else if (!strcasecmp(var, "name")) { - if (!strcasecmp(val, "undef")) { - chan_config.name[0] = '\0'; - } else { - ftdm_copy_string(chan_config.name, val, FTDM_MAX_NAME_STR_SZ); - } - } else if (!strcasecmp(var, "number")) { - if (!strcasecmp(val, "undef")) { - chan_config.number[0] = '\0'; - } else { - ftdm_copy_string(chan_config.number, val, FTDM_MAX_NUMBER_STR_SZ); - } - } else if (!strcasecmp(var, "analog-start-type")) { - if (span->trunk_type == FTDM_TRUNK_FXS || span->trunk_type == FTDM_TRUNK_FXO || span->trunk_type == FTDM_TRUNK_EM) { - if ((tmp = ftdm_str2ftdm_analog_start_type(val)) != FTDM_ANALOG_START_NA) { - span->start_type = tmp; - ftdm_log(FTDM_LOG_DEBUG, "changing start type to '%s'\n", ftdm_analog_start_type2str(span->start_type)); - } - } else { - ftdm_log(FTDM_LOG_ERROR, "This option is only valid on analog trunks!\n"); - } - } else if (!strcasecmp(var, "fxo-channel")) { - if (span->trunk_type == FTDM_TRUNK_NONE) { - span->trunk_type = FTDM_TRUNK_FXO; - span->trunk_mode = FTDM_TRUNK_MODE_CPE; - ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type), - ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode)); - } - if (span->trunk_type == FTDM_TRUNK_FXO) { - unsigned chans_configured = 0; - chan_config.type = FTDM_CHAN_TYPE_FXO; - if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) { - configured += chans_configured; - } - } else { - ftdm_log(FTDM_LOG_WARNING, "Cannot add FXO channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type)); - } - } else if (!strcasecmp(var, "fxs-channel")) { - if (span->trunk_type == FTDM_TRUNK_NONE) { - span->trunk_type = FTDM_TRUNK_FXS; - span->trunk_mode = FTDM_TRUNK_MODE_NET; - ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type), - ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode)); - } - if (span->trunk_type == FTDM_TRUNK_FXS) { - unsigned chans_configured = 0; - chan_config.type = FTDM_CHAN_TYPE_FXS; - if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) { - configured += chans_configured; - } - } else { - ftdm_log(FTDM_LOG_WARNING, "Cannot add FXS channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type)); - } - } else if (!strcasecmp(var, "em-channel")) { - if (span->trunk_type == FTDM_TRUNK_NONE) { - span->trunk_type = FTDM_TRUNK_EM; - span->trunk_mode = FTDM_TRUNK_MODE_CPE; - ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type), - ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode)); - } - if (span->trunk_type == FTDM_TRUNK_EM) { - unsigned chans_configured = 0; - chan_config.type = FTDM_CHAN_TYPE_EM; - if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) { - configured += chans_configured; - } - } else { - ftdm_log(FTDM_LOG_WARNING, "Cannot add EM channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type)); - } - } else if (!strcasecmp(var, "b-channel")) { - if (span->trunk_type == FTDM_TRUNK_NONE) { - ftdm_log(FTDM_LOG_ERROR, "No trunk type specified in configuration file\n"); - break; - } - if (FTDM_SPAN_IS_DIGITAL(span)) { - unsigned chans_configured = 0; - chan_config.type = FTDM_CHAN_TYPE_B; - if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) { - configured += chans_configured; - } - } else { - ftdm_log(FTDM_LOG_WARNING, "Cannot add B channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type)); - } - } else if (!strcasecmp(var, "d-channel")) { - if (span->trunk_type == FTDM_TRUNK_NONE) { - ftdm_log(FTDM_LOG_ERROR, "No trunk type specified in configuration file\n"); - break; - } - if (FTDM_SPAN_IS_DIGITAL(span)) { - unsigned chans_configured = 0; - if (d) { - ftdm_log(FTDM_LOG_WARNING, "ignoring extra d-channel\n"); - continue; - } - if (!strncasecmp(val, "lapd:", 5)) { - chan_config.type = FTDM_CHAN_TYPE_DQ931; - val += 5; - } else { - chan_config.type = FTDM_CHAN_TYPE_DQ921; - } - if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) { - configured += chans_configured; - } - d++; - } else { - ftdm_log(FTDM_LOG_WARNING, "Cannot add D channels to a %s trunk!\n", ftdm_trunk_type2str(span->trunk_type)); - } - } else if (!strcasecmp(var, "cas-channel")) { - unsigned chans_configured = 0; - chan_config.type = FTDM_CHAN_TYPE_CAS; - if (ftdm_configure_span_channels(span, val, &chan_config, &chans_configured) == FTDM_SUCCESS) { - configured += chans_configured; - } - } else if (!strcasecmp(var, "dtmf_hangup")) { - span->dtmf_hangup = ftdm_strdup(val); - span->dtmf_hangup_len = strlen(val); - } else if (!strcasecmp(var, "txgain")) { - if (sscanf(val, "%f", &(chan_config.txgain)) != 1) { - ftdm_log(FTDM_LOG_ERROR, "invalid txgain: '%s'\n", val); - } - } else if (!strcasecmp(var, "rxgain")) { - if (sscanf(val, "%f", &(chan_config.rxgain)) != 1) { - ftdm_log(FTDM_LOG_ERROR, "invalid rxgain: '%s'\n", val); - } - } else if (!strcasecmp(var, "debugdtmf")) { - chan_config.debugdtmf = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Setting debugdtmf to '%s'\n", chan_config.debugdtmf ? "yes" : "no"); - } else if (!strncasecmp(var, "dtmfdetect_ms", sizeof("dtmfdetect_ms")-1)) { - if (chan_config.dtmf_on_start == FTDM_TRUE) { - chan_config.dtmf_on_start = FTDM_FALSE; - ftdm_log(FTDM_LOG_WARNING, "dtmf_on_start parameter disabled because dtmfdetect_ms specified\n"); - } - if (sscanf(val, "%d", &(chan_config.dtmfdetect_ms)) != 1) { - ftdm_log(FTDM_LOG_ERROR, "invalid dtmfdetect_ms: '%s'\n", val); - } - } else if (!strncasecmp(var, "dtmf_on_start", sizeof("dtmf_on_start")-1)) { - if (chan_config.dtmfdetect_ms) { - ftdm_log(FTDM_LOG_WARNING, "dtmf_on_start parameter ignored because dtmf_detect_ms specified\n"); - } else { - if (ftdm_true(val)) { - chan_config.dtmf_on_start = FTDM_TRUE; - } else { - chan_config.dtmf_on_start = FTDM_FALSE; - } - } - } else if (!strcasecmp(var, "dtmf_time_on")) { - if (sscanf(val, "%u", &(chan_config.dtmf_time_on)) != 1) { - ftdm_log(FTDM_LOG_ERROR, "invalid dtmf_time_on: '%s'\n", val); - } - } else if (!strcasecmp(var, "dtmf_time_off")) { - if (sscanf(val, "%u", &(chan_config.dtmf_time_off)) != 1) { - ftdm_log(FTDM_LOG_ERROR, "invalid dtmf_time_off: '%s'\n", val); - } - } else if (!strncasecmp(var, "iostats", sizeof("iostats")-1)) { - if (ftdm_true(val)) { - chan_config.iostats = FTDM_TRUE; - } else { - chan_config.iostats = FTDM_FALSE; - } - ftdm_log(FTDM_LOG_DEBUG, "Setting iostats to '%s'\n", chan_config.iostats ? "yes" : "no"); - } else if (!strcasecmp(var, "group")) { - len = strlen(val); - if (len >= FTDM_MAX_NAME_STR_SZ) { - len = FTDM_MAX_NAME_STR_SZ - 1; - ftdm_log(FTDM_LOG_WARNING, "Truncating group name %s to %"FTDM_SIZE_FMT" length\n", val, len); - } - memcpy(chan_config.group_name, val, len); - chan_config.group_name[len] = '\0'; - } else { - ftdm_log(FTDM_LOG_ERROR, "unknown span variable '%s'\n", var); - } - } else if (!strncasecmp(cfg.category, "general", 7)) { - if (!strncasecmp(var, "cpu_monitor", sizeof("cpu_monitor")-1)) { - if (!strncasecmp(val, "yes", 3)) { - globals.cpu_monitor.enabled = 1; - if (!globals.cpu_monitor.alarm_action_flags) { - globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_WARN; - } - } - } else if (!strncasecmp(var, "debugdtmf_directory", sizeof("debugdtmf_directory")-1)) { - ftdm_set_string(globals.dtmfdebug_directory, val); - ftdm_log(FTDM_LOG_DEBUG, "Debug DTMF directory set to '%s'\n", globals.dtmfdebug_directory); - } else if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) { - if (atoi(val) > 0) { - globals.cpu_monitor.interval = atoi(val); - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid cpu monitoring interval %s\n", val); - } - } else if (!strncasecmp(var, "cpu_set_alarm_threshold", sizeof("cpu_set_alarm_threshold")-1)) { - intparam = atoi(val); - if (intparam > 0 && intparam < 100) { - globals.cpu_monitor.set_alarm_threshold = (uint8_t)intparam; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm set threshold %s\n", val); - } - } else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1) || - !strncasecmp(var, "cpu_clear_alarm_threshold", sizeof("cpu_clear_alarm_threshold")-1)) { - intparam = atoi(val); - if (intparam > 0 && intparam < 100) { - globals.cpu_monitor.clear_alarm_threshold = (uint8_t)intparam; - if (globals.cpu_monitor.clear_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) { - globals.cpu_monitor.clear_alarm_threshold = globals.cpu_monitor.set_alarm_threshold - 10; - ftdm_log(FTDM_LOG_ERROR, "Cpu alarm clear threshold must be lower than set threshold, " - "setting clear threshold to %d\n", globals.cpu_monitor.clear_alarm_threshold); - } - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm reset threshold %s\n", val); - } - } else if (!strncasecmp(var, "cpu_alarm_action", sizeof("cpu_alarm_action")-1)) { - char* p = val; - do { - if (!strncasecmp(p, "reject", sizeof("reject")-1)) { - globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_REJECT; - } else if (!strncasecmp(p, "warn", sizeof("warn")-1)) { - globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_WARN; - } - p = strchr(p, ','); - if (p) { - while(*p++) if (*p != 0x20) break; - } - } while (p); - } - } else { - ftdm_log(FTDM_LOG_ERROR, "unknown param [%s] '%s' / '%s'\n", cfg.category, var, val); - } - } - - /* Verify is trunk_type was specified for the last span */ - if (span && span->trunk_type == FTDM_TRUNK_NONE) { - ftdm_log(FTDM_LOG_ERROR, "trunk_type not specified for span %d (%s)\n", span->span_id, span->name); - ret = FTDM_FAIL; - } - -done: - ftdm_config_close_file(&cfg); - - ftdm_log(FTDM_LOG_INFO, "Configured %u channel(s)\n", configured); - if (!configured) { - ret = FTDM_FAIL; - } - - return ret; -} - -static ftdm_status_t process_module_config(ftdm_io_interface_t *fio) -{ - ftdm_config_t cfg; - char *var, *val; - char filename[256] = ""; - - ftdm_assert_return(fio != NULL, FTDM_FAIL, "fio argument is null\n"); - - snprintf(filename, sizeof(filename), "%s.conf", fio->name); - - if (!fio->configure) { - ftdm_log(FTDM_LOG_DEBUG, "Module %s does not support configuration.\n", fio->name); - return FTDM_FAIL; - } - - if (!ftdm_config_open_file(&cfg, filename)) { - /* This is normal if the user did not provide a configuration for this module */ - ftdm_log(FTDM_LOG_DEBUG, "File %s is not available\n", filename); - return FTDM_FAIL; - } - - while (ftdm_config_next_pair(&cfg, &var, &val)) { - fio->configure(cfg.category, var, val, cfg.lineno); - } - - ftdm_config_close_file(&cfg); - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_global_add_io_interface(ftdm_io_interface_t *interface1) -{ - ftdm_status_t ret = FTDM_SUCCESS; - ftdm_mutex_lock(globals.mutex); - if (hashtable_search(globals.interface_hash, (void *)interface1->name)) { - ftdm_log(FTDM_LOG_ERROR, "Interface %s already loaded!\n", interface1->name); - } else { - hashtable_insert(globals.interface_hash, (void *)interface1->name, interface1, HASHTABLE_FLAG_NONE); - } - ftdm_mutex_unlock(globals.mutex); - return ret; -} - -FT_DECLARE(ftdm_io_interface_t *) ftdm_global_get_io_interface(const char *iotype, ftdm_bool_t autoload) -{ - ftdm_io_interface_t *fio = NULL; - - ftdm_mutex_lock(globals.mutex); - - fio = (ftdm_io_interface_t *) hashtable_search(globals.interface_hash, (void *)iotype); - if (!fio && autoload) { - ftdm_load_module_assume(iotype); - fio = (ftdm_io_interface_t *) hashtable_search(globals.interface_hash, (void *)iotype); - if (fio) { - ftdm_log(FTDM_LOG_INFO, "Auto-loaded I/O module '%s'\n", iotype); - } - } - - ftdm_mutex_unlock(globals.mutex); - return fio; -} - -FT_DECLARE(int) ftdm_load_module(const char *name) -{ - ftdm_dso_lib_t lib; - int count = 0; - ftdm_bool_t load_proceed = FTDM_TRUE; - char path[512] = ""; - char *err; - ftdm_module_t *mod; - - ftdm_build_dso_path(name, path, sizeof(path)); - - if (!(lib = ftdm_dso_open(path, &err))) { - ftdm_log(FTDM_LOG_ERROR, "Error loading %s [%s]\n", path, err); - ftdm_safe_free(err); - return 0; - } - - if (!(mod = (ftdm_module_t *) ftdm_dso_func_sym(lib, "ftdm_module", &err))) { - ftdm_log(FTDM_LOG_ERROR, "Error loading %s [%s]\n", path, err); - ftdm_safe_free(err); - return 0; - } - - if (mod->io_load) { - ftdm_io_interface_t *interface1 = NULL; /* name conflict w/windows here */ - - if (mod->io_load(&interface1) != FTDM_SUCCESS || !interface1 || !interface1->name) { - ftdm_log(FTDM_LOG_ERROR, "Error loading %s\n", path); - load_proceed = FTDM_FALSE; - } else { - ftdm_log(FTDM_LOG_INFO, "Loading IO from %s [%s]\n", path, interface1->name); - if (ftdm_global_add_io_interface(interface1) == FTDM_SUCCESS) { - process_module_config(interface1); - } - } - } - - if (mod->sig_load) { - if (mod->sig_load() != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error loading %s\n", path); - load_proceed = FTDM_FALSE; - } else { - ftdm_log(FTDM_LOG_INFO, "Loading SIG from %s\n", path); - } - } - - if (load_proceed) { - char *p; - mod->lib = lib; - ftdm_set_string(mod->path, path); - if (mod->name[0] == '\0') { - if (!(p = strrchr(path, *FTDM_PATH_SEPARATOR))) { - p = path; - } - ftdm_set_string(mod->name, p); - } - - ftdm_mutex_lock(globals.mutex); - if (hashtable_search(globals.module_hash, (void *)mod->name)) { - ftdm_log(FTDM_LOG_ERROR, "Module %s already loaded!\n", mod->name); - ftdm_dso_destroy(&lib); - } else { - hashtable_insert(globals.module_hash, (void *)mod->name, mod, HASHTABLE_FLAG_NONE); - count++; - } - ftdm_mutex_unlock(globals.mutex); - } else { - ftdm_log(FTDM_LOG_ERROR, "Errors during module load. Unloading %s\n", path); - ftdm_dso_destroy(&lib); - } - - return count; -} - -FT_DECLARE(int) ftdm_load_module_assume(const char *name) -{ - char buf[256] = ""; - - snprintf(buf, sizeof(buf), "ftmod_%s", name); - return ftdm_load_module(buf); -} - -FT_DECLARE(int) ftdm_load_modules(void) -{ - char cfg_name[] = "modules.conf"; - ftdm_config_t cfg; - char *var, *val; - int count = 0; - - if (!ftdm_config_open_file(&cfg, cfg_name)) { - return FTDM_FAIL; - } - - while (ftdm_config_next_pair(&cfg, &var, &val)) { - if (!strcasecmp(cfg.category, "modules")) { - if (!strcasecmp(var, "load")) { - count += ftdm_load_module(val); - } - } - } - - return count; -} - -FT_DECLARE(ftdm_status_t) ftdm_unload_modules(void) -{ - ftdm_hash_iterator_t *i = NULL; - ftdm_dso_lib_t lib = NULL; - char modpath[256] = { 0 }; - - /* stop signaling interfaces first as signaling depends on I/O and not the other way around */ - for (i = hashtable_first(globals.module_hash); i; i = hashtable_next(i)) { - const void *key = NULL; - void *val = NULL; - ftdm_module_t *mod = NULL; - - hashtable_this(i, &key, NULL, &val); - - if (!key || !val) { - continue; - } - - mod = (ftdm_module_t *) val; - - if (!mod->sig_unload) { - continue; - } - - ftdm_log(FTDM_LOG_INFO, "Unloading signaling interface %s\n", mod->name); - - if (mod->sig_unload() != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error unloading signaling interface %s\n", mod->name); - continue; - } - - ftdm_log(FTDM_LOG_INFO, "Unloaded signaling interface %s\n", mod->name); - } - - /* Now go ahead with I/O interfaces */ - for (i = hashtable_first(globals.module_hash); i; i = hashtable_next(i)) { - const void *key = NULL; - void *val = NULL; - ftdm_module_t *mod = NULL; - - hashtable_this(i, &key, NULL, &val); - - if (!key || !val) { - continue; - } - - mod = (ftdm_module_t *) val; - - if (!mod->io_unload) { - continue; - } - - ftdm_log(FTDM_LOG_INFO, "Unloading I/O interface %s\n", mod->name); - - if (mod->io_unload() != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error unloading I/O interface %s\n", mod->name); - continue; - } - - ftdm_log(FTDM_LOG_INFO, "Unloaded I/O interface %s\n", mod->name); - } - - /* Now unload the actual shared object/dll */ - for (i = hashtable_first(globals.module_hash); i; i = hashtable_next(i)) { - ftdm_module_t *mod = NULL; - const void *key = NULL; - void *val = NULL; - - hashtable_this(i, &key, NULL, &val); - - if (!key || !val) { - continue; - } - - mod = (ftdm_module_t *) val; - - lib = mod->lib; - snprintf(modpath, sizeof(modpath), "%s", mod->path); - ftdm_log(FTDM_LOG_INFO, "Unloading module %s\n", modpath); - ftdm_dso_destroy(&lib); - ftdm_log(FTDM_LOG_INFO, "Unloaded module %s\n", modpath); - } - - return FTDM_SUCCESS; -} - -static ftdm_status_t post_configure_span_channels(ftdm_span_t *span) -{ - unsigned i = 0; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; - for (i = 1; i <= span->chan_count; i++) { - sigstatus = FTDM_SIG_STATE_DOWN; - ftdm_channel_get_sig_status(span->channels[i], &sigstatus); - if (sigstatus == FTDM_SIG_STATE_UP) { - ftdm_set_flag(span->channels[i], FTDM_CHANNEL_SIG_UP); - } - } - if (ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) { - status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE); - } - if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) { - status = ftdm_queue_create(&span->pendingsignals, SPAN_PENDING_SIGNALS_QUEUE_SIZE); - } - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_configure_span(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ...) -{ - ftdm_module_t *mod = (ftdm_module_t *) hashtable_search(globals.module_hash, (void *)type); - ftdm_status_t status = FTDM_FAIL; - - if (!span->chan_count) { - ftdm_log(FTDM_LOG_WARNING, "Cannot configure signaling on span with no channels\n"); - return FTDM_FAIL; - } - - if (!mod) { - ftdm_load_module_assume(type); - if ((mod = (ftdm_module_t *) hashtable_search(globals.module_hash, (void *)type))) { - ftdm_log(FTDM_LOG_INFO, "auto-loaded '%s'\n", type); - } else { - ftdm_log(FTDM_LOG_ERROR, "can't load '%s'\n", type); - return FTDM_FAIL; - } - } - - if (mod->sig_configure) { - va_list ap; - va_start(ap, sig_cb); - status = mod->sig_configure(span, sig_cb, ap); - va_end(ap); - if (status == FTDM_SUCCESS) { - status = post_configure_span_channels(span); - } - } else { - ftdm_log(FTDM_LOG_CRIT, "module '%s' did not implement the sig_configure method\n", type); - status = FTDM_FAIL; - } - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *parameters) -{ - ftdm_module_t *mod = (ftdm_module_t *) hashtable_search(globals.module_hash, (void *)type); - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(type != NULL, FTDM_FAIL, "No signaling type"); - ftdm_assert_return(span != NULL, FTDM_FAIL, "No span"); - ftdm_assert_return(sig_cb != NULL, FTDM_FAIL, "No signaling callback"); - ftdm_assert_return(parameters != NULL, FTDM_FAIL, "No parameters"); - - if (!span->chan_count) { - ftdm_log(FTDM_LOG_WARNING, "Cannot configure signaling on span %s with no channels\n", span->name); - return FTDM_FAIL; - } - - if (!mod) { - ftdm_load_module_assume(type); - if ((mod = (ftdm_module_t *) hashtable_search(globals.module_hash, (void *)type))) { - ftdm_log(FTDM_LOG_INFO, "auto-loaded '%s'\n", type); - } - } - - if (!mod) { - ftdm_log(FTDM_LOG_ERROR, "Failed to load module type: %s\n", type); - return FTDM_FAIL; - } - - if (mod->configure_span_signaling) { - status = mod->configure_span_signaling(span, sig_cb, parameters); - if (status == FTDM_SUCCESS) { - status = post_configure_span_channels(span); - } - } else { - ftdm_log(FTDM_LOG_ERROR, "Module %s did not implement the signaling configuration method\n", type); - } - - return status; -} - -static void *ftdm_span_service_events(ftdm_thread_t *me, void *obj) -{ - uint32_t i; - unsigned waitms; - ftdm_event_t *event; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_span_t *span = (ftdm_span_t*) obj; - short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); - - if (me == 0) {}; - - memset(poll_events, 0, sizeof(short) * span->chan_count); - - for(i = 1; i <= span->chan_count; i++) { - poll_events[i] |= FTDM_EVENTS; - } - - while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) { - waitms = 1000; - status = ftdm_span_poll_event(span, waitms, poll_events); - switch (status) { - case FTDM_FAIL: - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to poll span for events\n", span->name); - break; - case FTDM_TIMEOUT: - break; - case FTDM_SUCCESS: - /* Check if there are any channels that have events available */ - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS); - break; - default: - ftdm_log(FTDM_LOG_CRIT, "%s:Unhandled IO event\n", span->name); - } - } - return NULL; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb) -{ - span->signal_cb = sig_cb; - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_mutex_lock(span->mutex); - - if (ftdm_test_flag(span, FTDM_SPAN_STARTED)) { - status = FTDM_EINVAL; - goto done; - } - if (span->signal_type == FTDM_SIGTYPE_NONE) { - /* If there is no signalling component, start a thread to poll events */ - status = ftdm_thread_create_detached(ftdm_span_service_events, span); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT,"Failed to start span event monitor thread!\n"); - goto done; - } - - //ftdm_report_initial_channels_alarms(span); - ftdm_set_flag_locked(span, FTDM_SPAN_STARTED); - goto done; - } - - if (!span->start) { - status = FTDM_ENOSYS; - goto done; - } - - /* Start I/O */ - if (span->fio && span->fio->span_start) { - status = span->fio->span_start(span); - if (status != FTDM_SUCCESS) - goto done; - } - - /* Start SIG */ - status = ftdm_report_initial_channels_alarms(span); - if (status != FTDM_SUCCESS) { - goto done; - } - - status = span->start(span); - if (status == FTDM_SUCCESS) { - ftdm_set_flag_locked(span, FTDM_SPAN_STARTED); - } -done: - ftdm_mutex_unlock(span->mutex); - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_add_to_group(const char* name, ftdm_channel_t* ftdmchan) -{ - unsigned int i; - ftdm_group_t* group = NULL; - - ftdm_mutex_lock(globals.group_mutex); - - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Cannot add a null channel to a group\n"); - - if (ftdm_group_find_by_name(name, &group) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_DEBUG, "Creating new group:%s\n", name); - ftdm_group_create(&group, name); - } - - /*verify that group does not already include this channel first */ - for(i = 0; i < group->chan_count; i++) { - if (group->channels[i]->physical_span_id == ftdmchan->physical_span_id && - group->channels[i]->physical_chan_id == ftdmchan->physical_chan_id) { - - ftdm_mutex_unlock(globals.group_mutex); - ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d is already added to group %s\n", - group->channels[i]->physical_span_id, - group->channels[i]->physical_chan_id, - name); - return FTDM_SUCCESS; - } - } - - if (group->chan_count >= FTDM_MAX_CHANNELS_GROUP) { - ftdm_log(FTDM_LOG_ERROR, "Max number of channels exceeded (max:%d)\n", FTDM_MAX_CHANNELS_GROUP); - ftdm_mutex_unlock(globals.group_mutex); - return FTDM_FAIL; - } - - group->channels[group->chan_count++] = ftdmchan; - ftdm_mutex_unlock(globals.group_mutex); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_remove_from_group(ftdm_group_t* group, ftdm_channel_t* ftdmchan) -{ - unsigned int i, j; - //Need to test this function - ftdm_mutex_lock(globals.group_mutex); - - for (i=0; i < group->chan_count; i++) { - if (group->channels[i]->physical_span_id == ftdmchan->physical_span_id && - group->channels[i]->physical_chan_id == ftdmchan->physical_chan_id) { - - j=i; - while(j < group->chan_count-1) { - group->channels[j] = group->channels[j+1]; - j++; - } - group->channels[group->chan_count--] = NULL; - if (group->chan_count <=0) { - /* Delete group if it is empty */ - hashtable_remove(globals.group_hash, (void *)group->name); - } - ftdm_mutex_unlock(globals.group_mutex); - return FTDM_SUCCESS; - } - } - - ftdm_mutex_unlock(globals.group_mutex); - //Group does not contain this channel - return FTDM_FAIL; -} - -static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name) -{ - unsigned chan_index = 0; - - ftdm_assert_return(strlen(name) > 0, FTDM_FAIL, "Invalid group name provided\n"); - ftdm_assert_return(currindex >= 0, FTDM_FAIL, "Invalid current channel index provided\n"); - - if (!span->chan_count) { - return FTDM_SUCCESS; - } - - for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) { - if (!FTDM_IS_VOICE_CHANNEL(span->channels[chan_index])) { - continue; - } - if (ftdm_channel_add_to_group(name, span->channels[chan_index])) { - ftdm_log(FTDM_LOG_ERROR, "Failed to add chan:%d to group:%s\n", chan_index, name); - } - } - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_group_find(uint32_t id, ftdm_group_t **group) -{ - ftdm_group_t *fgroup = NULL, *grp; - - if (id > FTDM_MAX_GROUPS_INTERFACE) { - return FTDM_FAIL; - } - - - ftdm_mutex_lock(globals.group_mutex); - for (grp = globals.groups; grp; grp = grp->next) { - if (grp->group_id == id) { - fgroup = grp; - break; - } - } - ftdm_mutex_unlock(globals.group_mutex); - - if (!fgroup) { - return FTDM_FAIL; - } - - *group = fgroup; - - return FTDM_SUCCESS; - -} - -FT_DECLARE(ftdm_status_t) ftdm_group_find_by_name(const char *name, ftdm_group_t **group) -{ - ftdm_status_t status = FTDM_FAIL; - *group = NULL; - ftdm_mutex_lock(globals.group_mutex); - if (!ftdm_strlen_zero(name)) { - if ((*group = hashtable_search(globals.group_hash, (void *) name))) { - status = FTDM_SUCCESS; - } - } - ftdm_mutex_unlock(globals.group_mutex); - return status; -} - -static void ftdm_group_add(ftdm_group_t *group) -{ - ftdm_group_t *grp; - ftdm_mutex_lock(globals.group_mutex); - - for (grp = globals.groups; grp && grp->next; grp = grp->next); - - if (grp) { - grp->next = group; - } else { - globals.groups = group; - } - hashtable_insert(globals.group_hash, (void *)group->name, group, HASHTABLE_FLAG_NONE); - - ftdm_mutex_unlock(globals.group_mutex); -} - -FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *name) -{ - ftdm_group_t *new_group = NULL; - ftdm_status_t status = FTDM_FAIL; - - ftdm_mutex_lock(globals.mutex); - if (globals.group_index < FTDM_MAX_GROUPS_INTERFACE) { - new_group = ftdm_calloc(1, sizeof(*new_group)); - - ftdm_assert(new_group != NULL, "Failed to create new ftdm group, expect a crash\n"); - - status = ftdm_mutex_create(&new_group->mutex); - - ftdm_assert(status == FTDM_SUCCESS, "Failed to create group mutex, expect a crash\n"); - - new_group->group_id = ++globals.group_index; - new_group->name = ftdm_strdup(name); - ftdm_group_add(new_group); - *group = new_group; - status = FTDM_SUCCESS; - } else { - ftdm_log(FTDM_LOG_ERROR, "Group %s was not added, we exceeded the max number of groups\n", name); - } - ftdm_mutex_unlock(globals.mutex); - return status; -} - -static void ftdm_group_destroy(ftdm_group_t **group) -{ - ftdm_group_t *grp = NULL; - ftdm_assert(group != NULL, "Group must not be null\n"); - grp = *group; - ftdm_mutex_destroy(&grp->mutex); - ftdm_safe_free(grp->name); - ftdm_safe_free(grp); - *group = NULL; -} - -static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) -{ - if (!span->signal_cb) { - return FTDM_FAIL; - } - return span->signal_cb(sigmsg); -} - -static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) -{ - ftdm_sigmsg_t *new_sigmsg = NULL; - - new_sigmsg = ftdm_calloc(1, sizeof(*sigmsg)); - if (!new_sigmsg) { - return FTDM_FAIL; - } - memcpy(new_sigmsg, sigmsg, sizeof(*sigmsg)); - - ftdm_queue_enqueue(span->pendingsignals, new_sigmsg); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span) -{ - ftdm_sigmsg_t *sigmsg = NULL; - while ((sigmsg = ftdm_queue_dequeue(span->pendingsignals))) { - ftdm_span_trigger_signal(span, sigmsg); - ftdm_sigmsg_free(&sigmsg); - } - return FTDM_SUCCESS; -} - -static void execute_safety_hangup(void *data) -{ - ftdm_channel_t *fchan = data; - ftdm_channel_lock(fchan); - fchan->hangup_timer = 0; - if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER); - _ftdm_channel_call_hangup_nl(__FILE__, __FTDM_FUNC__, __LINE__, fchan, NULL); - } else { - ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state)); - } - ftdm_channel_unlock(fchan); -} - -FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) -{ - ftdm_channel_t *fchan = NULL; - ftdm_status_t status = FTDM_SUCCESS; - if (sigmsg->channel) { - fchan = sigmsg->channel; - ftdm_channel_lock(fchan); - } - - /* some core things to do on special events */ - switch (sigmsg->event_id) { - - case FTDM_SIGEVENT_SIGSTATUS_CHANGED: - { - if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_UP) { - ftdm_set_flag(fchan, FTDM_CHANNEL_SIG_UP); - ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED); - } else { - ftdm_clear_flag(fchan, FTDM_CHANNEL_SIG_UP); - if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_SUSPENDED) { - ftdm_set_flag(fchan, FTDM_CHANNEL_SUSPENDED); - } else { - ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED); - } - } - } - break; - - case FTDM_SIGEVENT_START: - { - ftdm_assert(!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED), "Started call twice!\n"); - - if (ftdm_test_flag(fchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "Inbound call taking over outbound channel\n"); - ftdm_clear_flag(fchan, FTDM_CHANNEL_OUTBOUND); - } - ftdm_set_flag(fchan, FTDM_CHANNEL_CALL_STARTED); - ftdm_call_set_call_id(fchan, &fchan->caller_data); - /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was - * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if - * is needed at all? */ - ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD); - if (sigmsg->channel->caller_data.bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) { - ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_DIGITAL_MEDIA); - } - } - break; - - case FTDM_SIGEVENT_PROGRESS_MEDIA: - { - /* test signaling module compliance */ - if (fchan->state != FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "FTDM_SIGEVENT_PROGRESS_MEDIA sent in state %s\n", ftdm_channel_state2str(fchan->state)); - } - } - break; - - case FTDM_SIGEVENT_UP: - { - /* test signaling module compliance */ - if (fchan->state != FTDM_CHANNEL_STATE_UP) { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "FTDM_SIGEVENT_UP sent in state %s\n", ftdm_channel_state2str(fchan->state)); - } - } - break; - - case FTDM_SIGEVENT_STOP: - { - /* TODO: we could test for compliance here and check the state is FTDM_CHANNEL_STATE_TERMINATING - * but several modules need to be updated first */ - - /* if the call was never started, do not send SIGEVENT_STOP - this happens for FXS devices in ftmod_analog which blindly send SIGEVENT_STOP, we should fix it there ... */ - if (!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED)) { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n"); - goto done; - } - - if (ftdm_test_flag(fchan, FTDM_CHANNEL_USER_HANGUP)) { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n"); - goto done; - } - - if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n"); - /* if the user does not move us to hangup in 2 seconds, we will do it ourselves */ - ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, fchan, &fchan->hangup_timer); - } - } - break; - - default: - break; - - } - - if (fchan) { - /* set members of the sigmsg that must be present for all events */ - sigmsg->chan_id = fchan->chan_id; - sigmsg->span_id = fchan->span_id; - sigmsg->call_id = fchan->caller_data.call_id; - sigmsg->call_priv = fchan->caller_data.priv; - } - - /* if the signaling module uses a queue for signaling notifications, then enqueue it */ - if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) { - ftdm_span_queue_signal(span, sigmsg); - } else { - status = ftdm_span_trigger_signal(span, sigmsg); - } - -done: - - if (fchan) { - ftdm_channel_unlock(fchan); - } - - return status; -} - -static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj) -{ - cpu_monitor_t *monitor = (cpu_monitor_t *)obj; - struct ftdm_cpu_monitor_stats *cpu_stats = ftdm_new_cpu_monitor(); - - ftdm_log(FTDM_LOG_DEBUG, "CPU monitor thread is now running\n"); - if (!cpu_stats) { - goto done; - } - monitor->running = 1; - - while (ftdm_running()) { - double idle_time = 0.0; - int cpu_usage = 0; - - if (ftdm_cpu_get_system_idle_time(cpu_stats, &idle_time)) { - break; - } - - cpu_usage = (int)(100 - idle_time); - if (monitor->alarm) { - if (cpu_usage <= monitor->clear_alarm_threshold) { - ftdm_log(FTDM_LOG_DEBUG, "CPU alarm is now OFF (cpu usage: %d)\n", cpu_usage); - monitor->alarm = 0; - } else if (monitor->alarm_action_flags & FTDM_CPU_ALARM_ACTION_WARN) { - ftdm_log(FTDM_LOG_WARNING, "CPU alarm is still ON (cpu usage: %d)\n", cpu_usage); - } - } else { - if (cpu_usage >= monitor->set_alarm_threshold) { - ftdm_log(FTDM_LOG_WARNING, "CPU alarm is now ON (cpu usage: %d)\n", cpu_usage); - monitor->alarm = 1; - } - } - ftdm_interrupt_wait(monitor->interrupt, monitor->interval); - } - - ftdm_delete_cpu_monitor(cpu_stats); - monitor->running = 0; - -done: - ftdm_unused_arg(me); - ftdm_log(FTDM_LOG_DEBUG, "CPU monitor thread is now terminating\n"); - return NULL; -} - -static ftdm_status_t ftdm_cpu_monitor_start(void) -{ - if (ftdm_interrupt_create(&globals.cpu_monitor.interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to create CPU monitor interrupt\n"); - return FTDM_FAIL; - } - - if (ftdm_thread_create_detached(ftdm_cpu_monitor_run, &globals.cpu_monitor) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to create cpu monitor thread!!\n"); - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -static void ftdm_cpu_monitor_stop(void) -{ - if (!globals.cpu_monitor.interrupt) { - return; - } - - if (!globals.cpu_monitor.running) { - return; - } - - if (ftdm_interrupt_signal(globals.cpu_monitor.interrupt) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to interrupt the CPU monitor\n"); - return; - } - - while (globals.cpu_monitor.running) { - ftdm_sleep(10); - } - - ftdm_interrupt_destroy(&globals.cpu_monitor.interrupt); -} - -FT_DECLARE(ftdm_status_t) ftdm_global_init(void) -{ - memset(&globals, 0, sizeof(globals)); - - time_init(); - - ftdm_thread_override_default_stacksize(FTDM_THREAD_STACKSIZE); - - globals.interface_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - globals.module_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - globals.span_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - globals.group_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - ftdm_mutex_create(&globals.mutex); - ftdm_mutex_create(&globals.span_mutex); - ftdm_mutex_create(&globals.group_mutex); - ftdm_mutex_create(&globals.call_id_mutex); - - ftdm_sched_global_init(); - globals.running = 1; - if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n"); - goto global_init_fail; - } - if (ftdm_sched_free_run(globals.timingsched) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n"); - goto global_init_fail; - } - - return FTDM_SUCCESS; - -global_init_fail: - globals.running = 0; - ftdm_mutex_destroy(&globals.mutex); - ftdm_mutex_destroy(&globals.span_mutex); - ftdm_mutex_destroy(&globals.group_mutex); - ftdm_mutex_destroy(&globals.call_id_mutex); - hashtable_destroy(globals.interface_hash); - hashtable_destroy(globals.module_hash); - hashtable_destroy(globals.span_hash); - hashtable_destroy(globals.group_hash); - - return FTDM_FAIL; -} - -FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void) -{ - int modcount = 0; - - if (!globals.running) { - return FTDM_FAIL; - } - - modcount = ftdm_load_modules(); - - ftdm_log(FTDM_LOG_NOTICE, "Modules configured: %d \n", modcount); - - globals.cpu_monitor.enabled = 0; - globals.cpu_monitor.interval = 1000; - globals.cpu_monitor.alarm_action_flags = 0; - globals.cpu_monitor.set_alarm_threshold = 92; - globals.cpu_monitor.clear_alarm_threshold = 82; - - if (load_config() != FTDM_SUCCESS) { - globals.running = 0; - ftdm_log(FTDM_LOG_ERROR, "FreeTDM global configuration failed!\n"); - return FTDM_FAIL; - } - - if (globals.cpu_monitor.enabled) { - ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d set-thres:%d clear-thres:%d\n", - globals.cpu_monitor.interval, - globals.cpu_monitor.set_alarm_threshold, - globals.cpu_monitor.clear_alarm_threshold); - - if (ftdm_cpu_monitor_start() != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } - - - return FTDM_SUCCESS; -} - -FT_DECLARE(uint32_t) ftdm_running(void) -{ - return globals.running; -} - -static void destroy_span(ftdm_span_t *span) -{ - if (ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) { - ftdm_span_destroy(span); - } - hashtable_remove(globals.span_hash, (void *)span->name); - ftdm_safe_free(span->dtmf_hangup); - ftdm_safe_free(span->type); - ftdm_safe_free(span->name); - ftdm_safe_free(span); -} - -static void force_stop_span(ftdm_span_t *span) -{ - /* This is a forced stop */ - ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE); - ftdm_span_stop(span); -} - -static void span_for_each(void (*func)(ftdm_span_t *span)) -{ - ftdm_span_t *sp = NULL, *next = NULL; - for (sp = globals.spans; sp; sp = next) { - next = sp->next; - func(sp); - } -} - -FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void) -{ - ftdm_group_t *grp = NULL, *next_grp = NULL; - - time_end(); - - /* many freetdm event loops rely on this variable to decide when to stop, do this first */ - globals.running = 0; - - /* stop the scheduling thread */ - ftdm_free_sched_stop(); - - /* stop the cpu monitor thread */ - ftdm_cpu_monitor_stop(); - - /* now destroy channels and spans */ - globals.span_index = 0; - - ftdm_span_close_all(); - - /* Stop and destroy alls pans */ - ftdm_mutex_lock(globals.span_mutex); - - span_for_each(force_stop_span); - span_for_each(destroy_span); - globals.spans = NULL; - - ftdm_mutex_unlock(globals.span_mutex); - - /* destroy signaling and io modules */ - ftdm_unload_modules(); - - /* Destroy hunting groups */ - ftdm_mutex_lock(globals.group_mutex); - grp = globals.groups; - while (grp) { - next_grp = grp->next; - ftdm_group_destroy(&grp); - grp = next_grp; - } - ftdm_mutex_unlock(globals.group_mutex); - - /* finally destroy the globals */ - ftdm_mutex_lock(globals.mutex); - - ftdm_sched_destroy(&globals.timingsched); - - hashtable_destroy(globals.interface_hash); - hashtable_destroy(globals.module_hash); - hashtable_destroy(globals.span_hash); - hashtable_destroy(globals.group_hash); - - ftdm_mutex_destroy(&globals.span_mutex); - ftdm_mutex_destroy(&globals.group_mutex); - ftdm_mutex_destroy(&globals.call_id_mutex); - - ftdm_mutex_unlock(globals.mutex); - - ftdm_mutex_destroy(&globals.mutex); - - ftdm_sched_global_destroy(); - - ftdm_global_set_logger(NULL); - memset(&globals, 0, sizeof(globals)); - return FTDM_SUCCESS; -} - - -FT_DECLARE(uint32_t) ftdm_separate_string(char *buf, char delim, char **array, int arraylen) -{ - int argc; - char *ptr; - int quot = 0; - char qc = '\''; - int x; - - if (!buf || !array || !arraylen) { - return 0; - } - - memset(array, 0, arraylen * sizeof(*array)); - - ptr = buf; - - /* we swallow separators that are contiguous */ - while (*ptr == delim) ptr++; - - for (argc = 0; *ptr && (argc < arraylen - 1); argc++) { - array[argc] = ptr; - for (; *ptr; ptr++) { - if (*ptr == qc) { - if (quot) { - quot--; - } else { - quot++; - } - } else if ((*ptr == delim) && !quot) { - *ptr++ = '\0'; - /* we swallow separators that are contiguous */ - while (*ptr == delim) ptr++; - break; - } - } - } - - if (*ptr) { - array[argc++] = ptr; - } - - /* strip quotes */ - for (x = 0; x < argc; x++) { - char *p = array[x]; - while((p = strchr(array[x], qc))) { - memmove(p, p+1, strlen(p)); - p++; - } - } - - return argc; -} - -FT_DECLARE(void) ftdm_bitstream_init(ftdm_bitstream_t *bsp, uint8_t *data, uint32_t datalen, ftdm_endian_t endian, uint8_t ss) -{ - memset(bsp, 0, sizeof(*bsp)); - bsp->data = data; - bsp->datalen = datalen; - bsp->endian = endian; - bsp->ss = ss; - - if (endian < 0) { - bsp->top = bsp->bit_index = 7; - bsp->bot = 0; - } else { - bsp->top = bsp->bit_index = 0; - bsp->bot = 7; - } - -} - -FT_DECLARE(int8_t) ftdm_bitstream_get_bit(ftdm_bitstream_t *bsp) -{ - int8_t bit = -1; - - - if (bsp->byte_index >= bsp->datalen) { - goto done; - } - - if (bsp->ss) { - if (!bsp->ssv) { - bsp->ssv = 1; - return 0; - } else if (bsp->ssv == 2) { - bsp->byte_index++; - bsp->ssv = 0; - return 1; - } - } - - - - - bit = (bsp->data[bsp->byte_index] >> (bsp->bit_index)) & 1; - - if (bsp->bit_index == bsp->bot) { - bsp->bit_index = bsp->top; - if (bsp->ss) { - bsp->ssv = 2; - goto done; - } - - if (++bsp->byte_index > bsp->datalen) { - bit = -1; - goto done; - } - - } else { - bsp->bit_index = bsp->bit_index + bsp->endian; - } - - - done: - return bit; -} - -FT_DECLARE(void) print_hex_bytes(uint8_t *data, ftdm_size_t dlen, char *buf, ftdm_size_t blen) -{ - char *bp = buf; - uint8_t *byte = data; - uint32_t i, j = 0; - - if (blen < (dlen * 3) + 2) { - return; - } - - *bp++ = '['; - j++; - - for(i = 0; i < dlen; i++) { - snprintf(bp, blen-j, "%02x ", *byte++); - bp += 3; - j += 3; - } - - *--bp = ']'; - -} - -FT_DECLARE(void) print_bits(uint8_t *b, int bl, char *buf, int blen, ftdm_endian_t e, uint8_t ss) -{ - ftdm_bitstream_t bs; - int j = 0, c = 0; - int8_t bit; - uint32_t last; - - if (blen < (bl * 10) + 2) { - return; - } - - ftdm_bitstream_init(&bs, b, bl, e, ss); - last = bs.byte_index; - while((bit = ftdm_bitstream_get_bit(&bs)) > -1) { - buf[j++] = bit ? '1' : '0'; - if (bs.byte_index != last) { - buf[j++] = ' '; - last = bs.byte_index; - if (++c == 8) { - buf[j++] = '\n'; - c = 0; - } - } - } - -} - - - -FT_DECLARE_NONSTD(ftdm_status_t) ftdm_console_stream_raw_write(ftdm_stream_handle_t *handle, uint8_t *data, ftdm_size_t datalen) -{ - ftdm_size_t need = handle->data_len + datalen; - - if (need >= handle->data_size) { - void *new_data; - need += handle->alloc_chunk; - - if (!(new_data = realloc(handle->data, need))) { - return FTDM_MEMERR; - } - - handle->data = new_data; - handle->data_size = need; - } - - memcpy((uint8_t *) (handle->data) + handle->data_len, data, datalen); - handle->data_len += datalen; - handle->end = (uint8_t *) (handle->data) + handle->data_len; - *(uint8_t *)handle->end = '\0'; - - return FTDM_SUCCESS; -} - -FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap) /* code from switch_apr.c */ -{ -#ifdef HAVE_VASPRINTF - return vasprintf(ret, fmt, ap); -#else - char *buf; - int len; - size_t buflen; - va_list ap2; - char *tmp = NULL; - -#ifdef _MSC_VER -#if _MSC_VER >= 1500 - /* hack for incorrect assumption in msvc header files for code analysis */ - __analysis_assume(tmp); -#endif - ap2 = ap; -#else - va_copy(ap2, ap); -#endif - - len = vsnprintf(tmp, 0, fmt, ap2); - - if (len > 0 && (buf = ftdm_malloc((buflen = (size_t) (len + 1)))) != NULL) { - len = vsnprintf(buf, buflen, fmt, ap); - *ret = buf; - } else { - *ret = NULL; - len = -1; - } - - va_end(ap2); - return len; -#endif -} - -FT_DECLARE_NONSTD(ftdm_status_t) ftdm_console_stream_write(ftdm_stream_handle_t *handle, const char *fmt, ...) -{ - va_list ap; - char *buf = handle->data; - char *end = handle->end; - int ret = 0; - char *data = NULL; - - if (handle->data_len >= handle->data_size) { - return FTDM_FAIL; - } - - va_start(ap, fmt); - ret = ftdm_vasprintf(&data, fmt, ap); - va_end(ap); - - if (data) { - ftdm_size_t remaining = handle->data_size - handle->data_len; - ftdm_size_t need = strlen(data) + 1; - - if ((remaining < need) && handle->alloc_len) { - ftdm_size_t new_len; - void *new_data; - - new_len = handle->data_size + need + handle->alloc_chunk; - if ((new_data = ftdm_realloc(handle->data, new_len))) { - handle->data_size = handle->alloc_len = new_len; - handle->data = new_data; - buf = handle->data; - remaining = handle->data_size - handle->data_len; - handle->end = (uint8_t *) (handle->data) + handle->data_len; - end = handle->end; - } else { - ftdm_log(FTDM_LOG_CRIT, "Memory Error!\n"); - ftdm_safe_free(data); - return FTDM_FAIL; - } - } - - if (remaining < need) { - ret = -1; - } else { - ret = 0; - snprintf(end, remaining, "%s", data); - handle->data_len = strlen(buf); - handle->end = (uint8_t *) (handle->data) + handle->data_len; - } - ftdm_safe_free(data); - } - - return ret ? FTDM_FAIL : FTDM_SUCCESS; -} - -FT_DECLARE(char *) ftdm_strdup(const char *str) -{ - ftdm_size_t len = strlen(str) + 1; - void *new = ftdm_malloc(len); - - if (!new) { - return NULL; - } - - return (char *)memcpy(new, str, len); -} - -FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen) -{ - char *new = NULL; - ftdm_size_t len = strlen(str) + 1; - if (len > (inlen+1)) { - len = inlen+1; - } - new = (char *)ftdm_malloc(len); - - if (!new) { - return NULL; - } - - memcpy(new, str, len-1); - new[len-1] = 0; - return new; -} - -static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data) -{ - uint32_t current_call_id; - - ftdm_assert_return(!caller_data->call_id, FTDM_FAIL, "Overwriting non-cleared call-id\n"); - - ftdm_mutex_lock(globals.call_id_mutex); - - current_call_id = globals.last_call_id; - - for (current_call_id = globals.last_call_id + 1; - current_call_id != globals.last_call_id; - current_call_id++ ) { - if (current_call_id > MAX_CALLIDS) { - current_call_id = 1; - } - if (globals.call_ids[current_call_id] == NULL) { - break; - } - } - - ftdm_assert_return(globals.call_ids[current_call_id] == NULL, FTDM_FAIL, "We ran out of call ids\n"); - - globals.last_call_id = current_call_id; - caller_data->call_id = current_call_id; - - globals.call_ids[current_call_id] = caller_data; - caller_data->fchan = fchan; - - ftdm_mutex_unlock(globals.call_id_mutex); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data) -{ - if (caller_data->call_id) { - ftdm_assert_return((caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Cannot clear call with invalid call-id\n"); - } else { - /* there might not be a call at all */ - return FTDM_SUCCESS; - } - - ftdm_mutex_lock(globals.call_id_mutex); - if (globals.call_ids[caller_data->call_id]) { - ftdm_log(FTDM_LOG_DEBUG, "Cleared call with id %u\n", caller_data->call_id); - globals.call_ids[caller_data->call_id] = NULL; - caller_data->call_id = 0; - } else { - ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id); - } - ftdm_mutex_unlock(globals.call_id_mutex); - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_get_raw_data(ftdm_sigmsg_t *sigmsg, void **data, ftdm_size_t *datalen) -{ - if (!sigmsg || !sigmsg->raw.len) { - return FTDM_FAIL; - } - - *data = sigmsg->raw.data; - *datalen = sigmsg->raw.len; - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_get_raw_data_detached(ftdm_sigmsg_t *sigmsg, void **data, ftdm_size_t *datalen) -{ - if (!sigmsg || !sigmsg->raw.len) { - return FTDM_FAIL; - } - - *data = sigmsg->raw.data; - *datalen = sigmsg->raw.len; - - sigmsg->raw.data = NULL; - sigmsg->raw.len = 0; - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *data, ftdm_size_t datalen) -{ - ftdm_assert_return(sigmsg, FTDM_FAIL, "Trying to set raw data on a NULL event\n"); - ftdm_assert_return(!sigmsg->raw.len, FTDM_FAIL, "Overwriting existing raw data\n"); - ftdm_assert_return(datalen, FTDM_FAIL, "Data length not set\n"); - - sigmsg->raw.data = data; - sigmsg->raw.len = datalen; - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_get_raw_data(ftdm_usrmsg_t *usrmsg, void **data, ftdm_size_t *datalen) -{ - if (!usrmsg || !usrmsg->raw.len) { - return FTDM_FAIL; - } - - *data = usrmsg->raw.data; - *datalen = usrmsg->raw.len; - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_set_raw_data(ftdm_usrmsg_t *usrmsg, void *data, ftdm_size_t datalen) -{ - ftdm_assert_return(usrmsg, FTDM_FAIL, "Trying to set raw data on a NULL event\n"); - ftdm_assert_return(!usrmsg->raw.len, FTDM_FAIL, "Overwriting existing raw data\n"); - ftdm_assert_return(datalen, FTDM_FAIL, "Data length not set\n"); - - usrmsg->raw.data = data; - usrmsg->raw.len = datalen; - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_save_usrmsg(ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg) -{ - ftdm_assert_return(!ftdmchan->usrmsg, FTDM_FAIL, "Info from previous event was not cleared\n"); - if (usrmsg) { - /* Copy sigmsg from user to internal copy so user can set new variables without race condition */ - ftdmchan->usrmsg = ftdm_calloc(1, sizeof(ftdm_usrmsg_t)); - memcpy(ftdmchan->usrmsg, usrmsg, sizeof(ftdm_usrmsg_t)); - - if (usrmsg->raw.data) { - usrmsg->raw.data = NULL; - usrmsg->raw.len = 0; - } - if (usrmsg->variables) { - usrmsg->variables = NULL; - } - } - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_free(ftdm_sigmsg_t **sigmsg) -{ - if (!*sigmsg) { - return FTDM_SUCCESS; - } - - if ((*sigmsg)->variables) { - hashtable_destroy((*sigmsg)->variables); - (*sigmsg)->variables = NULL; - } - - if ((*sigmsg)->raw.data) { - ftdm_safe_free((*sigmsg)->raw.data); - (*sigmsg)->raw.data = NULL; - (*sigmsg)->raw.len = 0; - } - - ftdm_safe_free(*sigmsg); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_free(ftdm_usrmsg_t **usrmsg) -{ - if (!*usrmsg) { - return FTDM_SUCCESS; - } - - if ((*usrmsg)->variables) { - hashtable_destroy((*usrmsg)->variables); - (*usrmsg)->variables = NULL; - } - - if ((*usrmsg)->raw.data) { - ftdm_safe_free((*usrmsg)->raw.data); - (*usrmsg)->raw.data = NULL; - (*usrmsg)->raw.len = 0; - } - - ftdm_safe_free(*usrmsg); - return FTDM_SUCCESS; -} - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_queue.c b/libs/freetdm/src/ftdm_queue.c deleted file mode 100644 index c4c6524064..0000000000 --- a/libs/freetdm/src/ftdm_queue.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2009, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "private/ftdm_core.h" - -static ftdm_status_t ftdm_std_queue_create(ftdm_queue_t **outqueue, ftdm_size_t capacity); -static ftdm_status_t ftdm_std_queue_enqueue(ftdm_queue_t *queue, void *obj); -static void *ftdm_std_queue_dequeue(ftdm_queue_t *queue); -static ftdm_status_t ftdm_std_queue_wait(ftdm_queue_t *queue, int ms); -static ftdm_status_t ftdm_std_queue_get_interrupt(ftdm_queue_t *queue, ftdm_interrupt_t **interrupt); -static ftdm_status_t ftdm_std_queue_destroy(ftdm_queue_t **inqueue); - -struct ftdm_queue { - ftdm_mutex_t *mutex; - ftdm_interrupt_t *interrupt; - ftdm_size_t capacity; - ftdm_size_t size; - unsigned rindex; - unsigned windex; - void **elements; -}; - -FT_DECLARE_DATA ftdm_queue_handler_t g_ftdm_queue_handler = -{ - /*.create = */ ftdm_std_queue_create, - /*.enqueue = */ ftdm_std_queue_enqueue, - /*.dequeue = */ ftdm_std_queue_dequeue, - /*.wait = */ ftdm_std_queue_wait, - /*.get_interrupt = */ ftdm_std_queue_get_interrupt, - /*.destroy = */ ftdm_std_queue_destroy -}; - -FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *handler) -{ - if (!handler || - !handler->create || - !handler->enqueue || - !handler->dequeue || - !handler->wait || - !handler->get_interrupt || - !handler->destroy) { - return FTDM_FAIL; - } - memcpy(&g_ftdm_queue_handler, handler, sizeof(*handler)); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_std_queue_create(ftdm_queue_t **outqueue, ftdm_size_t capacity) -{ - ftdm_queue_t *queue = NULL; - ftdm_assert_return(outqueue, FTDM_FAIL, "Queue double pointer is null\n"); - ftdm_assert_return(capacity > 0, FTDM_FAIL, "Queue capacity is not bigger than 0\n"); - - *outqueue = NULL; - queue = ftdm_calloc(1, sizeof(*queue)); - if (!queue) { - return FTDM_FAIL; - } - - queue->elements = ftdm_calloc(1, (sizeof(void*)*capacity)); - if (!queue->elements) { - goto failed; - } - queue->capacity = capacity; - - if (ftdm_mutex_create(&queue->mutex) != FTDM_SUCCESS) { - goto failed; - } - - if (ftdm_interrupt_create(&queue->interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS) != FTDM_SUCCESS) { - goto failed; - } - - *outqueue = queue; - return FTDM_SUCCESS; - -failed: - if (queue) { - if (queue->interrupt) { - ftdm_interrupt_destroy(&queue->interrupt); - } - if (queue->mutex) { - ftdm_mutex_destroy(&queue->mutex); - } - ftdm_safe_free(queue->elements); - ftdm_safe_free(queue); - } - return FTDM_FAIL; -} - -static ftdm_status_t ftdm_std_queue_enqueue(ftdm_queue_t *queue, void *obj) -{ - ftdm_status_t status = FTDM_FAIL; - - ftdm_assert_return(queue != NULL, FTDM_FAIL, "Queue is null!"); - - ftdm_mutex_lock(queue->mutex); - - if (queue->windex == queue->capacity) { - /* try to see if we can wrap around */ - queue->windex = 0; - } - - if (queue->size != 0 && queue->windex == queue->rindex) { - ftdm_log(FTDM_LOG_ERROR, "Failed to enqueue obj %p in queue %p, no more room! windex == rindex == %d!\n", obj, queue, queue->windex); - goto done; - } - - queue->elements[queue->windex++] = obj; - queue->size++; - status = FTDM_SUCCESS; - - /* wake up queue reader */ - ftdm_interrupt_signal(queue->interrupt); - -done: - - ftdm_mutex_unlock(queue->mutex); - - return status; -} - -static void *ftdm_std_queue_dequeue(ftdm_queue_t *queue) -{ - void *obj = NULL; - - ftdm_assert_return(queue != NULL, NULL, "Queue is null!"); - - ftdm_mutex_lock(queue->mutex); - - if (queue->size == 0) { - goto done; - } - - obj = queue->elements[queue->rindex]; - queue->elements[queue->rindex++] = NULL; - queue->size--; - if (queue->rindex == queue->capacity) { - queue->rindex = 0; - } - -done: - - ftdm_mutex_unlock(queue->mutex); - - return obj; -} - -static ftdm_status_t ftdm_std_queue_wait(ftdm_queue_t *queue, int ms) -{ - ftdm_status_t ret; - ftdm_assert_return(queue != NULL, FTDM_FAIL, "Queue is null!"); - - ftdm_mutex_lock(queue->mutex); - - /* if there is elements in the queue, no need to wait */ - if (queue->size != 0) { - ftdm_mutex_unlock(queue->mutex); - return FTDM_SUCCESS; - } - - /* no elements on the queue, wait for someone to write an element */ - ret = ftdm_interrupt_wait(queue->interrupt, ms); - - /* got an element or timeout, bail out */ - ftdm_mutex_unlock(queue->mutex); - - return ret; -} - -static ftdm_status_t ftdm_std_queue_get_interrupt(ftdm_queue_t *queue, ftdm_interrupt_t **interrupt) -{ - ftdm_assert_return(queue != NULL, FTDM_FAIL, "Queue is null!\n"); - ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Queue is null!\n"); - *interrupt = queue->interrupt; - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_std_queue_destroy(ftdm_queue_t **inqueue) -{ - ftdm_queue_t *queue = NULL; - ftdm_assert_return(inqueue != NULL, FTDM_FAIL, "Queue is null!\n"); - ftdm_assert_return(*inqueue != NULL, FTDM_FAIL, "Queue is null!\n"); - - queue = *inqueue; - ftdm_interrupt_destroy(&queue->interrupt); - ftdm_mutex_destroy(&queue->mutex); - ftdm_safe_free(queue->elements); - ftdm_safe_free(queue); - *inqueue = NULL; - return FTDM_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_sched.c b/libs/freetdm/src/ftdm_sched.c deleted file mode 100644 index 324073976c..0000000000 --- a/libs/freetdm/src/ftdm_sched.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "private/ftdm_core.h" - -#ifdef __WINDOWS__ -struct ftdm_timezone { - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; -int gettimeofday(struct timeval *tv, struct ftdm_timezone *tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; - if (NULL != tv) { - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - - /*converting file time to unix epoch */ - tmpres /= 10; /*convert into microseconds */ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long) (tmpres / 1000000UL); - tv->tv_usec = (long) (tmpres % 1000000UL); - } - if (NULL != tz) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - return 0; -} -#endif /* __WINDOWS__ */ - -typedef struct ftdm_timer ftdm_timer_t; - -static struct { - ftdm_sched_t *freeruns; - ftdm_mutex_t *mutex; - ftdm_bool_t running; -} sched_globals; - -struct ftdm_sched { - char name[80]; - ftdm_timer_id_t currid; - ftdm_mutex_t *mutex; - ftdm_timer_t *timers; - int freerun; - ftdm_sched_t *next; - ftdm_sched_t *prev; -}; - -struct ftdm_timer { - char name[80]; - ftdm_timer_id_t id; - struct timeval time; - void *usrdata; - ftdm_sched_callback_t callback; - ftdm_timer_t *next; - ftdm_timer_t *prev; -}; - -/* FIXME: use ftdm_interrupt_t to wait for new schedules to monitor */ -#define SCHED_MAX_SLEEP 100 -static void *run_main_schedule(ftdm_thread_t *thread, void *data) -{ - int32_t timeto; - int32_t sleepms; - ftdm_status_t status; - ftdm_sched_t *current = NULL; - - ftdm_unused_arg(data); - ftdm_unused_arg(thread); - - while (ftdm_running()) { - - sleepms = SCHED_MAX_SLEEP; - - ftdm_mutex_lock(sched_globals.mutex); - - if (!sched_globals.freeruns) { - - /* there are no free runs, wait a bit and check again (FIXME: use ftdm_interrupt_t for this) */ - ftdm_mutex_unlock(sched_globals.mutex); - - if (ftdm_running()) { - ftdm_sleep(sleepms); - } - } - - for (current = sched_globals.freeruns; current; current = current->next) { - if (!ftdm_running()) { - break; - } - - /* first run the schedule */ - ftdm_sched_run(current); - - /* now find out how much time to sleep until running them again */ - status = ftdm_sched_get_time_to_next_timer(current, &timeto); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_WARNING, "Failed to get time to next timer for schedule %s, skipping\n", current->name); - continue; - } - - /* if timeto == -1 we don't want to sleep forever, so keep the last sleepms */ - if (timeto != -1 && sleepms > timeto) { - sleepms = timeto; - } - } - - ftdm_mutex_unlock(sched_globals.mutex); - - if (ftdm_running()) { - ftdm_sleep(sleepms); - } - } - ftdm_log(FTDM_LOG_NOTICE, "Main scheduling thread going out ...\n"); - sched_globals.running = 0; - return NULL; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_global_init() -{ - ftdm_log(FTDM_LOG_DEBUG, "Initializing scheduling API\n"); - memset(&sched_globals, 0, sizeof(sched_globals)); - if (ftdm_mutex_create(&sched_globals.mutex) == FTDM_SUCCESS) { - return FTDM_SUCCESS; - } - return FTDM_FAIL; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_global_destroy() -{ - ftdm_mutex_destroy(&sched_globals.mutex); - memset(&sched_globals, 0, sizeof(sched_globals)); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_assert_return(sched != NULL, FTDM_EINVAL, "invalid pointer\n"); - - ftdm_mutex_lock(sched->mutex); - - ftdm_mutex_lock(sched_globals.mutex); - - if (sched->freerun) { - ftdm_log(FTDM_LOG_ERROR, "Schedule %s is already running in free run\n", sched->name); - goto done; - } - sched->freerun = 1; - - if (sched_globals.running == FTDM_FALSE) { - ftdm_log(FTDM_LOG_NOTICE, "Launching main schedule thread\n"); - status = ftdm_thread_create_detached(run_main_schedule, NULL); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to launch main schedule thread\n"); - goto done; - } - sched_globals.running = FTDM_TRUE; - } - - ftdm_log(FTDM_LOG_DEBUG, "Running schedule %s in the main schedule thread\n", sched->name); - status = FTDM_SUCCESS; - - /* Add the schedule to the global list of free runs */ - if (!sched_globals.freeruns) { - sched_globals.freeruns = sched; - } else { - sched->next = sched_globals.freeruns; - sched_globals.freeruns->prev = sched; - sched_globals.freeruns = sched; - } - -done: - ftdm_mutex_unlock(sched_globals.mutex); - - ftdm_mutex_unlock(sched->mutex); - return status; -} - -FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void) -{ - return sched_globals.running; -} - -FT_DECLARE(ftdm_bool_t) ftdm_free_sched_stop(void) -{ - /* currently we really dont stop the thread here, we rely on freetdm being shutdown and ftdm_running() to be false - * so the scheduling thread dies and we just wait for it here */ - uint32_t sanity = 100; - while (ftdm_free_sched_running() && --sanity) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for main schedule thread to finish\n"); - ftdm_sleep(100); - } - - if (!sanity) { - ftdm_log(FTDM_LOG_CRIT, "schedule thread did not stop running, we may crash on shutdown\n"); - return FTDM_FALSE; - } - - return FTDM_TRUE; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name) -{ - ftdm_sched_t *newsched = NULL; - - ftdm_assert_return(sched != NULL, FTDM_EINVAL, "invalid pointer\n"); - ftdm_assert_return(name != NULL, FTDM_EINVAL, "invalid sched name\n"); - - *sched = NULL; - - newsched = ftdm_calloc(1, sizeof(*newsched)); - if (!newsched) { - return FTDM_MEMERR; - } - - if (ftdm_mutex_create(&newsched->mutex) != FTDM_SUCCESS) { - goto failed; - } - - ftdm_set_string(newsched->name, name); - newsched->currid = 1; - - *sched = newsched; - ftdm_log(FTDM_LOG_DEBUG, "Created schedule %s\n", name); - return FTDM_SUCCESS; - -failed: - ftdm_log(FTDM_LOG_CRIT, "Failed to create schedule\n"); - - if (newsched) { - if (newsched->mutex) { - ftdm_mutex_destroy(&newsched->mutex); - } - ftdm_safe_free(newsched); - } - return FTDM_FAIL; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_run(ftdm_sched_t *sched) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_timer_t *runtimer; - ftdm_timer_t *timer; - ftdm_sched_callback_t callback; - int ms = 0; - int rc = -1; - void *data; - struct timeval now; - - ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n"); - -tryagain: - - ftdm_mutex_lock(sched->mutex); - - rc = gettimeofday(&now, NULL); - if (rc == -1) { - ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n"); - goto done; - } - - timer = sched->timers; - while (timer) { - runtimer = timer; - timer = runtimer->next; - - ms = ((runtimer->time.tv_sec - now.tv_sec) * 1000) + - ((runtimer->time.tv_usec - now.tv_usec) / 1000); - - if (ms <= 0) { - - if (runtimer == sched->timers) { - sched->timers = runtimer->next; - if (sched->timers) { - sched->timers->prev = NULL; - } - } - - callback = runtimer->callback; - data = runtimer->usrdata; - if (runtimer->next) { - runtimer->next->prev = runtimer->prev; - } - if (runtimer->prev) { - runtimer->prev->next = runtimer->next; - } - - runtimer->id = 0; - ftdm_safe_free(runtimer); - - /* avoid deadlocks by releasing the sched lock before triggering callbacks */ - ftdm_mutex_unlock(sched->mutex); - - callback(data); - /* after calling a callback we must start the scanning again since the - * callback or some other thread may have added or cancelled timers to - * the linked list */ - goto tryagain; - } - } - - status = FTDM_SUCCESS; -done: - ftdm_mutex_unlock(sched->mutex); - ftdm_unused_arg(sched); - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, - int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timerid) -{ - ftdm_status_t status = FTDM_FAIL; - struct timeval now; - int rc = 0; - ftdm_timer_t *newtimer; - - ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n"); - ftdm_assert_return(name != NULL, FTDM_EINVAL, "timer name is null!\n"); - ftdm_assert_return(callback != NULL, FTDM_EINVAL, "sched callback is null!\n"); - ftdm_assert_return(ms > 0, FTDM_EINVAL, "milliseconds must be bigger than 0!\n"); - - if (timerid) { - *timerid = 0; - } - - rc = gettimeofday(&now, NULL); - if (rc == -1) { - ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n"); - return FTDM_FAIL; - } - - ftdm_mutex_lock(sched->mutex); - - newtimer = ftdm_calloc(1, sizeof(*newtimer)); - if (!newtimer) { - goto done; - } - newtimer->id = sched->currid; - sched->currid++; - if (!sched->currid) { - ftdm_log(FTDM_LOG_NOTICE, "Timer id wrap around for sched %s\n", sched->name); - /* we do not want currid to be zero since is an invalid id - * TODO: check that currid does not exists already in the context, it'd be insane - * though, having a timer to live all that time */ - sched->currid++; - } - - ftdm_set_string(newtimer->name, name); - newtimer->callback = callback; - newtimer->usrdata = data; - - newtimer->time.tv_sec = now.tv_sec + (ms / 1000); - newtimer->time.tv_usec = now.tv_usec + (ms % 1000) * 1000; - if (newtimer->time.tv_usec >= FTDM_MICROSECONDS_PER_SECOND) { - newtimer->time.tv_sec += 1; - newtimer->time.tv_usec -= FTDM_MICROSECONDS_PER_SECOND; - } - - if (!sched->timers) { - sched->timers = newtimer; - } else { - newtimer->next = sched->timers; - sched->timers->prev = newtimer; - sched->timers = newtimer; - } - - if (timerid) { - *timerid = newtimer->id; - } - - status = FTDM_SUCCESS; -done: - ftdm_mutex_unlock(sched->mutex); - ftdm_unused_arg(sched); - ftdm_unused_arg(name); - ftdm_unused_arg(ms); - ftdm_unused_arg(callback); - ftdm_unused_arg(data); - ftdm_unused_arg(timerid); - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_get_time_to_next_timer(const ftdm_sched_t *sched, int32_t *timeto) -{ - ftdm_status_t status = FTDM_FAIL; - int res = -1; - int ms = 0; - struct timeval currtime; - ftdm_timer_t *current = NULL; - ftdm_timer_t *winner = NULL; - - /* forever by default */ - *timeto = -1; - - ftdm_mutex_lock(sched->mutex); - - res = gettimeofday(&currtime, NULL); - if (-1 == res) { - ftdm_log(FTDM_LOG_ERROR, "Failed to get next event time\n"); - goto done; - } - status = FTDM_SUCCESS; - current = sched->timers; - while (current) { - /* if no winner, set this as winner */ - if (!winner) { - winner = current; - } - current = current->next; - /* if no more timers, return the winner */ - if (!current) { - ms = (((winner->time.tv_sec - currtime.tv_sec) * 1000) + - ((winner->time.tv_usec - currtime.tv_usec) / 1000)); - - /* if the timer is expired already, return 0 to attend immediately */ - if (ms < 0) { - *timeto = 0; - break; - } - *timeto = ms; - break; - } - - /* if the winner timer is after the current timer, then we have a new winner */ - if (winner->time.tv_sec > current->time.tv_sec - || (winner->time.tv_sec == current->time.tv_sec && - winner->time.tv_usec > current->time.tv_usec)) { - winner = current; - } - } - -done: - ftdm_mutex_unlock(sched->mutex); - ftdm_unused_arg(timeto); - ftdm_unused_arg(sched); - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timerid) -{ - ftdm_status_t status = FTDM_FAIL; - ftdm_timer_t *timer; - - ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n"); - - if (!timerid) { - return FTDM_SUCCESS; - } - - ftdm_mutex_lock(sched->mutex); - - /* look for the timer and destroy it */ - for (timer = sched->timers; timer; timer = timer->next) { - if (timer->id == timerid) { - if (timer == sched->timers) { - /* it's the head timer, put a new head */ - sched->timers = timer->next; - } - if (timer->prev) { - timer->prev->next = timer->next; - } - if (timer->next) { - timer->next->prev = timer->prev; - } - ftdm_safe_free(timer); - status = FTDM_SUCCESS; - break; - } - } - - ftdm_mutex_unlock(sched->mutex); - - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_sched_destroy(ftdm_sched_t **insched) -{ - ftdm_sched_t *sched = NULL; - ftdm_timer_t *timer; - ftdm_timer_t *deltimer; - ftdm_assert_return(insched != NULL, FTDM_EINVAL, "sched is null!\n"); - ftdm_assert_return(*insched != NULL, FTDM_EINVAL, "sched is null!\n"); - - sched = *insched; - - /* since destroying a sched may affect the global list, we gotta check */ - ftdm_mutex_lock(sched_globals.mutex); - - /* if we're head, replace head with our next (whatever our next is, even null will do) */ - if (sched == sched_globals.freeruns) { - sched_globals.freeruns = sched->next; - } - /* if we have a previous member (then we were not head) set our previous next to our next */ - if (sched->prev) { - sched->prev->next = sched->next; - } - /* if we have a next then set their prev to our prev (if we were head prev will be null and sched->next is already the new head) */ - if (sched->next) { - sched->next->prev = sched->prev; - } - - ftdm_mutex_unlock(sched_globals.mutex); - - /* now grab the sched mutex */ - ftdm_mutex_lock(sched->mutex); - - timer = sched->timers; - while (timer) { - deltimer = timer; - timer = timer->next; - ftdm_safe_free(deltimer); - } - - ftdm_log(FTDM_LOG_DEBUG, "Destroying schedule %s\n", sched->name); - - ftdm_mutex_unlock(sched->mutex); - - ftdm_mutex_destroy(&sched->mutex); - - ftdm_safe_free(sched); - - *insched = NULL; - return FTDM_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c deleted file mode 100644 index f6bc0ef4c4..0000000000 --- a/libs/freetdm/src/ftdm_state.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "private/ftdm_core.h" - -FTDM_ENUM_NAMES(CHANNEL_STATE_NAMES, CHANNEL_STATE_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t, CHANNEL_STATE_NAMES, FTDM_CHANNEL_STATE_INVALID) - -FTDM_ENUM_NAMES(CHANNEL_STATE_STATUS_NAMES, CHANNEL_STATE_STATUS_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_state_status, ftdm_state_status2str, ftdm_state_status_t, CHANNEL_STATE_STATUS_NAMES, FTDM_STATE_STATUS_INVALID) - -static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int waitrq); - -FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *func, int line, ftdm_channel_t *fchan) -{ - uint8_t hindex = 0; - ftdm_time_t diff = 0; - ftdm_channel_state_t state = fchan->state; - -#if 0 - /* I could not perform this sanity check without more disruptive changes. Ideally we should check here if the signaling module completing the state - executed a state processor (called ftdm_channel_advance_states() which call fchan->span->state_processor(fchan)) for the state. That is just a - sanity check, as in the past we had at least one bug where the signaling module set the state and then accidentally changed the state to a new one - without calling ftdm_channel_advance_states(), meaning the state processor for the first state was not executed and that lead to unexpected behavior. - - If we want to be able to perform this kind of sanity check it would be nice to add a new state status (FTDM_STATE_STATUS_PROCESSING), the function - ftdm_channel_advance_states() would set the state_status to PROCESSING and then the check below for STATUS_NEW would be valid. Currently is not - valid because the signaling module may be completing the state at the end of the state_processor callback and therefore the state will still be - in STATUS_NEW, and is perfectly valid ... */ - - if (fchan->state_status == FTDM_STATE_STATUS_NEW) { - ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_CRIT, - "Asking to complete state change from %s to %s in %llums, but the state is still unprocessed (this might be a bug!)\n", - ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff); - } -#endif - - if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) { - ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL, "State change flag set but state is already completed\n"); - return FTDM_SUCCESS; - } - - ftdm_usrmsg_free(&fchan->usrmsg); - - ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE); - - if (state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); - } else if (state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { - ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); - ftdm_test_and_set_media(fchan); - } else if (state == FTDM_CHANNEL_STATE_UP) { - ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); - ftdm_set_flag(fchan, FTDM_CHANNEL_ANSWERED); - ftdm_test_and_set_media(fchan); - } else if (state == FTDM_CHANNEL_STATE_DIALING) { - ftdm_sigmsg_t msg; - memset(&msg, 0, sizeof(msg)); - msg.channel = fchan; - msg.event_id = FTDM_SIGEVENT_DIALING; - ftdm_span_send_signal(fchan->span, &msg); - } else if (state == FTDM_CHANNEL_STATE_HANGUP) { - ftdm_set_echocancel_call_end(fchan); - } - - /* MAINTENANCE WARNING - * we're assuming an indication performed - * via state change will involve a single state change */ - ftdm_ack_indication(fchan, fchan->indication, FTDM_SUCCESS); - - hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1); - - ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n"); - - fchan->history[hindex].end_time = ftdm_current_time_in_ms(); - fchan->last_state_change_time = ftdm_current_time_in_ms(); - - fchan->state_status = FTDM_STATE_STATUS_COMPLETED; - - diff = fchan->history[hindex].end_time - fchan->history[hindex].time; - - ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %"FTDM_TIME_FMT" ms\n", - ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff); - - - if (ftdm_test_flag(fchan, FTDM_CHANNEL_BLOCKING)) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_BLOCKING); - ftdm_interrupt_signal(fchan->state_completed_interrupt); - } - - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) _ftdm_set_state(const char *file, const char *func, int line, - ftdm_channel_t *fchan, ftdm_channel_state_t state) -{ - if (fchan->state_status != FTDM_STATE_STATUS_COMPLETED) { - /* the current state is not completed, setting a new state from a signaling module - when the current state is not completed is equivalent to implicitly acknowledging - the current state */ - _ftdm_channel_complete_state(file, func, line, fchan); - } - return ftdm_core_set_state(file, func, line, fchan, state, 0); -} - -static int ftdm_parse_state_map(ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, ftdm_state_map_t *state_map) -{ - int x = 0, ok = 0; - ftdm_state_direction_t direction = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? ZSD_OUTBOUND : ZSD_INBOUND; - - for(x = 0; x < FTDM_MAP_NODE_SIZE; x++) { - int i = 0, proceed = 0; - if (!state_map->nodes[x].type) { - break; - } - - if (state_map->nodes[x].direction != direction) { - continue; - } - - if (state_map->nodes[x].check_states[0] == FTDM_CHANNEL_STATE_ANY) { - proceed = 1; - } else { - for(i = 0; i < FTDM_MAP_MAX; i++) { - if (state_map->nodes[x].check_states[i] == ftdmchan->state) { - proceed = 1; - break; - } - } - } - - if (!proceed) { - continue; - } - - for(i = 0; i < FTDM_MAP_MAX; i++) { - ok = (state_map->nodes[x].type == ZSM_ACCEPTABLE); - if (state_map->nodes[x].states[i] == FTDM_CHANNEL_STATE_END) { - break; - } - if (state_map->nodes[x].states[i] == state) { - ok = !ok; - goto end; - } - } - } - end: - - return ok; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_cancel_state(const char *file, const char *func, int line, ftdm_channel_t *fchan) -{ - ftdm_time_t diff; - ftdm_channel_state_t state; - ftdm_channel_state_t last_state; - uint8_t hindex = 0; - - if (!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Cannot cancel state change from %s to %s, it was already processed\n", - ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(fchan->state)); - return FTDM_FAIL; - } - - if (fchan->state_status != FTDM_STATE_STATUS_NEW) { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Failed to cancel state change from %s to %s, state is not new anymore\n", - ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(fchan->state)); - return FTDM_FAIL; - } - - /* compute the last history index */ - hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1); - diff = fchan->history[hindex].end_time - fchan->history[hindex].time; - - /* go back in time and revert the state to the previous state */ - state = fchan->state; - last_state = fchan->last_state; - - fchan->state = fchan->last_state; - fchan->state_status = FTDM_STATE_STATUS_COMPLETED; - fchan->last_state = fchan->history[hindex].last_state; - fchan->hindex = hindex; - - /* clear the state change flag */ - ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE); - - /* ack any pending indications as cancelled */ - ftdm_ack_indication(fchan, fchan->indication, FTDM_ECANCELED); - - /* wake up anyone sleeping waiting for the state change to complete, it won't ever be completed */ - if (ftdm_test_flag(fchan, FTDM_CHANNEL_BLOCKING)) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_BLOCKING); - ftdm_interrupt_signal(fchan->state_completed_interrupt); - } - - /* NOTE - * we could potentially also take out the channel from the pendingchans queue, but I believe is easier just leave it, - * the only side effect will be a call to ftdm_channel_advance_states() for a channel that has nothing to advance */ - ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Cancelled state change from %s to %s in %"FTDM_TIME_FMT" ms\n", - ftdm_channel_state2str(last_state), ftdm_channel_state2str(state), diff); - - return FTDM_SUCCESS; -} - - -FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int waitrq, ftdm_usrmsg_t *usrmsg) -{ - ftdm_channel_save_usrmsg(ftdmchan, usrmsg); - - if (ftdm_core_set_state(file, func, line, ftdmchan, state, waitrq) != FTDM_SUCCESS) { - ftdm_usrmsg_free(&ftdmchan->usrmsg); - } - return FTDM_SUCCESS; -} - -/* this function MUST be called with the channel lock held. If waitrq == 1, the channel will be unlocked/locked (never call it with waitrq == 1 with an lock recursivity > 1) */ -#define DEFAULT_WAIT_TIME 1000 -static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int waitrq) -{ - ftdm_status_t status; - int ok = 1; - int waitms = DEFAULT_WAIT_TIME; - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY)) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR, "Ignored state change request from %s to %s, the channel is not ready\n", - ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); - return FTDM_FAIL; - } - - if (ftdmchan->state_status != FTDM_STATE_STATUS_COMPLETED) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR, - "Ignored state change request from %s to %s, the previous state change has not been processed yet (status = %s)\n", - ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state), - ftdm_state_status2str(ftdmchan->state_status)); - return FTDM_FAIL; - } - - if (ftdmchan->state == state) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Why bother changing state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); - return FTDM_FAIL; - } - - if (!ftdmchan->state_completed_interrupt) { - status = ftdm_interrupt_create(&ftdmchan->state_completed_interrupt, FTDM_INVALID_SOCKET, FTDM_NO_FLAGS); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_CRIT, - "Failed to create state change interrupt when moving from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); - return status; - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { - goto perform_state_change; - } - - if (ftdmchan->span->state_map) { - ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map); - goto end; - } - - /* basic core state validation (by-passed if the signaling module provides a state_map) */ - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_TERMINATING: - { - ok = 0; - switch(state) { - case FTDM_CHANNEL_STATE_DOWN: - case FTDM_CHANNEL_STATE_BUSY: - case FTDM_CHANNEL_STATE_RESTART: - ok = 1; - break; - default: - break; - } - } - break; - case FTDM_CHANNEL_STATE_UP: - { - ok = 1; - switch(state) { - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_RING: - ok = 0; - break; - default: - break; - } - } - break; - case FTDM_CHANNEL_STATE_DOWN: - { - ok = 0; - - switch(state) { - case FTDM_CHANNEL_STATE_DIALTONE: - case FTDM_CHANNEL_STATE_COLLECT: - case FTDM_CHANNEL_STATE_DIALING: - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_IDLE: - case FTDM_CHANNEL_STATE_GET_CALLERID: - case FTDM_CHANNEL_STATE_GENRING: - ok = 1; - break; - default: - break; - } - } - break; - case FTDM_CHANNEL_STATE_BUSY: - { - switch(state) { - case FTDM_CHANNEL_STATE_UP: - ok = 0; - break; - default: - break; - } - } - break; - case FTDM_CHANNEL_STATE_RING: - { - switch(state) { - case FTDM_CHANNEL_STATE_UP: - ok = 1; - break; - default: - break; - } - } - break; - default: - break; - } - -end: - - if (!ok) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "VETO state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); - goto done; - } - -perform_state_change: - - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); - ftdmchan->last_state = ftdmchan->state; - ftdmchan->state = state; - ftdmchan->state_status = FTDM_STATE_STATUS_NEW; - ftdmchan->history[ftdmchan->hindex].file = file; - ftdmchan->history[ftdmchan->hindex].func = func; - ftdmchan->history[ftdmchan->hindex].line = line; - ftdmchan->history[ftdmchan->hindex].state = ftdmchan->state; - ftdmchan->history[ftdmchan->hindex].last_state = ftdmchan->last_state; - ftdmchan->history[ftdmchan->hindex].time = ftdm_current_time_in_ms(); - ftdmchan->history[ftdmchan->hindex].end_time = 0; - ftdmchan->hindex++; - if (ftdmchan->hindex == ftdm_array_len(ftdmchan->history)) { - ftdmchan->hindex = 0; - } - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE); - - if (ftdmchan->span->pendingchans) { - ftdm_queue_enqueue(ftdmchan->span->pendingchans, ftdmchan); - } else { - /* there is a potential deadlock here, if a signaling module is processing - * state changes while the ftdm_span_stop() function is called, the signaling - * thread will block until it can acquire the span lock, but the thread calling - * ftdm_span_stop() which holds the span lock is waiting on the signaling thread - * to finish ... The only reason to acquire the span lock is this flag, new - * signaling modules should use the pendingchans queue instead of this flag, - * as of today a few modules need still to be updated before we can get rid of - * this flag (ie, ftmod_libpri, ftmod_isdn, ftmod_analog) */ - ftdm_set_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE); - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) { - /* the channel should not block waiting for state processing */ - goto done; - } - - if (!waitrq) { - /* no waiting was requested */ - goto done; - } - - /* let's wait for the state change to be completed by the signaling stack */ - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_BLOCKING); - - ftdm_mutex_unlock(ftdmchan->mutex); - - status = ftdm_interrupt_wait(ftdmchan->state_completed_interrupt, waitms); - - ftdm_mutex_lock(ftdmchan->mutex); - - if (status != FTDM_SUCCESS) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_BLOCKING); - ftdm_log_chan_ex(ftdmchan, file, func, line, - FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not completed after aprox %dms\n", - ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME); - ok = 0; - goto done; - } -done: - return ok ? FTDM_SUCCESS : FTDM_FAIL; -} - -FT_DECLARE(int) ftdm_channel_get_state(const ftdm_channel_t *ftdmchan) -{ - int state; - ftdm_channel_lock(ftdmchan); - state = ftdmchan->state; - ftdm_channel_unlock(ftdmchan); - return state; -} - -FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *ftdmchan) -{ - const char *state; - ftdm_channel_lock(ftdmchan); - state = ftdm_channel_state2str(ftdmchan->state); - ftdm_channel_unlock(ftdmchan); - return state; -} - -FT_DECLARE(int) ftdm_channel_get_last_state(const ftdm_channel_t *ftdmchan) -{ - int last_state; - ftdm_channel_lock(ftdmchan); - last_state = ftdmchan->last_state; - ftdm_channel_unlock(ftdmchan); - return last_state; -} - -FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *ftdmchan) -{ - const char *state; - ftdm_channel_lock(ftdmchan); - state = ftdm_channel_state2str(ftdmchan->last_state); - ftdm_channel_unlock(ftdmchan); - return state; -} - -static void write_history_entry(const ftdm_channel_t *fchan, ftdm_stream_handle_t *stream, int i, ftdm_time_t *prevtime) -{ - char func[255]; - char line[255]; - char states[255]; - const char *filename = NULL; - snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); - snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); - filename = strrchr(fchan->history[i].file, *FTDM_PATH_SEPARATOR); - if (!filename) { - filename = fchan->history[i].file; - } else { - filename++; - } - if (!(*prevtime)) { - *prevtime = fchan->history[i].time; - } - snprintf(line, sizeof(func), "[%s:%d]", filename, fchan->history[i].line); - stream->write_function(stream, "%-30.30s %-30.30s %-30.30s %lums\n", states, func, line, (fchan->history[i].time - *prevtime)); - *prevtime = fchan->history[i].time; -} - -FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) -{ - uint8_t i = 0; - ftdm_time_t currtime = 0; - ftdm_time_t prevtime = 0; - - ftdm_stream_handle_t stream = { 0 }; - FTDM_STANDARD_STREAM(stream); - if (!fchan->history[0].file) { - stream.write_function(&stream, "-- No state history --\n"); - return stream.data; - } - - stream.write_function(&stream, "%-30.30s %-30.30s %-30.30s %s", - "-- States --", "-- Function --", "-- Location --", "-- Time Offset --\n"); - - for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) { - if (!fchan->history[i].file) { - break; - } - write_history_entry(fchan, &stream, i, &prevtime); - } - - for (i = 0; i < fchan->hindex; i++) { - write_history_entry(fchan, &stream, i, &prevtime); - } - - currtime = ftdm_current_time_in_ms(); - - stream.write_function(&stream, "\nTime since last state change: %lums\n", (currtime - prevtime)); - - return stream.data; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan) -{ - ftdm_channel_state_t state; - - ftdm_assert_return(fchan->span->state_processor, FTDM_FAIL, "Cannot process states without a state processor!\n"); - - while (fchan->state_status == FTDM_STATE_STATUS_NEW) { - state = fchan->state; - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Executing state processor for %s\n", ftdm_channel_state2str(fchan->state)); - fchan->span->state_processor(fchan); - if (state == fchan->state && fchan->state_status == FTDM_STATE_STATUS_NEW) { - /* if the state did not change and is still NEW, the state status must go to PROCESSED - * otherwise we don't touch it since is a new state and the old state was - * already completed implicitly by the state_processor() function via some internal - * call to ftdm_set_state() */ - fchan->state_status = FTDM_STATE_STATUS_PROCESSED; - } - } - - return FTDM_SUCCESS; -} - -FT_DECLARE(int) ftdm_check_state_all(ftdm_span_t *span, ftdm_channel_state_t state) -{ - uint32_t j; - for(j = 1; j <= span->chan_count; j++) { - if (span->channels[j]->state != state || ftdm_test_flag(span->channels[j], FTDM_CHANNEL_STATE_CHANGE)) { - return 0; - } - } - return 1; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_threadmutex.c b/libs/freetdm/src/ftdm_threadmutex.c deleted file mode 100644 index 6dc2c64f8f..0000000000 --- a/libs/freetdm/src/ftdm_threadmutex.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Cross Platform Thread/Mutex abstraction - * Copyright(C) 2007 Michael Jerris - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so. - * - * This work is provided under this license on an "as is" basis, without warranty of any kind, - * either expressed or implied, including, without limitation, warranties that the covered code - * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire - * risk as to the quality and performance of the covered code is with you. Should any covered - * code prove defective in any respect, you (not the initial developer or any other contributor) - * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty - * constitutes an essential part of this license. No use of any covered code is authorized hereunder - * except under this disclaimer. - * - * Contributors: - * - * Moises Silva - * - */ - -#ifdef WIN32 -# if (_WIN32_WINNT < 0x0400) -# error "Need to target at least Windows 95/WINNT 4.0 because TryEnterCriticalSection is needed" -# endif -# include -#endif -/*#define FTDM_DEBUG_MUTEX 0*/ - -#include "private/ftdm_core.h" -#include "ftdm_threadmutex.h" - -#ifdef WIN32 -#include - -#define FTDM_THREAD_CALLING_CONVENTION __stdcall - -struct ftdm_mutex { - CRITICAL_SECTION mutex; -}; - -#else -#include -#include - -#define FTDM_THREAD_CALLING_CONVENTION - -#ifdef FTDM_DEBUG_MUTEX -#define FTDM_MUTEX_MAX_REENTRANCY 30 -typedef struct ftdm_lock_entry { - const char *file; - const char *func; - uint32_t line; -} ftdm_lock_entry_t; - -typedef struct ftdm_lock_history { - ftdm_lock_entry_t locked; - ftdm_lock_entry_t unlocked; -} ftdm_lock_history_t; -#endif - -struct ftdm_mutex { - pthread_mutex_t mutex; -#ifdef FTDM_DEBUG_MUTEX - ftdm_lock_history_t lock_history[FTDM_MUTEX_MAX_REENTRANCY]; - uint8_t reentrancy; -#endif -}; - -#endif - -struct ftdm_interrupt { - ftdm_socket_t device; - ftdm_wait_flag_t device_input_flags; - ftdm_wait_flag_t device_output_flags; -#ifdef WIN32 - /* for generic interruption */ - HANDLE event; -#else - /* In theory we could be using thread conditions for generic interruption, - * however, Linux does not have a primitive like Windows WaitForMultipleObjects - * to wait for both thread condition and file descriptors, therefore we decided - * to use a dummy pipe for generic interruption/condition logic - * */ - int readfd; - int writefd; -#endif -}; - -struct ftdm_thread { -#ifdef WIN32 - void *handle; -#else - pthread_t handle; -#endif - void *private_data; - ftdm_thread_function_t function; - ftdm_size_t stack_size; -#ifndef WIN32 - pthread_attr_t attribute; -#endif -}; - -ftdm_size_t thread_default_stacksize = 0; - -FT_DECLARE(void) ftdm_thread_override_default_stacksize(ftdm_size_t size) -{ - thread_default_stacksize = size; -} - -static void * FTDM_THREAD_CALLING_CONVENTION thread_launch(void *args) -{ - void *exit_val; - ftdm_thread_t *thread = (ftdm_thread_t *)args; - exit_val = thread->function(thread, thread->private_data); -#ifndef WIN32 - pthread_attr_destroy(&thread->attribute); -#endif - ftdm_safe_free(thread); - - return exit_val; -} - -FT_DECLARE(ftdm_status_t) ftdm_thread_create_detached(ftdm_thread_function_t func, void *data) -{ - return ftdm_thread_create_detached_ex(func, data, thread_default_stacksize); -} - -FT_DECLARE(ftdm_status_t) ftdm_thread_create_detached_ex(ftdm_thread_function_t func, void *data, ftdm_size_t stack_size) -{ - ftdm_thread_t *thread = NULL; - ftdm_status_t status = FTDM_FAIL; - - if (!func || !(thread = (ftdm_thread_t *)ftdm_calloc(1, sizeof(ftdm_thread_t)))) { - goto done; - } - - thread->private_data = data; - thread->function = func; - thread->stack_size = stack_size; - -#if defined(WIN32) - thread->handle = (void *)_beginthreadex(NULL, (unsigned)thread->stack_size, (unsigned int (__stdcall *)(void *))thread_launch, thread, 0, NULL); - if (!thread->handle) { - goto fail; - } - CloseHandle(thread->handle); - - status = FTDM_SUCCESS; - goto done; -#else - - if (pthread_attr_init(&thread->attribute) != 0) goto fail; - - if (pthread_attr_setdetachstate(&thread->attribute, PTHREAD_CREATE_DETACHED) != 0) goto failpthread; - - if (thread->stack_size && pthread_attr_setstacksize(&thread->attribute, thread->stack_size) != 0) goto failpthread; - - if (pthread_create(&thread->handle, &thread->attribute, thread_launch, thread) != 0) goto failpthread; - - status = FTDM_SUCCESS; - goto done; - failpthread: - pthread_attr_destroy(&thread->attribute); -#endif - - fail: - if (thread) { - ftdm_safe_free(thread); - } - done: - return status; -} - - -FT_DECLARE(ftdm_status_t) ftdm_mutex_create(ftdm_mutex_t **mutex) -{ - ftdm_status_t status = FTDM_FAIL; -#ifndef WIN32 - pthread_mutexattr_t attr; -#endif - ftdm_mutex_t *check = NULL; - - check = (ftdm_mutex_t *)ftdm_calloc(1, sizeof(**mutex)); - if (!check) - goto done; -#ifdef WIN32 - InitializeCriticalSection(&check->mutex); -#else - if (pthread_mutexattr_init(&attr)) - goto done; - - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) - goto fail; - - if (pthread_mutex_init(&check->mutex, &attr)) - goto fail; - - goto success; - - fail: - pthread_mutexattr_destroy(&attr); - goto done; - - success: -#endif - *mutex = check; - status = FTDM_SUCCESS; - - done: - return status; -} - -FT_DECLARE(ftdm_status_t) ftdm_mutex_destroy(ftdm_mutex_t **mutex) -{ - ftdm_mutex_t *mp = *mutex; - *mutex = NULL; - if (!mp) { - return FTDM_FAIL; - } -#ifdef WIN32 - DeleteCriticalSection(&mp->mutex); -#else - if (pthread_mutex_destroy(&mp->mutex)) - return FTDM_FAIL; -#endif - ftdm_safe_free(mp); - return FTDM_SUCCESS; -} - -#define ADD_LOCK_HISTORY(mutex, file, line, func) \ - { \ - if ((mutex)->reentrancy < FTDM_MUTEX_MAX_REENTRANCY) { \ - (mutex)->lock_history[mutex->reentrancy].locked.file = (file); \ - (mutex)->lock_history[mutex->reentrancy].locked.func = (func); \ - (mutex)->lock_history[mutex->reentrancy].locked.line = (line); \ - (mutex)->lock_history[mutex->reentrancy].unlocked.file = NULL; \ - (mutex)->lock_history[mutex->reentrancy].unlocked.func = NULL; \ - (mutex)->lock_history[mutex->reentrancy].unlocked.line = 0; \ - (mutex)->reentrancy++; \ - if ((mutex)->reentrancy == FTDM_MUTEX_MAX_REENTRANCY) { \ - ftdm_log((file), (func), (line), FTDM_LOG_LEVEL_ERROR, "Max reentrancy reached for mutex %p\n", (mutex)); \ - } \ - } \ - } - -FT_DECLARE(ftdm_status_t) _ftdm_mutex_lock(const char *file, int line, const char *func, ftdm_mutex_t *mutex) -{ -#ifdef WIN32 - ftdm_unused_arg(file); - ftdm_unused_arg(line); - ftdm_unused_arg(func); - - EnterCriticalSection(&mutex->mutex); -#else - int err; - if ((err = pthread_mutex_lock(&mutex->mutex))) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "Failed to lock mutex %d:%s\n", err, strerror(err)); - return FTDM_FAIL; - } -#endif -#ifdef FTDM_DEBUG_MUTEX - ADD_LOCK_HISTORY(mutex, file, line, func); -#endif - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(const char *file, int line, const char *func, ftdm_mutex_t *mutex) -{ - ftdm_unused_arg(file); - ftdm_unused_arg(line); - ftdm_unused_arg(func); -#ifdef WIN32 - if (!TryEnterCriticalSection(&mutex->mutex)) - return FTDM_FAIL; -#else - if (pthread_mutex_trylock(&mutex->mutex)) - return FTDM_FAIL; -#endif -#ifdef FTDM_DEBUG_MUTEX - ADD_LOCK_HISTORY(mutex, file, line, func); -#endif - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const char *func, ftdm_mutex_t *mutex) -{ -#ifdef FTDM_DEBUG_MUTEX - int i = 0; - if (mutex->reentrancy == 0) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "Cannot unlock something that is not locked!\n"); - return FTDM_FAIL; - } - i = mutex->reentrancy - 1; - /* I think this is a fair assumption when debugging */ - if (func != mutex->lock_history[i].locked.func) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Mutex %p was suspiciously locked at %s->%s:%d but unlocked at %s->%s:%d!\n", - mutex, mutex->lock_history[i].locked.func, mutex->lock_history[i].locked.file, mutex->lock_history[i].locked.line, - func, file, line); - } - mutex->lock_history[i].unlocked.file = file; - mutex->lock_history[i].unlocked.line = line; - mutex->lock_history[i].unlocked.func = func; - mutex->reentrancy--; -#endif -#ifdef WIN32 - ftdm_unused_arg(file); - ftdm_unused_arg(line); - ftdm_unused_arg(func); - - LeaveCriticalSection(&mutex->mutex); -#else - if (pthread_mutex_unlock(&mutex->mutex)) { - ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "Failed to unlock mutex: %s\n", strerror(errno)); -#ifdef FTDM_DEBUG_MUTEX - mutex->reentrancy++; -#endif - return FTDM_FAIL; - } -#endif - return FTDM_SUCCESS; -} - - -FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device, ftdm_wait_flag_t device_flags) -{ - ftdm_status_t status = FTDM_SUCCESS; - ftdm_interrupt_t *interrupt = NULL; -#ifndef WIN32 - int fds[2]; -#endif - - ftdm_assert_return(ininterrupt != NULL, FTDM_FAIL, "interrupt double pointer is null!\n"); - - interrupt = ftdm_calloc(1, sizeof(*interrupt)); - if (!interrupt) { - ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt memory\n"); - return FTDM_ENOMEM; - } - - interrupt->device = device; - interrupt->device_input_flags = device_flags; -#ifdef WIN32 - interrupt->event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!interrupt->event) { - ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt event\n"); - status = FTDM_ENOMEM; - goto failed; - } -#else - if (pipe(fds)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt pipe: %s\n", strerror(errno)); - status = FTDM_FAIL; - goto failed; - } - interrupt->readfd = fds[0]; - interrupt->writefd = fds[1]; -#endif - - *ininterrupt = interrupt; - return FTDM_SUCCESS; - -failed: - if (interrupt) { -#ifndef WIN32 - if (interrupt->readfd) { - close(interrupt->readfd); - close(interrupt->writefd); - interrupt->readfd = -1; - interrupt->writefd = -1; - } -#endif - ftdm_safe_free(interrupt); - } - return status; -} - -#define ONE_BILLION 1000000000 - -FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int ms) -{ - int num = 1; -#ifdef WIN32 - DWORD res = 0; - HANDLE ints[2]; -#else - int res = 0; - struct pollfd ints[2]; - char pipebuf[255]; -#endif - - ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Interrupt is null!\n"); - - interrupt->device_output_flags = FTDM_NO_FLAGS; - /* start implementation */ -#ifdef WIN32 - ints[0] = interrupt->event; - if (interrupt->device != FTDM_INVALID_SOCKET) { - num++; - ints[1] = interrupt->device; - ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_output_flags member!)\n"); - } - res = WaitForMultipleObjects(num, ints, FALSE, ms >= 0 ? ms : INFINITE); - switch (res) { - case WAIT_TIMEOUT: - return FTDM_TIMEOUT; - case WAIT_FAILED: - case WAIT_ABANDONED: /* is it right to fail with abandoned? */ - return FTDM_FAIL; - default: - if (res >= (sizeof(ints)/sizeof(ints[0]))) { - ftdm_log(FTDM_LOG_ERROR, "Error waiting for freetdm interrupt event (WaitForSingleObject returned %d)\n", res); - return FTDM_FAIL; - } - return FTDM_SUCCESS; - } -#else -pollagain: - ints[0].fd = interrupt->readfd; - ints[0].events = POLLIN; - ints[0].revents = 0; - - if (interrupt->device != FTDM_INVALID_SOCKET) { - num++; - ints[1].fd = interrupt->device; - ints[1].events = interrupt->device_input_flags; - ints[1].revents = 0; - } - - res = poll(ints, num, ms); - - if (res == -1) { - if (errno == EINTR) { - goto pollagain; - } - ftdm_log(FTDM_LOG_CRIT, "interrupt poll failed (%s)\n", strerror(errno)); - return FTDM_FAIL; - } - - if (res == 0) { - return FTDM_TIMEOUT; - } - - if (ints[0].revents & POLLIN) { - res = read(ints[0].fd, pipebuf, sizeof(pipebuf)); - if (res == -1) { - ftdm_log(FTDM_LOG_CRIT, "reading interrupt descriptor failed (%s)\n", strerror(errno)); - } - } - if (interrupt->device != FTDM_INVALID_SOCKET) { - if (ints[1].revents & POLLIN) { - interrupt->device_output_flags |= FTDM_READ; - } - if (ints[1].revents & POLLOUT) { - interrupt->device_output_flags |= FTDM_WRITE; - } - if (ints[1].revents & POLLPRI) { - interrupt->device_output_flags |= FTDM_EVENTS; - } - } - return FTDM_SUCCESS; -#endif -} - -FT_DECLARE(ftdm_status_t) ftdm_interrupt_signal(ftdm_interrupt_t *interrupt) -{ - ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Interrupt is null!\n"); -#ifdef WIN32 - if (!SetEvent(interrupt->event)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt\n"); - return FTDM_FAIL; - - } -#else - int err; - struct pollfd testpoll; - testpoll.revents = 0; - testpoll.events = POLLIN; - testpoll.fd = interrupt->readfd; - err = poll(&testpoll, 1, 0); - if (err == 0 && !(testpoll.revents & POLLIN)) { - /* we just try to notify if there is nothing on the read fd already, - * otherwise users that never call interrupt wait eventually will - * eventually have the pipe buffer filled */ - if ((err = write(interrupt->writefd, "w", 1)) != 1) { - ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt: %s\n", strerror(errno)); - return FTDM_FAIL; - } - } -#endif - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **ininterrupt) -{ - ftdm_interrupt_t *interrupt = NULL; - ftdm_assert_return(ininterrupt != NULL, FTDM_FAIL, "Interrupt null when destroying!\n"); - interrupt = *ininterrupt; -#ifdef WIN32 - CloseHandle(interrupt->event); -#else - close(interrupt->readfd); - close(interrupt->writefd); - - interrupt->readfd = -1; - interrupt->writefd = -1; -#endif - ftdm_safe_free(interrupt); - *ininterrupt = NULL; - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interrupts[], ftdm_size_t size, int ms) -{ - int numdevices = 0; - unsigned i = 0; - -#if defined(__WINDOWS__) - DWORD res = 0; - HANDLE ints[20]; - if (size > (ftdm_array_len(ints)/2)) { - /* improve if needed: dynamically allocate the list of interrupts *only* when exceeding the default size */ - ftdm_log(FTDM_LOG_CRIT, "Unsupported size of interrupts: %d, implement me!\n", size); - return FTDM_FAIL; - } - - for (i = 0; i < size; i++) { - ints[i] = interrupts[i]->event; - interrupts[i]->device_output_flags = FTDM_NO_FLAGS; - if (interrupts[i]->device != FTDM_INVALID_SOCKET) { - /* WARNING: if the device is ready for data we must implement for Windows the device_output_flags member */ - ints[size+numdevices] = interrupts[i]->device; - numdevices++; - ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_data_ready member!)\n", size); - } - } - - res = WaitForMultipleObjects((DWORD)size+numdevices, ints, FALSE, ms >= 0 ? ms : INFINITE); - - switch (res) { - case WAIT_TIMEOUT: - return FTDM_TIMEOUT; - case WAIT_FAILED: - case WAIT_ABANDONED: /* is it right to fail with abandoned? */ - return FTDM_FAIL; - default: - if (res >= (size+numdevices)) { - ftdm_log(FTDM_LOG_ERROR, "Error waiting for freetdm interrupt event (WaitForSingleObject returned %d)\n", res); - return FTDM_FAIL; - } - /* fall-through to FTDM_SUCCESS at the end of the function */ - } -#elif defined(__linux__) || defined(__FreeBSD__) - int res = 0; - char pipebuf[255]; - struct pollfd ints[size*2]; - - memset(&ints, 0, sizeof(ints)); -pollagain: - for (i = 0; i < size; i++) { - ints[i].events = POLLIN; - ints[i].revents = 0; - ints[i].fd = interrupts[i]->readfd; - interrupts[i]->device_output_flags = FTDM_NO_FLAGS; - if (interrupts[i]->device != FTDM_INVALID_SOCKET) { - ints[size+numdevices].events = interrupts[i]->device_input_flags; - ints[size+numdevices].revents = 0; - ints[size+numdevices].fd = interrupts[i]->device; - numdevices++; - } - } - - res = poll(ints, size + numdevices, ms); - if (res == -1) { - if (errno == EINTR) { - goto pollagain; - } - ftdm_log(FTDM_LOG_CRIT, "interrupt poll failed (%s)\n", strerror(errno)); - return FTDM_FAIL; - } - - if (res == 0) { - return FTDM_TIMEOUT; - } - - /* check for events in the pipes and in the devices, but service only the pipes */ - numdevices = 0; - for (i = 0; i < size; i++) { - if (ints[i].revents & POLLIN) { - res = read(ints[i].fd, pipebuf, sizeof(pipebuf)); - if (res == -1) { - ftdm_log(FTDM_LOG_CRIT, "reading interrupt descriptor failed (%s)\n", strerror(errno)); - } - } - if (interrupts[i]->device != FTDM_INVALID_SOCKET) { - if (ints[size+numdevices].revents & POLLIN) { - interrupts[i]->device_output_flags |= FTDM_READ; - } - if (ints[size+numdevices].revents & POLLOUT) { - interrupts[i]->device_output_flags |= FTDM_WRITE; - } - if (ints[size+numdevices].revents & POLLPRI) { - interrupts[i]->device_output_flags |= FTDM_EVENTS; - } - numdevices++; - } - } -#else - /* for MacOS compilation, unused vars */ - numdevices = i; -#endif - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_wait_flag_t) ftdm_interrupt_device_ready(ftdm_interrupt_t *interrupt) -{ -#if defined(__WINDOWS__) - /* device output flags are not currently filled for Windows upon returning from a wait function */ - ftdm_log(FTDM_LOG_CRIT, "IMPLEMENT ME!\n"); -#endif - return interrupt->device_output_flags; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftdm_variables.c b/libs/freetdm/src/ftdm_variables.c deleted file mode 100644 index a2899c4ca9..0000000000 --- a/libs/freetdm/src/ftdm_variables.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * - */ - -#include "private/ftdm_core.h" - -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_add_var(ftdm_sigmsg_t *sigmsg, const char *var_name, const char *value) -{ - char *t_name = 0, *t_val = 0; - - if (!sigmsg || !var_name || !value) { - return FTDM_FAIL; - } - - if (!sigmsg->variables) { - /* initialize on first use */ - sigmsg->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - ftdm_assert_return(sigmsg->variables, FTDM_FAIL, "Failed to create hash table\n"); - } - - t_name = ftdm_strdup(var_name); - t_val = ftdm_strdup(value); - hashtable_insert(sigmsg->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_remove_var(ftdm_sigmsg_t *sigmsg, const char *var_name) -{ - if (sigmsg && sigmsg->variables) { - hashtable_remove(sigmsg->variables, (void *)var_name); - } - return FTDM_SUCCESS; -} - -FT_DECLARE(const char *) ftdm_sigmsg_get_var(ftdm_sigmsg_t *sigmsg, const char *var_name) -{ - const char *var = NULL; - - if (!sigmsg || !sigmsg->variables || !var_name) { - return NULL; - } - - var = (const char *)hashtable_search(((struct hashtable*)sigmsg->variables), (void *)var_name); - return var; -} - -FT_DECLARE(ftdm_iterator_t *) ftdm_sigmsg_get_var_iterator(const ftdm_sigmsg_t *sigmsg, ftdm_iterator_t *iter) -{ - ftdm_hash_iterator_t *hashiter = NULL; - if (!sigmsg) { - return NULL; - } - - hashiter = sigmsg->variables == NULL ? NULL : hashtable_first(sigmsg->variables); - - if (hashiter == NULL) { - return NULL; - } - - if (!(iter = ftdm_get_iterator(FTDM_ITERATOR_VARS, iter))) { - return NULL; - } - iter->pvt.hashiter = hashiter; - return iter; -} - -FT_DECLARE(ftdm_status_t) ftdm_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val) -{ - const void *key = NULL; - void *val = NULL; - - *var_name = NULL; - *var_val = NULL; - - ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_VARS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); - - hashtable_this(iter->pvt.hashiter, &key, NULL, &val); - - *var_name = key; - *var_val = val; - - return FTDM_SUCCESS; -} - - -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_add_var(ftdm_usrmsg_t *usrmsg, const char *var_name, const char *value) -{ - char *t_name = 0, *t_val = 0; - - if (!usrmsg || !var_name || !value) { - return FTDM_FAIL; - } - - if (!usrmsg->variables) { - /* initialize on first use */ - usrmsg->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - ftdm_assert_return(usrmsg->variables, FTDM_FAIL, "Failed to create hash table\n"); - } - - t_name = ftdm_strdup(var_name); - t_val = ftdm_strdup(value); - hashtable_insert(usrmsg->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); - return FTDM_SUCCESS; -} - -FT_DECLARE(const char *) ftdm_usrmsg_get_var(ftdm_usrmsg_t *usrmsg, const char *var_name) -{ - const char *var = NULL; - - if (!usrmsg || !usrmsg->variables || !var_name) { - return NULL; - } - - var = (const char *)hashtable_search(((struct hashtable*)usrmsg->variables), (void *)var_name); - return var; -} diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h b/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h deleted file mode 100644 index 2bc1717556..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FTDM_ANALOG_H -#define FTDM_ANALOG_H -#include "freetdm.h" - -typedef enum { - FTDM_ANALOG_RUNNING = (1 << 0), - FTDM_ANALOG_CALLERID = (1 << 1), - FTDM_ANALOG_ANSWER_POLARITY_REVERSE = (1 << 2), - FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3), - FTDM_ANALOG_POLARITY_CALLERID = (1 << 4) -} ftdm_analog_flag_t; - -#define FTDM_MAX_HOTLINE_STR 32 -#define MAX_DTMF 256 - -struct ftdm_analog_data { - uint32_t flags; - uint32_t max_dialstr; - uint32_t wait_dialtone_timeout; - uint32_t polarity_delay; - uint32_t digit_timeout; - char hotline[FTDM_MAX_HOTLINE_STR]; -}; - -/* Analog flags to be set in the sflags (signaling flags) channel memeber */ -#define AF_POLARITY_REVERSE (1 << 0) - -static void *ftdm_analog_run(ftdm_thread_t *me, void *obj); -typedef struct ftdm_analog_data ftdm_analog_data_t; - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2008.vcproj deleted file mode 100644 index 09349fc05f..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2008.vcproj +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2010.vcxproj.filters deleted file mode 100644 index b6fed5927a..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2010.vcxproj.filters +++ /dev/null @@ -1,23 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c deleted file mode 100644 index 065e12a0d0..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ /dev/null @@ -1,1270 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "private/ftdm_core.h" -#include "ftdm_analog.h" - -#ifndef localtime_r -struct tm * localtime_r(const time_t *clock, struct tm *result); -#endif - -static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj); - -/** - * \brief Starts an FXO channel thread (outgoing call) - * \param ftdmchan Channel to initiate call on - * \return Success or failure - * - * Initialises state, starts tone progress detection and runs the channel in a new a thread. - */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxo_outgoing_call) -{ - ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data; - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) { - ftdm_channel_clear_needed_tones(ftdmchan); - ftdm_channel_clear_detected_tones(ftdmchan); - - ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_PROGRESS_DETECT, NULL); - if (analog_data->wait_dialtone_timeout) { - ftdmchan->needed_tones[FTDM_TONEMAP_DIAL] = 1; - } - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING); - ftdm_thread_create_detached(ftdm_analog_channel_run, ftdmchan); - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -/** - * \brief Starts an FXS channel thread (outgoing call) - * \param ftdmchan Channel to initiate call on - * \return Success or failure - * - * Indicates call waiting if channel is already in use, otherwise runs the channel in a new thread. - */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxs_outgoing_call) -{ - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CALLWAITING); - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_GENRING); - ftdm_thread_create_detached(ftdm_analog_channel_run, ftdmchan); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Returns the signalling status on a channel - * \param ftdmchan Channel to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ - -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_get_channel_sig_status) -{ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) { - *status = FTDM_SIG_STATE_DOWN; - return FTDM_SUCCESS; - } - *status = FTDM_SIG_STATE_UP; - return FTDM_SUCCESS; -} - -/** - * \brief Returns the signalling status on a span - * \param span Span to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_get_span_sig_status) -{ - ftdm_iterator_t *citer = NULL; - ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL); - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - return FTDM_FAIL; - } - /* if ALL channels are in alarm, report DOWN, UP otherwise. */ - *status = FTDM_SIG_STATE_DOWN; - for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { - ftdm_channel_t *fchan = ftdm_iterator_current(citer); - ftdm_channel_lock(fchan); - if (!ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) { - *status = FTDM_SIG_STATE_UP; - ftdm_channel_unlock(fchan); - break; - } - ftdm_channel_unlock(fchan); - } - ftdm_iterator_free(chaniter); - return FTDM_SUCCESS; -} - -/** - * \brief Starts an analog span thread (monitor) - * \param span Span to monitor - * \return Success or failure - */ -static ftdm_status_t ftdm_analog_start(ftdm_span_t *span) -{ - ftdm_analog_data_t *analog_data = span->signal_data; - ftdm_set_flag(analog_data, FTDM_ANALOG_RUNNING); - return ftdm_thread_create_detached(ftdm_analog_run, span); -} - -/** - * \brief Stops the analog span thread (monitor) - * \param span Span to stop - * \return Success or failure - */ -static ftdm_status_t ftdm_analog_stop(ftdm_span_t *span) -{ - ftdm_analog_data_t *analog_data = span->signal_data; - int32_t sanity = 100; - while (ftdm_test_flag(analog_data, FTDM_ANALOG_RUNNING) && sanity--) { - ftdm_sleep(100); - ftdm_log(FTDM_LOG_DEBUG, "Waiting for analog thread for span %s to stop\n", span->name); - } - - if (!sanity) { - ftdm_log(FTDM_LOG_ERROR, "The analog thread for span %s is probably still running, we may crash :(\n", span->name); - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -/** - * \brief Initialises an analog span from configuration variables - * \param span Span to configure - * \param sig_cb Callback function for event signals - * \param ap List of configuration variables - * \return Success or failure - */ -static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span) -//ftdm_status_t ftdm_analog_configure_span(ftdm_span_t *span, char *tonemap, uint32_t digit_timeout, uint32_t max_dialstr, fio_signal_cb_t sig_cb) -{ - ftdm_analog_data_t *analog_data; - const char *tonemap = "us"; - const char *hotline = ""; - uint32_t digit_timeout = 10; - uint32_t wait_dialtone_timeout = 5000; - uint32_t max_dialstr = MAX_DTMF; - uint32_t polarity_delay = 600; - const char *var, *val; - int *intval; - uint32_t flags = FTDM_ANALOG_CALLERID; - int callwaiting = 1; - unsigned int i = 0; - - assert(sig_cb != NULL); - ftdm_log(FTDM_LOG_DEBUG, "Configuring span %s for analog signaling ...\n", span->name); - - if (span->signal_type) { - ftdm_log(FTDM_LOG_ERROR, "Span %s is already configured for signaling %d\n", span->name, span->signal_type); - snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling."); - return FTDM_FAIL; - } - - analog_data = ftdm_malloc(sizeof(*analog_data)); - - ftdm_assert_return(analog_data != NULL, FTDM_FAIL, "malloc failure\n"); - - memset(analog_data, 0, sizeof(*analog_data)); - - while ((var = va_arg(ap, char *))) { - ftdm_log(FTDM_LOG_DEBUG, "Analog config var = %s\n", var); - if (!strcasecmp(var, "tonemap")) { - if (!(val = va_arg(ap, char *))) { - break; - } - tonemap = val; - } else if (!strcasecmp(var, "digit_timeout")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - digit_timeout = *intval; - } else if (!strcasecmp(var, "wait_dialtone_timeout")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - wait_dialtone_timeout = ftdm_max(0, *intval); - ftdm_log(FTDM_LOG_DEBUG, "Wait dial tone ms = %d\n", wait_dialtone_timeout); - } else if (!strcasecmp(var, "enable_callerid")) { - if (!(val = va_arg(ap, char *))) { - break; - } - - if (ftdm_true(val)) { - flags |= FTDM_ANALOG_CALLERID; - } else { - flags &= ~FTDM_ANALOG_CALLERID; - } - } else if (!strcasecmp(var, "answer_polarity_reverse")) { - if (!(val = va_arg(ap, char *))) { - break; - } - if (ftdm_true(val)) { - flags |= FTDM_ANALOG_ANSWER_POLARITY_REVERSE; - } else { - flags &= ~FTDM_ANALOG_ANSWER_POLARITY_REVERSE; - } - } else if (!strcasecmp(var, "hangup_polarity_reverse")) { - if (!(val = va_arg(ap, char *))) { - break; - } - if (ftdm_true(val)) { - flags |= FTDM_ANALOG_HANGUP_POLARITY_REVERSE; - } else { - flags &= ~FTDM_ANALOG_HANGUP_POLARITY_REVERSE; - } - } else if (!strcasecmp(var, "polarity_delay")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - polarity_delay = *intval; - } else if (!strcasecmp(var, "callwaiting")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - callwaiting = *intval; - } else if (!strcasecmp(var, "max_dialstr")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - max_dialstr = *intval; - } else if (!strcasecmp(var, "hotline")) { - if (!(val = va_arg(ap, char *))) { - break; - } - hotline = val; - } else if (!strcasecmp(var, "polarity_callerid")) { - if (!(val = va_arg(ap, char *))) { - break; - } - if (ftdm_true(val)) { - flags |= FTDM_ANALOG_POLARITY_CALLERID; - } else { - flags &= ~FTDM_ANALOG_POLARITY_CALLERID; - } - } else { - ftdm_log(FTDM_LOG_ERROR, "Unknown parameter %s in span %s\n", var, span->name); - } - } - - if (digit_timeout < 2000 || digit_timeout > 10000) { - digit_timeout = 2000; - } - - if ((max_dialstr < 1 && !strlen(hotline)) || max_dialstr > MAX_DTMF) { - max_dialstr = MAX_DTMF; - } - - if (callwaiting) { - for (i = 1; i <= span->chan_count; i++) { - ftdm_log_chan_msg(span->channels[i], FTDM_LOG_DEBUG, "Enabled call waiting\n"); - ftdm_channel_set_feature(span->channels[i], FTDM_CHANNEL_FEATURE_CALLWAITING); - } - } - - span->start = ftdm_analog_start; - span->stop = ftdm_analog_stop; - analog_data->flags = flags; - analog_data->digit_timeout = digit_timeout; - analog_data->wait_dialtone_timeout = wait_dialtone_timeout; - analog_data->polarity_delay = polarity_delay; - analog_data->max_dialstr = max_dialstr; - span->signal_cb = sig_cb; - strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline)); - span->signal_type = FTDM_SIGTYPE_ANALOG; - span->signal_data = analog_data; - span->outgoing_call = span->trunk_type == FTDM_TRUNK_FXS ? analog_fxs_outgoing_call : analog_fxo_outgoing_call; - span->get_channel_sig_status = analog_get_channel_sig_status; - span->get_span_sig_status = analog_get_span_sig_status; - - ftdm_span_load_tones(span, tonemap); - - ftdm_log(FTDM_LOG_DEBUG, "Configuration of analog signaling for span %s is done\n", span->name); - return FTDM_SUCCESS; - -} - -/** - * \brief Retrieves tone generation output to be sent - * \param ts Teletone generator - * \param map Tone map - * \return -1 on error, 0 on success - */ -static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map) -{ - ftdm_buffer_t *dt_buffer = ts->user_data; - int wrote; - - if (!dt_buffer) { - return -1; - } - wrote = teletone_mux_tones(ts, map); - ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2); - return 0; -} - -/** - * \brief Sends caller id on an analog channel (FSK coded) - * \param ftdmchan Channel to send caller id on - */ -static void send_caller_id(ftdm_channel_t *ftdmchan) -{ - ftdm_fsk_data_state_t fsk_data; - uint8_t databuf[1024] = ""; - char time_str[9]; - struct tm tm; - time_t now; - ftdm_mdmf_type_t mt = MDMF_INVALID; - - time(&now); -#ifdef WIN32 - _tzset(); - _localtime64_s(&tm, &now); -#else - localtime_r(&now, &tm); -#endif - strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm); - - ftdm_fsk_data_init(&fsk_data, databuf, sizeof(databuf)); - ftdm_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *) time_str, 8); - - if (ftdm_strlen_zero(ftdmchan->caller_data.cid_num.digits)) { - mt = MDMF_NO_NUM; - ftdm_set_string(ftdmchan->caller_data.cid_num.digits, "O"); - } else if (!strcasecmp(ftdmchan->caller_data.cid_num.digits, "P") || !strcasecmp(ftdmchan->caller_data.cid_num.digits, "O")) { - mt = MDMF_NO_NUM; - } else { - mt = MDMF_PHONE_NUM; - } - ftdm_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) ftdmchan->caller_data.cid_num.digits, (uint8_t)strlen(ftdmchan->caller_data.cid_num.digits)); - - if (ftdm_strlen_zero(ftdmchan->caller_data.cid_name)) { - mt = MDMF_NO_NAME; - ftdm_set_string(ftdmchan->caller_data.cid_name, "O"); - } else if (!strcasecmp(ftdmchan->caller_data.cid_name, "P") || !strcasecmp(ftdmchan->caller_data.cid_name, "O")) { - mt = MDMF_NO_NAME; - } else { - mt = MDMF_PHONE_NAME; - } - ftdm_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) ftdmchan->caller_data.cid_name, (uint8_t)strlen(ftdmchan->caller_data.cid_name)); - - ftdm_fsk_data_add_checksum(&fsk_data); - ftdm_channel_send_fsk_data(ftdmchan, &fsk_data, -14); -} - -static void analog_dial(ftdm_channel_t *ftdmchan, uint32_t *state_counter, uint32_t *dial_timeout) -{ - if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No digits to send, moving to UP!\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - } else { - if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else { - *state_counter = 0; - ftdmchan->needed_tones[FTDM_TONEMAP_RING] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_BUSY] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_FAIL1] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_FAIL2] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_FAIL3] = 1; - *dial_timeout = (uint32_t)((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000; - } - } -} - -/** - * \brief Main thread function for analog channel (outgoing call) - * \param me Current thread - * \param obj Channel to run in this thread - */ -static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) -{ - ftdm_channel_t *ftdmchan = (ftdm_channel_t *) obj; - ftdm_buffer_t *dt_buffer = NULL; - teletone_generation_session_t ts; - uint8_t frame[1024]; - ftdm_size_t len, rlen; - ftdm_tone_type_t tt = FTDM_TONE_DTMF; - char dtmf[MAX_DTMF+1] = ""; - ftdm_size_t dtmf_offset = 0; - ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data; - ftdm_channel_t *closed_chan; - uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout; - uint32_t answer_on_polarity_counter = 0; - ftdm_sigmsg_t sig; - - ftdm_unused_arg(me); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n"); - - ts.buffer = NULL; - - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "OPEN ERROR [%s]\n", ftdmchan->last_error); - goto done; - } - - if (ftdm_buffer_create(&dt_buffer, 1024, 3192, 0) != FTDM_SUCCESS) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "memory error!"); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "MEM ERROR\n"); - goto done; - } - - if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, &tt) != FTDM_SUCCESS) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "error initilizing tone detector!"); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "failed to initialize DTMF detector\n"); - goto done; - } - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Initialized DTMF detection\n"); - - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INTHREAD); - teletone_init_session(&ts, 0, teletone_handler, dt_buffer); - ts.rate = 8000; -#if 0 - ts.debug = 1; - ts.debug_stream = stdout; -#endif - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); - ftdm_buffer_set_loops(dt_buffer, -1); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - - ftdm_assert(interval != 0, "Invalid interval"); - - if (!dial_timeout) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Not waiting for dial tone to dial number %s\n", ftdmchan->caller_data.dnis.digits); - } - - while (ftdm_running() && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) { - ftdm_wait_flag_t flags = FTDM_READ; - ftdm_size_t dlen = 0; - - len = sizeof(frame); - - elapsed += interval; - state_counter += interval; - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_GET_CALLERID: - { - if (state_counter > 5000 || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_CALLERID_DETECT, NULL); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - } - break; - case FTDM_CHANNEL_STATE_DIALING: - { - if (state_counter > dial_timeout) { - if (ftdmchan->needed_tones[FTDM_TONEMAP_DIAL]) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else { - /* do not go up if we're waiting for polarity reversal */ - if (ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - } - } - } - } - break; - case FTDM_CHANNEL_STATE_GENRING: - { - if (state_counter > 60000) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else if (!ftdmchan->fsk_buffer || !ftdm_buffer_inuse(ftdmchan->fsk_buffer)) { - ftdm_sleep(interval); - continue; - } - } - break; - case FTDM_CHANNEL_STATE_DIALTONE: - { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD) && state_counter > 10000) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } - } - break; - case FTDM_CHANNEL_STATE_BUSY: - { - if (state_counter > 20000) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_ATTN); - } - } - break; - case FTDM_CHANNEL_STATE_ATTN: - { - if (state_counter > 20000) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - break; - case FTDM_CHANNEL_STATE_HANGUP: - { - if (state_counter > 500) { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL); - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && - (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING - || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE - || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING - || ftdmchan->last_state == FTDM_CHANNEL_STATE_UP)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else { - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - } - break; - case FTDM_CHANNEL_STATE_CALLWAITING: - { - int done = 0; - - if (ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] == 1) { - send_caller_id(ftdmchan); - ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++; - } else if (state_counter > 600 && !ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]) { - send_caller_id(ftdmchan); - ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++; - } else if (state_counter > 1000 && !ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]) { - done = 1; - } else if (state_counter > 10000) { - if (ftdmchan->fsk_buffer) { - ftdm_buffer_zero(ftdmchan->fsk_buffer); - } else { - ftdm_buffer_create(&ftdmchan->fsk_buffer, 128, 128, 0); - } - - ts.user_data = ftdmchan->fsk_buffer; - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_CALLWAITING_SAS]); - ts.user_data = dt_buffer; - done = 1; - } - - if (done) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE); - ftdm_channel_complete_state(ftdmchan); - ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0; - } - } - case FTDM_CHANNEL_STATE_UP: - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) && - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA && - ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Answering on polarity reverse\n"); - ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - answer_on_polarity_counter = state_counter; - } else if (ftdmchan->state == FTDM_CHANNEL_STATE_UP - && ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)){ - /* if this polarity reverse is close to the answer polarity reverse, ignore it */ - if (answer_on_polarity_counter - && (state_counter - answer_on_polarity_counter) > analog_data->polarity_delay) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Hanging up on polarity reverse\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, - "Not hanging up on polarity reverse, too close to Answer reverse\n"); - } - ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE); - } else { - ftdm_sleep(interval); - } - continue; - } - break; - case FTDM_CHANNEL_STATE_DOWN: - { - goto done; - } - break; - default: - break; - } - } else { - ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE); - ftdm_channel_complete_state(ftdmchan); - indicate = 0; - state_counter = 0; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler on %d:%d for %s\n", - ftdmchan->span_id, ftdmchan->chan_id, - ftdm_channel_state2str(ftdmchan->state)); - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_UP: - { - ftdm_channel_use(ftdmchan); - ftdm_channel_clear_needed_tones(ftdmchan); - ftdm_channel_flush_dtmf(ftdmchan); - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL); - } - - if (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancel FSK transmit due to early answer.\n"); - ftdm_buffer_zero(ftdmchan->fsk_buffer); - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL); - } - - if (ftdmchan->token_count == 1) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD); - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD)) { - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD); - sig.event_id = FTDM_SIGEVENT_ADD_CALL; - } else { - sig.event_id = FTDM_SIGEVENT_UP; - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && - !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) && - ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) { - ftdm_polarity_t polarity = FTDM_POLARITY_REVERSE; - if (ftdmchan->polarity == FTDM_POLARITY_FORWARD) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on answer\n"); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity); - } else { - /* the polarity may be already reversed if this is the second time we - * answer (ie, due to 2 calls being on the same line) */ - } - } - - ftdm_span_send_signal(ftdmchan->span, &sig); - continue; - } - break; - case FTDM_CHANNEL_STATE_DIALING: - { - ftdm_channel_use(ftdmchan); - } - break; - case FTDM_CHANNEL_STATE_RING: - { - ftdm_channel_use(ftdmchan); - sig.event_id = FTDM_SIGEVENT_START; - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXO) { - ftdm_set_string(ftdmchan->caller_data.dnis.digits, ftdmchan->chan_number); - } else { - ftdm_set_string(ftdmchan->caller_data.dnis.digits, dtmf); - } - - ftdm_span_send_signal(ftdmchan->span, &sig); - continue; - } - break; - - case FTDM_CHANNEL_STATE_HANGUP: - /* this state is only used when the user hangup, if the device hang up (onhook) we currently - * go straight to DOWN. If we ever change this (as other signaling modules do) by using this - * state for both user and device hangup, we should check here for the type of hangup since - * some actions (polarity reverse) do not make sense if the device hung up */ - if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && - ftdmchan->last_state == FTDM_CHANNEL_STATE_UP && - ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) { - ftdm_polarity_t polarity = ftdmchan->polarity == FTDM_POLARITY_REVERSE - ? FTDM_POLARITY_FORWARD : FTDM_POLARITY_REVERSE; - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on hangup\n"); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity); - } - break; - - case FTDM_CHANNEL_STATE_DOWN: - { - sig.event_id = FTDM_SIGEVENT_STOP; - ftdm_span_send_signal(ftdmchan->span, &sig); - goto done; - } - break; - case FTDM_CHANNEL_STATE_DIALTONE: - { - memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - *dtmf = '\0'; - dtmf_offset = 0; - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_DIAL]); - indicate = 1; - } - break; - case FTDM_CHANNEL_STATE_CALLWAITING: - { - ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0; - if (ftdmchan->fsk_buffer) { - ftdm_buffer_zero(ftdmchan->fsk_buffer); - } else { - ftdm_buffer_create(&ftdmchan->fsk_buffer, 128, 128, 0); - } - - ts.user_data = ftdmchan->fsk_buffer; - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_CALLWAITING_SAS]); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_CALLWAITING_CAS]); - ts.user_data = dt_buffer; - } - break; - case FTDM_CHANNEL_STATE_GENRING: - { - ftdm_sigmsg_t sig; - - send_caller_id(ftdmchan); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_ON, NULL); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - sig.event_id = FTDM_SIGEVENT_PROGRESS; - ftdm_span_send_signal(ftdmchan->span, &sig); - - } - break; - case FTDM_CHANNEL_STATE_GET_CALLERID: - { - memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Initializing cid data!\n"); - ftdm_set_string(ftdmchan->caller_data.ani.digits, "unknown"); - ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.ani.digits); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_CALLERID_DETECT, NULL); - continue; - } - break; - case FTDM_CHANNEL_STATE_RINGING: - { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]); - indicate = 1; - - } - break; - case FTDM_CHANNEL_STATE_BUSY: - { - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CIRCUIT_CONGESTION; - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_BUSY]); - indicate = 1; - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - break; - case FTDM_CHANNEL_STATE_ATTN: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_ATTN]); - indicate = 1; - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - break; - default: - break; - } - } - - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE || ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT) { - if ((dlen = ftdm_channel_dequeue_dtmf(ftdmchan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) { - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - collecting = 1; - } - dtmf_offset = strlen(dtmf); - last_digit = elapsed; - sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; - ftdm_set_string(sig.ev_data.collected.digits, dtmf); - if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) { - collecting = 0; - } - } - else if(!analog_data->max_dialstr) - { - last_digit = elapsed; - collecting = 0; - strcpy(dtmf, analog_data->hotline); - } - } - - - if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf); - if (ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT && ftdmchan->state_status != FTDM_STATE_STATUS_COMPLETED) { - ftdm_channel_complete_state(ftdmchan); - } - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); - last_digit = 0; - collecting = 0; - } - - if (ftdm_channel_wait(ftdmchan, &flags, interval * 2) != FTDM_SUCCESS) { - continue; - } - - if (!(flags & FTDM_READ)) { - continue; - } - - if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "read error [%s]\n", ftdmchan->last_error); - continue; - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdmchan->detected_tones[0]) { - int i; - - for (i = 1; i < FTDM_TONEMAP_INVALID; i++) { - if (ftdmchan->detected_tones[i]) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Detected tone %s on %d:%d\n", ftdm_tonemap2str(i), ftdmchan->span_id, ftdmchan->chan_id); - } - } - - if (ftdmchan->detected_tones[FTDM_TONEMAP_BUSY] || - ftdmchan->detected_tones[FTDM_TONEMAP_FAIL1] || - ftdmchan->detected_tones[FTDM_TONEMAP_FAIL2] || - ftdmchan->detected_tones[FTDM_TONEMAP_FAIL3] || - ftdmchan->detected_tones[FTDM_TONEMAP_ATTN] - ) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failure indication detected!\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else if (ftdmchan->detected_tones[FTDM_TONEMAP_DIAL]) { - analog_dial(ftdmchan, &state_counter, &dial_timeout); - } else if (ftdmchan->detected_tones[FTDM_TONEMAP_RING]) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - } - - ftdm_channel_clear_detected_tones(ftdmchan); - } else if (!dial_timeout) { - /* we were requested not to wait for dial tone, we can dial immediately */ - analog_dial(ftdmchan, &state_counter, &dial_timeout); - } - - if ((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) || (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer))) { - //rlen = len; - //memset(frame, 0, len); - //ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen); - continue; - } - - if (!indicate) { - continue; - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL); - } - - if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) { - len *= 2; - } - - rlen = ftdm_buffer_read_loop(dt_buffer, frame, len); - - if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) { - fio_codec_t codec_func = NULL; - - if (ftdmchan->native_codec == FTDM_CODEC_ULAW) { - codec_func = fio_slin2ulaw; - } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW) { - codec_func = fio_slin2alaw; - } - - if (codec_func) { - codec_func(frame, sizeof(frame), &rlen); - } else { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!"); - goto done; - } - } - - ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen); - } - - done: - - closed_chan = ftdmchan; - - ftdm_channel_lock(closed_chan); - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Going onhook\n"); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL); - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL); - } - - - ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE); - - ftdm_channel_close(&ftdmchan); - - ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL); - - if (ts.buffer) { - teletone_destroy_session(&ts); - } - - if (dt_buffer) { - ftdm_buffer_destroy(&dt_buffer); - } - - if (closed_chan->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state_locked(closed_chan, FTDM_CHANNEL_STATE_DOWN); - } - - ftdm_log_chan(closed_chan, FTDM_LOG_DEBUG, "ANALOG CHANNEL %d:%d thread ended.\n", closed_chan->span_id, closed_chan->chan_id); - - ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD); - - ftdm_channel_unlock(closed_chan); - - return NULL; -} - -/** - * \brief Processes freetdm event - * \param span Span on which the event was fired - * \param event Event to be treated - * \return Success or failure - */ -static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event) -{ - ftdm_sigmsg_t sig; - ftdm_analog_data_t *analog_data = event->channel->span->signal_data; - int locked = 0; - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = event->channel->chan_id; - sig.span_id = event->channel->span_id; - sig.channel = event->channel; - - - ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Received event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state)); - - ftdm_mutex_lock(event->channel->mutex); - locked++; - - /* MAINTENANCE WARNING: - * 1. Be aware you are working on the locked channel - * 2. We should not be calling ftdm_span_send_signal or ftdm_set_state when there is already a channel thread running - * however, since this is old code I am not changing it now, but new code should adhere to that convention - * otherwise, we have possible races where we compete with the user for state changes, ie, the user requests - * a state change and then we process an event, the state change from the user is pending so our ftdm_set_state - * operation will fail. In cases where we win the race, our state change will be accepted but if a user requests - * a state change before the state change we requested here is processed by the channel thread, we'll end up - * rejecting the user request. - * - * See docs/locking.txt for further information about what guarantees should signaling modules provide when - * locking/unlocking a channel - * */ - switch(event->enum_id) { - case FTDM_OOB_RING_START: - { - if (event->channel->type != FTDM_CHAN_TYPE_FXO) { - ftdm_log_chan_msg(event->channel, FTDM_LOG_ERROR, "Cannot get a RING_START event on a non-fxo channel, please check your config.\n"); - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); - goto end; - } - if (!event->channel->ring_count && (event->channel->state == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD))) { - if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) { - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID); - } else { - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_RING); - } - event->channel->ring_count = 1; - ftdm_mutex_unlock(event->channel->mutex); - locked = 0; - ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel); - } else { - event->channel->ring_count++; - } - } - break; - case FTDM_OOB_ONHOOK: - { - if (ftdm_test_flag(event->channel, FTDM_CHANNEL_RINGING)) { - ftdm_channel_command(event->channel, FTDM_COMMAND_GENERATE_RING_OFF, NULL); - } - - if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) { - if (event->channel->state == FTDM_CHANNEL_STATE_HANGUP && - ftdm_test_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE)) { - /* we do not need to process HANGUP since the device also hangup already */ - ftdm_channel_complete_state(event->channel); - } - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); - } - if (event->channel->type == FTDM_CHAN_TYPE_FXS) { - /* we always return to forward when the device goes onhook */ - ftdm_polarity_t forward_polarity = FTDM_POLARITY_FORWARD; - ftdm_channel_command(event->channel, FTDM_COMMAND_SET_POLARITY, &forward_polarity); - } - } - break; - case FTDM_OOB_FLASH: - { - if (event->channel->state == FTDM_CHANNEL_STATE_CALLWAITING) { - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP); - ftdm_clear_flag(event->channel->span, FTDM_SPAN_STATE_CHANGE); - ftdm_channel_complete_state(event->channel); - event->channel->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0; - } - - ftdm_channel_rotate_tokens(event->channel); - - if (ftdm_test_flag(event->channel, FTDM_CHANNEL_HOLD) && event->channel->token_count != 1) { - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP); - } else { - sig.event_id = FTDM_SIGEVENT_FLASH; - ftdm_span_send_signal(span, &sig); - } - } - break; - case FTDM_OOB_OFFHOOK: - { - if (event->channel->type == FTDM_CHAN_TYPE_FXS) { - if (ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD)) { - if (ftdm_test_flag(event->channel, FTDM_CHANNEL_RINGING)) { - ftdm_channel_command(event->channel, FTDM_COMMAND_GENERATE_RING_OFF, NULL); - } - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP); - } else { - if(!analog_data->max_dialstr) { - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_COLLECT); - } else { - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DIALTONE); - } - ftdm_mutex_unlock(event->channel->mutex); - locked = 0; - ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel); - } - } else { - if (!ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD)) { - if (ftdm_test_flag(event->channel, FTDM_CHANNEL_OFFHOOK)) { - ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL); - } - } - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); - } - } - break; - case FTDM_OOB_ALARM_TRAP: - { - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; - ftdm_span_send_signal(span, &sig); - } - break; - case FTDM_OOB_ALARM_CLEAR: - { - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; - ftdm_span_send_signal(span, &sig); - } - break; - case FTDM_OOB_POLARITY_REVERSE: - { - if (event->channel->type != FTDM_CHAN_TYPE_FXO) { - ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING, - "Ignoring polarity reversal, this should not happen in non-FXO channels!\n"); - break; - } - if (!ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD) && - ftdm_test_flag(event->channel, FTDM_CHANNEL_OFFHOOK)) { - ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING, - "Forcing onhook in channel not in thread after polarity reversal\n"); - ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL); - break; - } - if (!ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE) - && !ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) { - ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, - "Ignoring polarity reversal because this channel is not configured for it\n"); - break; - } - if (event->channel->state == FTDM_CHANNEL_STATE_DOWN) { - if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID) - && ftdm_test_flag(analog_data, FTDM_ANALOG_POLARITY_CALLERID)) { - ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, "Polarity reversal detected while down, getting caller id now\n"); - ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID); - event->channel->ring_count = 1; - ftdm_mutex_unlock(event->channel->mutex); - locked = 0; - ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel); - } else { - ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, - "Ignoring polarity reversal because this channel is down\n"); - } - break; - } - /* we have a good channel, set the polarity flag and let the channel thread deal with it */ - ftdm_set_sflag(event->channel, AF_POLARITY_REVERSE); - } - break; - default: - { - ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Ignoring event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state)); - } - break; - } - - end: - - if (locked) { - ftdm_mutex_unlock(event->channel->mutex); - } - return FTDM_SUCCESS; -} - -/** - * \brief Main thread function for analog span (monitor) - * \param me Current thread - * \param obj Span to run in this thread - */ -static void *ftdm_analog_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_analog_data_t *analog_data = span->signal_data; - int errs = 0; - - ftdm_unused_arg(me); - ftdm_log(FTDM_LOG_DEBUG, "ANALOG thread starting.\n"); - - while(ftdm_running() && ftdm_test_flag(analog_data, FTDM_ANALOG_RUNNING)) { - int waitms = 1000; - ftdm_status_t status; - - if ((status = ftdm_span_poll_event(span, waitms, NULL)) != FTDM_FAIL) { - errs = 0; - } - - switch(status) { - case FTDM_SUCCESS: - { - ftdm_event_t *event; - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { - if (event->enum_id == FTDM_OOB_NOOP) { - continue; - } - if (process_event(span, event) != FTDM_SUCCESS) { - goto end; - } - } - } - break; - case FTDM_FAIL: - { - ftdm_log(FTDM_LOG_ERROR, "Failure Polling event! [%s]\n", span->last_error); - if (++errs > 300) { - ftdm_log(FTDM_LOG_CRIT, "Too Many Errors!\n"); - goto end; - } - } - break; - default: - break; - } - - } - - end: - - ftdm_clear_flag(analog_data, FTDM_ANALOG_RUNNING); - - ftdm_log(FTDM_LOG_DEBUG, "ANALOG thread ending.\n"); - - return NULL; -} - -/** - * \brief FreeTDM analog signaling module initialisation - * \return Success - */ -static FIO_SIG_LOAD_FUNCTION(ftdm_analog_init) -{ - return FTDM_SUCCESS; -} - -/** - * \brief FreeTDM analog signaling module definition - */ -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - "analog", - NULL, - NULL, - ftdm_analog_init, - ftdm_analog_configure_span, - NULL -}; - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h b/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h deleted file mode 100644 index e52a319155..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftdm_analog_em.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2008-2012, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributor(s): - * - * John Wehle (john@feith.com) - * Moises Silva (moy@sangoma.com) - * - */ - -#ifndef FTDM_ANALOG_EM_H -#define FTDM_ANALOG_EM_H -#include "freetdm.h" - -#define MAX_DIALSTRING 256 - -typedef enum { - FTDM_ANALOG_EM_RUNNING = (1 << 0), - FTDM_ANALOG_EM_LOCAL_WRITE = (1 << 2), - FTDM_ANALOG_EM_LOCAL_SUSPEND = (1 << 3), - FTDM_ANALOG_EM_REMOTE_SUSPEND = (1 << 4), -} ftdm_analog_em_flag_t; - -struct ftdm_analog_data { - uint32_t flags; - uint32_t max_dialstr; - uint32_t digit_timeout; - uint32_t dial_timeout; - ftdm_bool_t answer_supervision; - ftdm_bool_t immediate_ringback; - char ringback_file[512]; -}; - -static void *ftdm_analog_em_run(ftdm_thread_t *me, void *obj); -typedef struct ftdm_analog_data ftdm_analog_em_data_t; - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2008.vcproj deleted file mode 100644 index 837ba7de0f..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2008.vcproj +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2010.vcxproj.filters deleted file mode 100644 index 3326f9fd16..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2010.vcxproj.filters +++ /dev/null @@ -1,23 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c deleted file mode 100644 index 98fde2a514..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * Copyright (c) 2008-2012, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributor(s): - * - * John Wehle (john@feith.com) - * Moises Silva (moy@sangoma.com) - * - */ - -#include "private/ftdm_core.h" -#include "ftdm_analog_em.h" - -#ifndef localtime_r -struct tm * localtime_r(const time_t *clock, struct tm *result); -#endif - -static FIO_SPAN_SET_SIG_STATUS_FUNCTION(analog_em_set_span_sig_status); - -/* check if the given file is a wave file and skip the header if it is */ -#define WAVE_CHUNK_ID "RIFF" -#define WAVE_FMT "WAVEfmt " -#define WAVE_HEADER_LEN 44 -static int skip_wave_header(const char *fname, FILE *f) -{ - char rbuff[10] = { 0 }; - unsigned int hz = 0; - unsigned int hs = 0; - unsigned short fmt = 0; - unsigned short chans = 0; - unsigned int size = 0; - - /* check chunk id */ - if (fread(rbuff, 1, 4, f) != 4) { - ftdm_log(FTDM_LOG_ERROR, "Unable to read wav chunk id from file %s\n", fname); - goto error; - } - rbuff[4] = 0; - - if (strncasecmp(rbuff, WAVE_CHUNK_ID, sizeof(WAVE_CHUNK_ID)-1)) { - goto notwave; - } - - /* read chunk size */ - if (fread(&size, 1, 4, f) != 4) { - ftdm_log(FTDM_LOG_ERROR, "Unable to read wav chunk size from file %s\n", fname); - goto error; - } - - /* check format and sub chunk id */ - if (fread(rbuff, 1, 8, f) != 8) { - ftdm_log(FTDM_LOG_ERROR, "Unable to read wav format and sub chunk id from file %s\n", fname); - goto error; - } - rbuff[8] = 0; - - if (strncasecmp(rbuff, WAVE_FMT, sizeof(WAVE_FMT)-1)) { - goto notwave; - } - - /* At this point we know is a wav file ... */ - - /* validate sub chunk size */ - if (fread(&hs, 1, 4, f) != 4) { - ftdm_log(FTDM_LOG_ERROR, "Unable to read wav sub chunk size from file %s\n", fname); - goto error; - } - - if (hs != 16) { - ftdm_log(FTDM_LOG_ERROR, "Unsupported wav sub chunk size %d from file %s\n", hs, fname); - goto error; - } - - /* validate audio format */ - if (fread(&fmt, 1, 2, f) != 2) { - ftdm_log(FTDM_LOG_ERROR, "Unable to read wav audio format from file %s\n", fname); - goto error; - } - - if (fmt != 1) { - ftdm_log(FTDM_LOG_ERROR, "Unsupported wav audio format %d in file %s, we only support PCM\n", fmt, fname); - goto error; - } - - /* validate channels */ - if (fread(&chans, 1, 2, f) != 2) { - ftdm_log(FTDM_LOG_ERROR, "Unable to read wav channels from file %s\n", fname); - goto error; - } - - if (chans != 1) { - ftdm_log(FTDM_LOG_ERROR, "Unsupported number of channels %d in file %s, we only support 1 (mono)\n", chans, fname); - goto error; - } - - /* validate sampling rate */ - if (fread(&hz, 1, 2, f) != 2) { - ftdm_log(FTDM_LOG_ERROR, "Unable to read wav sampling rate from file %s\n", fname); - goto error; - } - - if (hz != 8000) { - ftdm_log(FTDM_LOG_ERROR, "Invalid input wav sampling rate %dHz, only 8000Hz supported\n", hz); - goto error; - } - - ftdm_log(FTDM_LOG_DEBUG, "Found input file %s. PCM mono wav of %d bytes at %dHz, skipping header ...\n", fname, size, hz); - fseek(f, WAVE_HEADER_LEN, SEEK_SET); - - return 0; - -notwave: - ftdm_log(FTDM_LOG_ERROR, "File %s is not a wav file\n", fname); - return -1; - -error: - return -1; -} - -static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj); - -/** - * \brief Starts an EM channel thread (outgoing call) - * \param ftdmchan Channel to initiate call on - * \return Success or failure - * - * Initialises state, starts tone progress detection and runs the channel in a new a thread. - */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_em_outgoing_call) -{ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) { - ftdm_channel_clear_needed_tones(ftdmchan); - ftdm_channel_clear_detected_tones(ftdmchan); - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); - - ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_PROGRESS_DETECT, NULL); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING); - ftdm_thread_create_detached(ftdm_analog_em_channel_run, ftdmchan); - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -static ftdm_status_t ftdm_analog_em_sig_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size) -{ - ftdm_analog_em_data_t *analog_data = ftdmchan->span->signal_data; - if (ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA - && analog_data->immediate_ringback - && ftdm_test_sflag(ftdmchan, FTDM_ANALOG_EM_LOCAL_WRITE)) { - /* ringback is being played in the analog thread, ignore user data for now */ - return FTDM_BREAK; - } - return FTDM_SUCCESS; -} - -/** - * \brief Starts an EM span thread (monitor) - * \param span Span to monitor - * \return Success or failure - */ -static ftdm_status_t ftdm_analog_em_start(ftdm_span_t *span) -{ - ftdm_analog_em_data_t *analog_data = span->signal_data; - ftdm_set_flag(analog_data, FTDM_ANALOG_EM_RUNNING); - return ftdm_thread_create_detached(ftdm_analog_em_run, span); -} - -static void ftdm_analog_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -{ - ftdm_sigmsg_t sig; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status)); - } - return; -} - -/** - * \brief Stops EM span thread (monitor) - * \param span Span to monitor - * \return Success or failure - */ -static ftdm_status_t ftdm_analog_em_stop(ftdm_span_t *span) -{ - ftdm_analog_em_data_t *analog_data = span->signal_data; - ftdm_clear_flag(analog_data, FTDM_ANALOG_EM_RUNNING); - ftdm_sleep(100); - analog_em_set_span_sig_status(span, FTDM_SIG_STATE_SUSPENDED); - return FTDM_SUCCESS; -} - -/** - * \brief Returns the signalling status on a channel - * \param ftdmchan Channel to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_em_get_channel_sig_status) -{ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) { - *status = FTDM_SIG_STATE_DOWN; - return FTDM_SUCCESS; - } - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { - *status = FTDM_SIG_STATE_SUSPENDED; - return FTDM_SUCCESS; - } - *status = FTDM_SIG_STATE_UP; - return FTDM_SUCCESS; -} - -/** - * \brief Returns the signalling status on a span - * \param span Span to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_em_get_span_sig_status) -{ - ftdm_iterator_t *citer = NULL; - ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL); - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - return FTDM_FAIL; - } - /* if ALL channels are in alarm, report DOWN, UP otherwise. */ - *status = FTDM_SIG_STATE_DOWN; - for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { - ftdm_channel_t *fchan = ftdm_iterator_current(citer); - ftdm_channel_lock(fchan); - if (!ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) { - if (!ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) { - *status = FTDM_SIG_STATE_UP; - ftdm_channel_unlock(fchan); - break; - } else { - *status = FTDM_SIG_STATE_SUSPENDED; - } - } - ftdm_channel_unlock(fchan); - } - ftdm_iterator_free(chaniter); - return FTDM_SUCCESS; -} - -static ftdm_status_t analog_em_set_channel_sig_status_ex(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status, ftdm_bool_t remote) -{ - switch (status) { - case FTDM_SIG_STATE_DOWN: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot bring channel down, perhaps you want to try '%s'\n", ftdm_signaling_status2str(FTDM_SIG_STATE_SUSPENDED)); - return FTDM_FAIL; - case FTDM_SIG_STATE_SUSPENDED: - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { - int cas_bits = 0xFF; - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_CAS_BITS, &cas_bits); - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL); - } - ftdm_analog_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED); - } - if (remote) { - ftdm_set_sflag(ftdmchan, FTDM_ANALOG_EM_REMOTE_SUSPEND); - } else { - ftdm_set_sflag(ftdmchan, FTDM_ANALOG_EM_LOCAL_SUSPEND); - } - break; - case FTDM_SIG_STATE_UP: - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { - if (remote) { - ftdm_clear_sflag(ftdmchan, FTDM_ANALOG_EM_REMOTE_SUSPEND); - } else { - ftdm_clear_sflag(ftdmchan, FTDM_ANALOG_EM_LOCAL_SUSPEND); - } - if (!ftdm_test_sflag(ftdmchan, FTDM_ANALOG_EM_REMOTE_SUSPEND) && - !ftdm_test_sflag(ftdmchan, FTDM_ANALOG_EM_LOCAL_SUSPEND)) { - int cas_bits = 0x00; - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_CAS_BITS, &cas_bits); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL); - } - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) { - ftdm_analog_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP); - } - } - } - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(analog_em_set_channel_sig_status) -{ - return analog_em_set_channel_sig_status_ex(ftdmchan, status, FTDM_FALSE); -} - -static FIO_SPAN_SET_SIG_STATUS_FUNCTION(analog_em_set_span_sig_status) -{ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *citer = NULL; - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - return FTDM_FAIL; - } - /* iterate over all channels, setting them to the requested state */ - for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { - ftdm_channel_t *fchan = ftdm_iterator_current(citer); - /* we set channel's state through analog_em_set_channel_sig_status(), since it already takes care of notifying the user when appropriate */ - ftdm_channel_lock(fchan); - if ((analog_em_set_channel_sig_status_ex(fchan, status, FTDM_FALSE)) != FTDM_SUCCESS) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to set signaling status to %s\n", ftdm_signaling_status2str(status)); - } - ftdm_channel_unlock(fchan); - } - ftdm_iterator_free(chaniter); - return FTDM_SUCCESS; -} - -/** - * \brief Initialises an EM span from configuration variables - * \param span Span to configure - * \param sig_cb Callback function for event signals - * \param ap List of configuration variables - * \return Success or failure - */ -static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) -//ftdm_status_t ftdm_analog_em_configure_span(ftdm_span_t *span, char *tonemap, uint32_t digit_timeout, uint32_t max_dialstr, fio_signal_cb_t sig_cb) -{ - ftdm_analog_em_data_t *analog_data = NULL; - const char *tonemap = "us"; - const char *ringback_file = ""; - ftdm_bool_t immediate_ringback = FTDM_FALSE; - uint32_t digit_timeout = 2000; - uint32_t max_dialstr = 11; - uint32_t dial_timeout = 0; - uint32_t release_guard_time_ms = 500; - ftdm_bool_t answer_supervision = FTDM_FALSE; - const char *var, *val; - int *intval; - - assert(sig_cb != NULL); - - if (span->signal_type) { - snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling."); - return FTDM_FAIL; - } - - analog_data = ftdm_calloc(1, sizeof(*analog_data)); - assert(analog_data != NULL); - - while((var = va_arg(ap, char *))) { - ftdm_log(FTDM_LOG_DEBUG, "Parsing analog em parameter '%s'\n", var); - if (!strcasecmp(var, "tonemap")) { - if (!(val = va_arg(ap, char *))) { - break; - } - tonemap = val; - } else if (!strcasecmp(var, "immediate_ringback")) { - if (!(val = va_arg(ap, char *))) { - break; - } - immediate_ringback = ftdm_true(val); - } else if (!strcasecmp(var, "ringback_file")) { - if (!(val = va_arg(ap, char *))) { - break; - } - ringback_file = val; - } else if (!strcasecmp(var, "answer_supervision")) { - if (!(val = va_arg(ap, char *))) { - break; - } - answer_supervision = ftdm_true(val); - } else if (!strcasecmp(var, "dial_timeout")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - dial_timeout = *intval; - } else if (!strcasecmp(var, "digit_timeout")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - digit_timeout = *intval; - } else if (!strcasecmp(var, "max_dialstr")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - max_dialstr = *intval; - } else if (!strcasecmp(var, "release_guard_time_ms")) { - if (!(intval = va_arg(ap, int *))) { - break; - } - release_guard_time_ms = *intval; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid parameter for analog em span: '%s'\n", var); - return FTDM_FAIL; - } - } - - - if (digit_timeout < 2000 || digit_timeout > 10000) { - digit_timeout = 2000; - } - - if (max_dialstr < 2 || max_dialstr > MAX_DIALSTRING) { - ftdm_log(FTDM_LOG_ERROR, "Invalid max_dialstr, setting to %d\n", MAX_DIALSTRING); - max_dialstr = MAX_DIALSTRING; - } - - span->start = ftdm_analog_em_start; - span->stop = ftdm_analog_em_stop; - span->sig_write = ftdm_analog_em_sig_write; - analog_data->digit_timeout = digit_timeout; - analog_data->max_dialstr = max_dialstr; - analog_data->dial_timeout = dial_timeout; - analog_data->answer_supervision = answer_supervision; - span->signal_cb = sig_cb; - span->signal_type = FTDM_SIGTYPE_ANALOG; - span->signal_data = analog_data; - span->outgoing_call = analog_em_outgoing_call; - span->get_channel_sig_status = analog_em_get_channel_sig_status; - span->get_span_sig_status = analog_em_get_span_sig_status; - span->set_channel_sig_status = analog_em_set_channel_sig_status; - span->set_span_sig_status = analog_em_set_span_sig_status; - span->sig_release_guard_time_ms = release_guard_time_ms; - ftdm_span_load_tones(span, tonemap); - if (immediate_ringback || !ftdm_strlen_zero(ringback_file)) { - analog_data->immediate_ringback = FTDM_TRUE; - ftdm_set_string(analog_data->ringback_file, ringback_file); - } - - return FTDM_SUCCESS; - -} - -/** - * \brief Retrieves tone generation output to be sent - * \param ts Teletone generator - * \param map Tone map - * \return -1 on error, 0 on success - */ -static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map) -{ - ftdm_buffer_t *dt_buffer = ts->user_data; - int wrote; - - if (!dt_buffer) { - return -1; - } - wrote = teletone_mux_tones(ts, map); - ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2); - return 0; -} - -/** - * \brief Main thread function for EM channel (outgoing call) - * \param me Current thread - * \param obj Channel to run in this thread - */ -static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) -{ - ftdm_channel_t *ftdmchan = (ftdm_channel_t *) obj; - ftdm_buffer_t *dt_buffer = NULL; - teletone_generation_session_t ts; - uint8_t frame[1024]; - ftdm_size_t len, rlen; - ftdm_tone_type_t tt = FTDM_TONE_DTMF; - char dtmf[128] = ""; - ftdm_size_t dtmf_offset = 0; - ftdm_analog_em_data_t *analog_data = ftdmchan->span->signal_data; - ftdm_channel_t *closed_chan; - uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000; - ftdm_sigmsg_t sig; - int cas_bits = 0; - uint32_t cas_answer = 0; - uint32_t cas_hangup = 0; - int cas_answer_ms = 500; - int cas_hangup_ms = 500; - ftdm_bool_t busy_timeout = FTDM_FALSE; - FILE *ringback_f = NULL; - ftdm_bool_t digits_sent = FTDM_FALSE; - - ftdm_unused_arg(me); - ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread starting.\n"); - - ts.buffer = NULL; - - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "OPEN ERROR [%s]\n", ftdmchan->last_error); - goto done; - } - - if (ftdm_buffer_create(&dt_buffer, 1024, 3192, 0) != FTDM_SUCCESS) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "memory error!"); - ftdm_log(FTDM_LOG_ERROR, "MEM ERROR\n"); - goto done; - } - - if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, &tt) != FTDM_SUCCESS) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "error initilizing tone detector!"); - ftdm_log(FTDM_LOG_ERROR, "TONE ERROR\n"); - goto done; - } - - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INTHREAD); - teletone_init_session(&ts, 0, teletone_handler, dt_buffer); - ts.rate = 8000; -#if 0 - ts.debug = 1; - ts.debug_stream = stdout; -#endif - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); - ftdm_buffer_set_loops(dt_buffer, -1); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - - assert(interval != 0); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IO Interval: %u\n", interval); - - if (analog_data->immediate_ringback && !ftdm_strlen_zero(analog_data->ringback_file)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Using ringback file '%s'\n", analog_data->ringback_file); - ringback_f = fopen(analog_data->ringback_file, "rb"); - if (!ringback_f) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open ringback file '%s'\n", analog_data->ringback_file); - } else { - if (skip_wave_header(analog_data->ringback_file, ringback_f)) { - ringback_f = NULL; - } - } - } - - while (ftdm_running() && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) { - ftdm_wait_flag_t flags = FTDM_READ; - ftdm_size_t dlen = 0; - - elapsed += interval; - state_counter += interval; - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_DIALING: - { - if (! ftdmchan->needed_tones[FTDM_TONEMAP_RING] - && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK) - && !digits_sent) { - if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) { - ftdm_log(FTDM_LOG_ERROR, "No Digits to send!\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else { - if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else { - state_counter = 0; - digits_sent = FTDM_TRUE; - ftdmchan->needed_tones[FTDM_TONEMAP_RING] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_BUSY] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_FAIL1] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_FAIL2] = 1; - ftdmchan->needed_tones[FTDM_TONEMAP_FAIL3] = 1; - dial_timeout = ((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000; - if (analog_data->dial_timeout) { - dial_timeout += analog_data->dial_timeout; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Outbound dialing timeout: %dms\n", dial_timeout); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Outbound CAS answer timeout: %dms\n", cas_answer_ms); - } - } - break; - } - if (state_counter > dial_timeout) { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else if (!analog_data->answer_supervision) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - } - } - cas_bits = 0; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CAS_BITS, &cas_bits); - if (!(state_counter % 1000)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "CAS bits: 0x%X\n", cas_bits); - } - if (cas_bits == 0xF) { - cas_answer += interval; - if (cas_answer >= cas_answer_ms) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Answering on CAS answer signal persistence!\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - } - } else if (cas_answer) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Resetting cas answer to 0: 0x%X!\n", cas_bits); - cas_answer = 0; - } - } - break; - case FTDM_CHANNEL_STATE_DIALTONE: - { - if (state_counter > 10000) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } - } - break; - case FTDM_CHANNEL_STATE_BUSY: - { - if (state_counter > 20000) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_ATTN); - } - } - break; - case FTDM_CHANNEL_STATE_ATTN: - { - if (state_counter > 20000) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - break; - case FTDM_CHANNEL_STATE_HANGUP: - { - if (state_counter > 500) { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && - (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE - || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else { - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - } - break; - case FTDM_CHANNEL_STATE_UP: - case FTDM_CHANNEL_STATE_RING: - { - ftdm_sleep(interval); - if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) { - cas_bits = 0; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CAS_BITS, &cas_bits); - if (cas_bits == 0x0) { - cas_hangup += interval; - if (cas_hangup >= cas_hangup_ms) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Hanging up on CAS hangup signal persistence\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else if (cas_hangup) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Resetting cas hangup to 0: 0x%X!\n", cas_bits); - cas_hangup = 0; - } - } - continue; - } - break; - case FTDM_CHANNEL_STATE_DOWN: - { - goto done; - } - break; - default: - break; - } - } else { - ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE); - ftdm_channel_complete_state(ftdmchan); - indicate = 0; - state_counter = 0; - - ftdm_log(FTDM_LOG_DEBUG, "Executing state handler on %d:%d for %s\n", - ftdmchan->span_id, ftdmchan->chan_id, - ftdm_channel_state2str(ftdmchan->state)); - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_UP: - { - ftdm_channel_use(ftdmchan); - ftdm_channel_clear_needed_tones(ftdmchan); - ftdm_channel_flush_dtmf(ftdmchan); - - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL); - } - - sig.event_id = FTDM_SIGEVENT_UP; - - ftdm_span_send_signal(ftdmchan->span, &sig); - continue; - } - break; - case FTDM_CHANNEL_STATE_DIALING: - { - ftdm_channel_use(ftdmchan); - } - break; - case FTDM_CHANNEL_STATE_RING: - { - ftdm_channel_use(ftdmchan); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_set_string(ftdmchan->caller_data.dnis.digits, ftdmchan->chan_number); - } else { - ftdm_set_string(ftdmchan->caller_data.dnis.digits, dtmf); - } - - sig.event_id = FTDM_SIGEVENT_START; - - ftdm_span_send_signal(ftdmchan->span, &sig); - continue; - } - break; - case FTDM_CHANNEL_STATE_DOWN: - { - sig.event_id = FTDM_SIGEVENT_STOP; - ftdm_span_send_signal(ftdmchan->span, &sig); - goto done; - } - break; - case FTDM_CHANNEL_STATE_DIALTONE: - { - memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - *dtmf = '\0'; - dtmf_offset = 0; - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_DIAL]); - indicate = 1; - - ftdm_channel_command(ftdmchan, FTDM_COMMAND_WINK, NULL); - } - break; - case FTDM_CHANNEL_STATE_RINGING: - { - if (!analog_data->immediate_ringback) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]); - indicate = 1; - } - } - break; - case FTDM_CHANNEL_STATE_BUSY: - { - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CIRCUIT_CONGESTION; - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_BUSY]); - indicate = 1; - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - busy_timeout = FTDM_TRUE; - } - } - break; - case FTDM_CHANNEL_STATE_ATTN: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_ATTN]); - indicate = 1; - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - break; - default: - break; - } - } - - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE || ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT) { - if ((dlen = ftdm_channel_dequeue_dtmf(ftdmchan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) { - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - collecting = 1; - } - dtmf_offset = strlen(dtmf); - last_digit = elapsed; - sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; - ftdm_set_string(sig.ev_data.collected.digits, dtmf); - if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) { - collecting = 0; - } - } - } - - if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) { - ftdm_log(FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); - last_digit = 0; - collecting = 0; - } - - if (ftdm_channel_wait(ftdmchan, &flags, interval * 2) != FTDM_SUCCESS) { - continue; - } - - if (!(flags & FTDM_READ)) { - continue; - } - - /* Do not try to read more than the proper interval size */ - len = ftdmchan->packet_len * 2; - if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "READ ERROR [%s]\n", ftdmchan->last_error); - goto done; - } - - if (0 == len) { - ftdm_log(FTDM_LOG_DEBUG, "Nothing read\n"); - continue; - } - - if (len >= (sizeof(frame)/2)) { - ftdm_log(FTDM_LOG_CRIT, "Ignoring big read of %zd bytes!\n", len); - continue; - } - - if (ftdmchan->detected_tones[0]) { - int i; - - for (i = 1; i < FTDM_TONEMAP_INVALID; i++) { - if (ftdmchan->detected_tones[i]) { - ftdm_log(FTDM_LOG_DEBUG, "Detected tone %s on %d:%d\n", ftdm_tonemap2str(i), ftdmchan->span_id, ftdmchan->chan_id); - } - } - - if (ftdmchan->detected_tones[FTDM_TONEMAP_BUSY] || - ftdmchan->detected_tones[FTDM_TONEMAP_FAIL1] || - ftdmchan->detected_tones[FTDM_TONEMAP_FAIL2] || - ftdmchan->detected_tones[FTDM_TONEMAP_FAIL3] || - ftdmchan->detected_tones[FTDM_TONEMAP_ATTN] - ) { - ftdm_log(FTDM_LOG_ERROR, "Failure indication detected!\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); - } else if (ftdmchan->detected_tones[FTDM_TONEMAP_RING]) { - if (!analog_data->answer_supervision) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ringing, but not answering since answer supervision is enabled\n"); - } - } - - ftdm_channel_clear_detected_tones(ftdmchan); - } - - if ((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer))) { - rlen = len; - memset(frame, 0, len); - ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen); - continue; - } - - if (analog_data->immediate_ringback && - (ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT || - ftdmchan->state == FTDM_CHANNEL_STATE_RING || - ftdmchan->state == FTDM_CHANNEL_STATE_RINGING || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS || - ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA - )) { - indicate = 1; - if (!ringback_f) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]); - } - } - - if (!indicate) { - continue; - } - - if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) { - len *= 2; - } - - if (ringback_f) { - uint8_t failed_read = 0; -read_try: - rlen = fread(frame, 1, len, ringback_f); - if (rlen != len) { - if (!feof(ringback_f)) { - ftdm_log(FTDM_LOG_ERROR, "Error reading from ringback file: %zd != %zd\n", rlen, len); - } - if (failed_read) { - continue; - } - /* return cursor to start of wav file */ - fseek(ringback_f, WAVE_HEADER_LEN, SEEK_SET); - failed_read++; - goto read_try; - } - } else { - rlen = ftdm_buffer_read_loop(dt_buffer, frame, len); - } - - if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) { - fio_codec_t codec_func = NULL; - - if (ftdmchan->native_codec == FTDM_CODEC_ULAW) { - codec_func = fio_slin2ulaw; - } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW) { - codec_func = fio_slin2alaw; - } - - if (codec_func) { - codec_func(frame, sizeof(frame), &rlen); - } else { - ftdm_log(FTDM_LOG_ERROR, "codec error, no codec function for native codec %d!", ftdmchan->native_codec); - goto done; - } - } - - /* we must lock the channel and make sure we let our own generated audio thru (FTDM_ANALOG_EM_LOCAL_WRITE is tested in the ftdm_analog_em_sig_write handler)*/ - ftdm_channel_lock(ftdmchan); - ftdm_set_sflag(ftdmchan, FTDM_ANALOG_EM_LOCAL_WRITE); - ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen); - ftdm_clear_sflag(ftdmchan, FTDM_ANALOG_EM_LOCAL_WRITE); - ftdm_channel_unlock(ftdmchan); - } - - done: - - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL); - if (busy_timeout) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CAS_BITS, &cas_bits); - if (cas_bits == 0XF) { - /* the remote end never sent any digits, neither moved to onhook, let's stay suspended */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Moving channel to suspended after timeout, remote end still offhook\n"); - analog_em_set_channel_sig_status_ex(ftdmchan, FTDM_SIG_STATE_SUSPENDED, FTDM_TRUE); - } - } - - closed_chan = ftdmchan; - ftdm_channel_close(&ftdmchan); - - ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL); - - if (ts.buffer) { - teletone_destroy_session(&ts); - } - - if (dt_buffer) { - ftdm_buffer_destroy(&dt_buffer); - } - - if (ringback_f) { - fclose(ringback_f); - } - - ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD); - - ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread ended.\n"); - - return NULL; -} - -/** - * \brief Processes EM events coming from ftdmtel/dahdi - * \param span Span on which the event was fired - * \param event Event to be treated - * \return Success or failure - */ -static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event) -{ - ftdm_sigmsg_t sig; - int locked = 0; - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = event->channel->chan_id; - sig.span_id = event->channel->span_id; - sig.channel = event->channel; - - ftdm_unused_arg(span); - ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n", - ftdm_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, ftdm_channel_state2str(event->channel->state)); - - ftdm_mutex_lock(event->channel->mutex); - locked++; - - if (event->enum_id == FTDM_OOB_ONHOOK && ftdm_test_sflag(event->channel, FTDM_ANALOG_EM_REMOTE_SUSPEND)) { - /* We've got remote suspend, now we're back on hook, lift the remote suspend status */ - analog_em_set_channel_sig_status_ex(event->channel, FTDM_SIG_STATE_UP, FTDM_TRUE); - } - - if (ftdm_test_flag(event->channel, FTDM_CHANNEL_SUSPENDED)) { - ftdm_log(FTDM_LOG_WARNING, "Ignoring event %s on channel %d:%d in state %s, channel is suspended\n", - ftdm_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, ftdm_channel_state2str(event->channel->state)); - goto done; - } - - switch(event->enum_id) { - case FTDM_OOB_ONHOOK: - { - if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN); - } - - } - break; - case FTDM_OOB_OFFHOOK: - { - if (ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD)) { - if (event->channel->state < FTDM_CHANNEL_STATE_UP) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP); - } - } else { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DIALTONE); - ftdm_mutex_unlock(event->channel->mutex); - locked = 0; - ftdm_thread_create_detached(ftdm_analog_em_channel_run, event->channel); - } - break; - } - case FTDM_OOB_WINK: - { - if (event->channel->state != FTDM_CHANNEL_STATE_DIALING) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN); - } else { - ftdm_set_flag_locked(event->channel, FTDM_CHANNEL_WINK); - } - - } - break; - } - -done: - - if (locked) { - ftdm_mutex_unlock(event->channel->mutex); - } - return FTDM_SUCCESS; -} - -/** - * \brief Main thread function for EM span (monitor) - * \param me Current thread - * \param obj Span to run in this thread - */ -static void *ftdm_analog_em_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_analog_em_data_t *analog_data = span->signal_data; - - ftdm_unused_arg(me); - ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM thread starting.\n"); - analog_em_set_span_sig_status(span, FTDM_SIG_STATE_UP); - - while(ftdm_running() && ftdm_test_flag(analog_data, FTDM_ANALOG_EM_RUNNING)) { - int waitms = 10; - ftdm_status_t status; - - status = ftdm_span_poll_event(span, waitms, NULL); - - switch(status) { - case FTDM_SUCCESS: - { - ftdm_event_t *event; - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { - if (event->enum_id == FTDM_OOB_NOOP) { - continue; - } - if (process_event(span, event) != FTDM_SUCCESS) { - goto end; - } - } - } - break; - case FTDM_FAIL: - { - ftdm_log(FTDM_LOG_ERROR, "Failure Polling event! [%s]\n", span->last_error); - } - break; - default: - break; - } - - } - - end: - - ftdm_clear_flag(analog_data, FTDM_ANALOG_EM_RUNNING); - - ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM thread ending.\n"); - - return NULL; -} - -/** - * \brief FreeTDM analog EM module initialisation - * \return Success - */ -static FIO_SIG_LOAD_FUNCTION(ftdm_analog_em_init) -{ - return FTDM_SUCCESS; -} - -/** - * \brief FreeTDM analog EM module definition - */ -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - "analog_em", - NULL, - NULL, - ftdm_analog_em_init, - ftdm_analog_em_configure_span, - NULL -}; - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c b/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c deleted file mode 100755 index 0dbe1e647b..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_gsm/ftmod_gsm.c +++ /dev/null @@ -1,1592 +0,0 @@ -/* - * Copyright (c) 2011, Sangoma Technologies - * All rights reserved. - * - Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Gideon Sadan - * Moises Silva - * - */ - - -#define _GNU_SOURCE - -#include -#include - -#ifndef __WINDOWS__ -#include -#include -#include -#endif - -#include -#include -#include -/*========================*/ - -#include -#include -#include - -#include - -/********************************************************************************/ -/* */ -/* MACROS */ -/* */ -/********************************************************************************/ -// Macro to send signals -#define SEND_STATE_SIGNAL(sig) \ - { \ - ftdm_sigmsg_t sigev; \ - memset(&sigev, 0, sizeof(sigev)); \ - sigev.event_id = sig; \ - sigev.channel = ftdmchan; \ - ftdm_span_send_signal(ftdmchan->span, &sigev); \ - } - -// Syntax message -#define FT_SYNTAX "USAGE:\n" \ -"--------------------------------------------------------------------------------\n" \ -"ftdm gsm version \n" \ -"ftdm gsm status \n" \ -"ftdm gsm sms \n" \ -"ftdm gsm exec \n" \ -"ftdm gsm call [number]\n" \ -"--------------------------------------------------------------------------------\n" - -// Used to declare command handler -#define COMMAND_HANDLER(name) \ - static ftdm_status_t gsm_cmd_##name(ftdm_stream_handle_t *stream, char *argv[], int argc); \ - ftdm_status_t gsm_cmd_##name(ftdm_stream_handle_t *stream, char *argv[], int argc) - -// Used to define command entry in the command map -#define COMMAND(name, argc) {#name, argc, gsm_cmd_##name} - -/********************************************************************************/ -/* */ -/* types */ -/* */ -/********************************************************************************/ - -typedef enum { - FTDM_GSM_RUNNING = (1 << 0), - FTDM_GSM_SPAN_STARTED = (1 << 1), -} ftdm_gsm_flag_t; - -// private data -typedef struct ftdm_gsm_span_data_s { - ftdm_span_t *span; - ftdm_channel_t *dchan; - ftdm_channel_t *bchan; - int32_t call_id; - uint32_t sms_id; - char conditional_forward_prefix[10]; - char conditional_forward_number[50]; - char immediate_forward_prefix[10]; - struct { - char number[50]; - char span[50]; - } immediate_forward_numbers[10]; - char disable_forward_number[50]; - ftdm_sched_t *sched; - ftdm_timer_id_t conditional_forwarding_timer; - ftdm_timer_id_t immediate_forwarding_timer; - ftdm_bool_t init_conditional_forwarding; - ftdm_bool_t startup_forwarding_disabled; - char startup_commands[20][50]; - ftdm_gsm_flag_t flags; - ftdm_bool_t sig_up; -} ftdm_gsm_span_data_t; - -// command handler function type. -typedef ftdm_status_t (*command_handler_t)(ftdm_stream_handle_t *stream, char *argv[], int argc); - -typedef struct ftdm_gsm_exec_helper { - ftdm_span_t *span; - ftdm_stream_handle_t *stream; - uint8_t cmd_pending; -} ftdm_gsm_exec_helper_t; - -/********************************************************************************/ -/* */ -/* function declaration */ -/* */ -/********************************************************************************/ -static ftdm_status_t init_wat_lib(void); -static int wat_lib_initialized = 0; -static FIO_API_FUNCTION(ftdm_gsm_api); - -/* ugh, wasteful since unlikely anyone will ever have more than 4 or 8 GSM spans, but we couldn't use ftdm_find_span() - * because during the stop sequence the internal span lock is held and we end up deadlocked, ideally libwat would just give - * us a pointer we provide instead of a span id */ -static ftdm_span_t * span_map[255] = { 0 }; - -/* wat callbacks */ -static int on_wat_span_write(unsigned char span_id, void *buffer, unsigned len); - -static void on_wat_con_ind(unsigned char span_id, uint8_t call_id, wat_con_event_t *con_event); -static void on_wat_con_sts(unsigned char span_id, uint8_t call_id, wat_con_status_t *status); -static void on_wat_rel_ind(unsigned char span_id, uint8_t call_id, wat_rel_event_t *rel_event); -static void on_wat_rel_cfm(unsigned char span_id, uint8_t call_id); -static void on_wat_sms_ind(unsigned char span_id, wat_sms_event_t *sms_event); -static void on_wat_sms_sts(unsigned char span_id, uint8_t sms_id, wat_sms_status_t *status); - -static void on_wat_log(uint8_t level, char *fmt, ...); -static void *on_wat_malloc(size_t size); -static void *on_wat_calloc(size_t nmemb, size_t size); -static void on_wat_free(void *ptr); -static void on_wat_log_span(uint8_t span_id, uint8_t level, char *fmt, ...); - -static ftdm_span_t *get_span_by_id(uint8_t span_id, ftdm_gsm_span_data_t **gsm_data); - -static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj); - -/********************************************************************************/ -/* */ -/* static & global data */ -/* */ -/********************************************************************************/ - -/* At the moment we support only one concurrent call per span, so no need to have different ids */ -#define GSM_OUTBOUND_CALL_ID 8 - -/* IO interface for the command API */ -static ftdm_io_interface_t g_ftdm_gsm_interface; - -/********************************************************************************/ -/* */ -/* implementation */ -/* */ -/********************************************************************************/ -static int on_wat_span_write(unsigned char span_id, void *buffer, unsigned len) -{ - ftdm_span_t *span = NULL; - ftdm_status_t status = FTDM_FAIL; - ftdm_gsm_span_data_t *gsm_data = NULL; - ftdm_size_t outsize = len; - - status = ftdm_span_find(span_id, &span); - if (status != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to find span %d to write %d bytes\n", span_id, len); - return -1; - } - - gsm_data = span->signal_data; - status = ftdm_channel_write(gsm_data->dchan, (void *)buffer, len, &outsize); - if (status != FTDM_SUCCESS) { - char errbuf[255]; - ftdm_log(FTDM_LOG_ERROR, "Failed to write %d bytes to d-channel in span %s: %s\n", len, span->name, strerror_r(errno, errbuf, sizeof(errbuf))); - return -1; - } - return len; -} - -static void ftdm_gsm_make_raw_call(ftdm_gsm_span_data_t *gsm_data, const char *number) -{ - wat_con_event_t con_event; - - ftdm_channel_lock(gsm_data->bchan); - - if (ftdm_test_flag(gsm_data->bchan, FTDM_CHANNEL_INUSE)) { - ftdm_log_chan(gsm_data->bchan, FTDM_LOG_ERROR, "Failed to place raw call to %s: channel busy\n", number); - goto done; - } - - ftdm_log_chan(gsm_data->bchan, FTDM_LOG_INFO, "Placing raw call to %s\n", number); - ftdm_set_flag(gsm_data->bchan, FTDM_CHANNEL_INUSE); - - gsm_data->call_id = GSM_OUTBOUND_CALL_ID; - memset(&con_event, 0, sizeof(con_event)); - ftdm_set_string(con_event.called_num.digits, number); - wat_con_req(gsm_data->span->span_id, gsm_data->call_id , &con_event); - -done: - ftdm_channel_unlock(gsm_data->bchan); -} - -static void ftdm_gsm_enable_conditional_forwarding(void *data) -{ - char number[255]; - ftdm_gsm_span_data_t *gsm_data = data; - snprintf(number, sizeof(number), "%s%s", gsm_data->conditional_forward_prefix, gsm_data->conditional_forward_number); - ftdm_log_chan(gsm_data->bchan, FTDM_LOG_INFO, "Enabling conditional forwarding to %s\n", number); - ftdm_gsm_make_raw_call(data, number); -} - -static void on_wat_span_status(unsigned char span_id, wat_span_status_t *status) -{ - ftdm_gsm_span_data_t *gsm_data = NULL; - ftdm_span_t *span = get_span_by_id(span_id, &gsm_data); - - switch (status->type) { - case WAT_SPAN_STS_READY: - { - int i = 0; - ftdm_log(FTDM_LOG_INFO, "span %s: Ready\n", span->name); - for (i = 0; !ftdm_strlen_zero_buf(gsm_data->startup_commands[i]); i++) { - ftdm_log(FTDM_LOG_INFO, "span %d: Executing startup command '%s'\n", span_id, gsm_data->startup_commands[i]); - if (WAT_SUCCESS != wat_cmd_req(span_id, gsm_data->startup_commands[i], NULL, NULL)) { - ftdm_log(FTDM_LOG_ERROR, "span %d: Failed requesting execution of command '%s'\n", span_id, gsm_data->startup_commands[i]); - } - } - } - break; - case WAT_SPAN_STS_SIGSTATUS: - { - if (status->sts.sigstatus == WAT_SIGSTATUS_UP) { - ftdm_log_chan_msg(gsm_data->bchan, FTDM_LOG_INFO, "Signaling is now up\n"); - gsm_data->sig_up = FTDM_TRUE; - } else { - ftdm_log_chan_msg(gsm_data->bchan, FTDM_LOG_INFO, "Signaling is now down\n"); - gsm_data->sig_up = FTDM_FALSE; - } - if (gsm_data->init_conditional_forwarding == FTDM_TRUE && !ftdm_strlen_zero_buf(gsm_data->conditional_forward_number)) { - ftdm_sched_timer(gsm_data->sched, "conditional_forwarding_delay", 1000, - ftdm_gsm_enable_conditional_forwarding, - gsm_data, - &gsm_data->conditional_forwarding_timer); - gsm_data->init_conditional_forwarding = FTDM_FALSE; - } - } - break; - case WAT_SPAN_STS_SIM_INFO_READY: - { - const wat_sim_info_t *sim_info = NULL; - ftdm_log(FTDM_LOG_INFO, "span %s: SIM information ready\n", span->name); - sim_info = wat_span_get_sim_info(span->span_id); - if (!ftdm_strlen_zero(sim_info->subscriber.digits)) { - ftdm_set_string(gsm_data->bchan->chan_number, sim_info->subscriber.digits); - } - } - break; - case WAT_SPAN_STS_ALARM: - { - ftdm_log(FTDM_LOG_INFO, "span %s: Alarm received\n", span->name); - } - break; - default: - { - ftdm_log(FTDM_LOG_INFO, "span %s: Unhandled span status notification %d\n", span->name, status->type); - } - break; - } -} - -static void on_wat_con_ind(uint8_t span_id, uint8_t call_id, wat_con_event_t *con_event) -{ - ftdm_span_t *span = NULL; - ftdm_gsm_span_data_t *gsm_data = NULL; - - ftdm_log(FTDM_LOG_INFO, "s%d: Incoming call (id:%d) Calling Number:%s Calling Name:\"%s\" type:%d plan:%d\n", span_id, call_id, con_event->calling_num.digits, con_event->calling_name, con_event->calling_num.type, con_event->calling_num.plan); - - span = get_span_by_id(span_id, &gsm_data); - - gsm_data->call_id = call_id; - - // cid name - ftdm_set_string(gsm_data->bchan->caller_data.cid_name, con_event->calling_name); - - // cid number - ftdm_set_string(gsm_data->bchan->caller_data.cid_num.digits, con_event->calling_num.digits); - - // destination number - ftdm_set_string(gsm_data->bchan->caller_data.dnis.digits, gsm_data->bchan->chan_number); - - ftdm_set_state(gsm_data->bchan, FTDM_CHANNEL_STATE_RING); - - if (ftdm_channel_open_chan(gsm_data->bchan) != FTDM_SUCCESS) { - ftdm_log_chan(gsm_data->bchan, FTDM_LOG_ERROR, "Failed to open GSM b-channel of span %s!\n", span->name); - } - -} - -static ftdm_span_t *get_span_by_id(unsigned char span_id, ftdm_gsm_span_data_t **gsm_data) -{ - ftdm_span_t *span = NULL; - - if (gsm_data) { - (*gsm_data) = NULL; - } - - span = span_map[span_id]; - if (gsm_data) { - (*gsm_data) = span->signal_data; - } - return span; -} - -static void on_wat_con_sts(unsigned char span_id, uint8_t call_id, wat_con_status_t *status) -{ - ftdm_span_t *span = NULL; - ftdm_channel_state_t state = FTDM_CHANNEL_STATE_END; - ftdm_gsm_span_data_t *gsm_data = NULL; - - if (!(span = get_span_by_id(span_id, &gsm_data))) { - return; - } - - switch (status->type) { - case WAT_CON_STATUS_TYPE_RINGING: - ftdm_log_chan_msg(gsm_data->bchan, FTDM_LOG_INFO, "Received ringing indication\n"); - state = FTDM_CHANNEL_STATE_RINGING; - break; - - case WAT_CON_STATUS_TYPE_ANSWER: - ftdm_log_chan_msg(gsm_data->bchan, FTDM_LOG_INFO, "Received answer indication\n"); - state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA; - break; - - default: - ftdm_log_chan(gsm_data->bchan, FTDM_LOG_WARNING, "Unhandled indication status %d\n", status->type); - break; - - } - - if (state != FTDM_CHANNEL_STATE_END && gsm_data->bchan->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state(gsm_data->bchan, state); - } -} - -static void on_wat_rel_ind(unsigned char span_id, uint8_t call_id, wat_rel_event_t *rel_event) -{ - ftdm_span_t *span = NULL; - ftdm_gsm_span_data_t *gsm_data = NULL; - - ftdm_log(FTDM_LOG_INFO, "s%d: Call hangup (id:%d) cause:%d\n", span_id, call_id, rel_event->cause); - - if (!(span = get_span_by_id(span_id, &gsm_data))) { - return; - } - - if (gsm_data->bchan->state == FTDM_CHANNEL_STATE_DOWN) { - /* This is most likely due to a call to enable call - * forwarding, which does not run the state machine */ - ftdm_clear_flag(gsm_data->bchan, FTDM_CHANNEL_INUSE); - wat_rel_req(span_id, call_id); - return; - } - - if (gsm_data->bchan->state > FTDM_CHANNEL_STATE_DOWN && - gsm_data->bchan->state < FTDM_CHANNEL_STATE_HANGUP) { - ftdm_set_state(gsm_data->bchan, FTDM_CHANNEL_STATE_HANGUP); - } -} - -static void on_wat_rel_cfm(unsigned char span_id, uint8_t call_id) -{ - ftdm_span_t *span = NULL; - ftdm_gsm_span_data_t *gsm_data = NULL; - - ftdm_log(FTDM_LOG_INFO, "s%d: Call hangup complete (id:%d)\n", span_id, call_id); - - if (!(span = get_span_by_id(span_id, &gsm_data))) { - return; - } - - if (gsm_data->bchan->state == FTDM_CHANNEL_STATE_DOWN) { - /* This is most likely due to a call to enable call - * forwarding, which does not run the state machine */ - ftdm_clear_flag(gsm_data->bchan, FTDM_CHANNEL_INUSE); - return; - } - - switch(gsm_data->dchan->state) { - case FTDM_CHANNEL_STATE_UP: - ftdm_set_state(gsm_data->bchan, FTDM_CHANNEL_STATE_HANGUP); - break; - default: - ftdm_set_state(gsm_data->bchan, FTDM_CHANNEL_STATE_DOWN); - break; - } -} - -static void on_wat_sms_ind(unsigned char span_id, wat_sms_event_t *sms_event) -{ - ftdm_span_t *span = NULL; - ftdm_channel_t *ftdmchan; - - ftdm_gsm_span_data_t *gsm_data = NULL; - - if(!(span = get_span_by_id(span_id, &gsm_data))) { - return; - } - - ftdmchan = gsm_data->dchan; - - { - ftdm_sms_data_t sms_data; - ftdm_sigmsg_t sigev; - memset(&sms_data, 0, sizeof(sms_data)); - - strncpy(sms_data.from, sms_event->from.digits, sizeof(sms_data.from)); - strncpy(sms_data.body, sms_event->content.data, sizeof(sms_data.body)); - - memset(&sigev, 0, sizeof(sigev)); - sigev.event_id = FTDM_SIGEVENT_SMS; - sigev.channel = ftdmchan ; - gsm_data->dchan->caller_data.priv = (void *)&sms_data; - ftdm_span_send_signal(span, &sigev); - } - return; -} - -static void on_wat_sms_sts(unsigned char span_id, uint8_t sms_id, wat_sms_status_t *status) -{ - if (status->success) { - ftdm_log(FTDM_LOG_INFO, "Span %d SMS Send - OK\n", span_id ); - } else { - ftdm_log(FTDM_LOG_CRIT, "Span %d SMS Send - FAIL (%s)\n", span_id, status->error); - } -} - -static void on_wat_dtmf_ind(unsigned char span_id, const char *dtmf) -{ - ftdm_span_t *span = NULL; - ftdm_gsm_span_data_t *gsm_data = NULL; - - if (!(span = get_span_by_id(span_id, &gsm_data))) { - return; - } - - ftdm_channel_queue_dtmf(gsm_data->bchan, dtmf); -} - - -static void on_wat_log(uint8_t level, char *fmt, ...) -{ - int ftdm_level; - char buff[4096]; - - va_list argptr; - va_start(argptr, fmt); - - switch(level) { - case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break; - case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break; - case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break; - case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break; - case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break; - case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break; - default: ftdm_level = FTDM_LOG_LEVEL_ERROR; break; - }; - - - vsprintf(buff, fmt, argptr); - - ftdm_log(FTDM_PRE, ftdm_level, "%s", buff); - - va_end(argptr); -} - - -static void *on_wat_malloc(size_t size) -{ - return ftdm_malloc(size); -} - -static void *on_wat_calloc(size_t nmemb, size_t size) -{ - return ftdm_calloc(nmemb, size); -} - -static void on_wat_free(void *ptr) -{ - ftdm_free(ptr); -} - -static void on_wat_log_span(uint8_t span_id, uint8_t level, char *fmt, ...) -{ - ftdm_span_t *span = NULL; - ftdm_gsm_span_data_t *gsm_data = NULL; - int ftdm_level; - char buff[4096]; - va_list argptr; - - if (!(span = get_span_by_id(span_id, &gsm_data))) { - return; - } - - va_start(argptr, fmt); - - switch(level) { - case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break; - case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break; - case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break; - case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break; - case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break; - case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break; - default: ftdm_level = FTDM_LOG_LEVEL_ERROR; break; - }; - - vsprintf(buff, fmt, argptr); - - ftdm_log_chan_ex(gsm_data->bchan, __FILE__, __FTDM_FUNC__, __LINE__, ftdm_level, "%s", buff); - - va_end(argptr); -} - - -/* END wat callbacks */ - -/* span monitor thread */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(gsm_outgoing_call) -{ - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_gsm_start(ftdm_span_t *span) -{ - ftdm_gsm_span_data_t *gsm_data = span->signal_data; - ftdm_set_flag(gsm_data, FTDM_GSM_SPAN_STARTED); - return ftdm_thread_create_detached(ftdm_gsm_run, span); -} - -static ftdm_status_t ftdm_gsm_stop(ftdm_span_t *span) -{ - ftdm_gsm_span_data_t *gsm_data = span->signal_data; - ftdm_clear_flag(gsm_data, FTDM_GSM_SPAN_STARTED); - while (ftdm_test_flag(gsm_data, FTDM_GSM_RUNNING)) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for GSM span %s\n", span->name); - ftdm_sleep(100); - } - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_gsm_destroy(ftdm_span_t *span) -{ - ftdm_gsm_span_data_t *gsm_data = span->signal_data; - ftdm_assert_return(gsm_data != NULL, FTDM_FAIL, "Span does not have GSM data!\n"); - if (gsm_data->sched) { - ftdm_sched_destroy(&gsm_data->sched); - } - ftdm_free(gsm_data); - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_gsm_get_channel_sig_status) -{ - ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data; - *status = gsm_data->sig_up ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN; - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_gsm_set_channel_sig_status) -{ - ftdm_log(FTDM_LOG_ERROR, "You cannot set the signaling status for GSM channels (%s)\n", ftdmchan->span->name); - return FTDM_FAIL; -} - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_gsm_get_span_sig_status) -{ - ftdm_gsm_span_data_t *gsm_data = span->signal_data; - *status = gsm_data->sig_up ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN; - return FTDM_SUCCESS; -} - -static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_gsm_set_span_sig_status) -{ - ftdm_log(FTDM_LOG_ERROR, "You cannot set the signaling status for GSM spans (%s)\n", span->name); - return FTDM_FAIL; -} - -static ftdm_state_map_t gsm_state_map = { - { - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - - /* Outbound states */ - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END} - }, - - - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - } -}; - -#define immediate_forward_enabled(gsm_data) !ftdm_strlen_zero_buf(gsm_data->immediate_forward_numbers[0].number) - -static void perform_enable_immediate_forward(void *data) -{ - ftdm_span_t *fwd_span = NULL; - ftdm_gsm_span_data_t *fwd_gsm_data = NULL; - char *fwd_span_name = NULL; - char *number = NULL; - char cmd[100]; - int i = 0; - ftdm_channel_t *ftdmchan = data; - ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data; - - for (i = 0; i < ftdm_array_len(gsm_data->immediate_forward_numbers); i++) { - fwd_span_name = gsm_data->immediate_forward_numbers[i].span; - fwd_span = NULL; - if (!ftdm_strlen_zero_buf(fwd_span_name) && - ftdm_span_find_by_name(fwd_span_name, &fwd_span) != FTDM_SUCCESS) { - continue; - } - fwd_gsm_data = fwd_span ? fwd_span->signal_data : NULL; - if (fwd_gsm_data && fwd_gsm_data->call_id) { - /* span busy, do not forward here */ - continue; - } - number = gsm_data->immediate_forward_numbers[i].number; - break; - } - - if (!number) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "No numbers available to enable immediate forwarding\n"); - return; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Enabling immediate forwarding to %s\n", number); - snprintf(cmd, sizeof(cmd), "ATD%s%s", gsm_data->immediate_forward_prefix, number); - wat_cmd_req(ftdmchan->span->span_id, cmd, NULL, NULL); -} - -static __inline__ void enable_immediate_forward(ftdm_channel_t *ftdmchan) -{ - ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data; - ftdm_sched_timer(gsm_data->sched, "immediate_forwarding_delay", 1000, - perform_enable_immediate_forward, - ftdmchan, - &gsm_data->immediate_forwarding_timer); -} - -static __inline__ void disable_all_forwarding(ftdm_channel_t *ftdmchan) -{ - char cmd[100]; - ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data; - - if (ftdm_strlen_zero_buf(gsm_data->disable_forward_number)) { - return; - } - - snprintf(cmd, sizeof(cmd), "ATD%s", gsm_data->disable_forward_number); - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Disabling GSM immediate forward dialing %s\n", gsm_data->disable_forward_number); - wat_cmd_req(ftdmchan->span->span_id, cmd, NULL, NULL); -} - -static ftdm_status_t ftdm_gsm_state_advance(ftdm_channel_t *ftdmchan) -{ - ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing GSM state handler for %s\n", ftdm_channel_state2str(ftdmchan->state)); - - ftdm_channel_complete_state(ftdmchan); - - switch (ftdmchan->state) { - - /* starting an outgoing call */ - case FTDM_CHANNEL_STATE_DIALING: - { - uint32_t interval = 0; - wat_con_event_t con_event; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting outgoing call with interval %d\n", interval); - - gsm_data->call_id = GSM_OUTBOUND_CALL_ID; - memset(&con_event, 0, sizeof(con_event)); - ftdm_set_string(con_event.called_num.digits, ftdmchan->caller_data.dnis.digits); - ftdm_log(FTDM_LOG_DEBUG, "Dialing number %s\n", con_event.called_num.digits); - wat_con_req(ftdmchan->span->span_id, gsm_data->call_id , &con_event); - - SEND_STATE_SIGNAL(FTDM_SIGEVENT_DIALING); - } - break; - - /* incoming call was offered */ - case FTDM_CHANNEL_STATE_RING: - { - /* notify the user about the new call */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Inbound call detected\n"); - SEND_STATE_SIGNAL(FTDM_SIGEVENT_START); - } - break; - - /* the call is making progress */ - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - SEND_STATE_SIGNAL(FTDM_SIGEVENT_PROGRESS_MEDIA); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - } - break; - - /* the call was answered */ - case FTDM_CHANNEL_STATE_UP: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - SEND_STATE_SIGNAL(FTDM_SIGEVENT_UP); - } else { - wat_con_cfm(ftdmchan->span->span_id, gsm_data->call_id); - } - if (immediate_forward_enabled(gsm_data)) { - enable_immediate_forward(ftdmchan); - } - } - break; - - /* just got hangup */ - case FTDM_CHANNEL_STATE_HANGUP: - { - wat_rel_req(ftdmchan->span->span_id, gsm_data->call_id); - SEND_STATE_SIGNAL(FTDM_SIGEVENT_STOP); - } - break; - - /* finished call for good */ - case FTDM_CHANNEL_STATE_DOWN: - { - ftdm_channel_t *closed_chan; - gsm_data->call_id = 0; - closed_chan = ftdmchan; - ftdm_channel_close(&closed_chan); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "State processing ended.\n"); - SEND_STATE_SIGNAL(FTDM_SIGEVENT_STOP); - if (immediate_forward_enabled(gsm_data)) { - disable_all_forwarding(ftdmchan); - } - } - break; - - /* Outbound call is ringing */ - case FTDM_CHANNEL_STATE_RINGING: - { - SEND_STATE_SIGNAL(FTDM_SIGEVENT_RINGING); - } - break; - - case FTDM_CHANNEL_STATE_RESET: - { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - - default: - { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state: %s\n", ftdm_channel_state2str(ftdmchan->state)); - } - break; - } - - return FTDM_SUCCESS; -} - -static ftdm_status_t init_wat_lib(void) -{ - wat_interface_t wat_interface; - - if (wat_lib_initialized) { - return FTDM_SUCCESS; - } - - ftdm_log(FTDM_LOG_DEBUG, "Registering interface to WAT Library...\n"); - - memset(&wat_interface, 0, sizeof(wat_interface)); - wat_interface.wat_span_write = on_wat_span_write; - - wat_interface.wat_log = on_wat_log; - wat_interface.wat_log_span = on_wat_log_span; - wat_interface.wat_malloc = on_wat_malloc; - wat_interface.wat_calloc = on_wat_calloc; - wat_interface.wat_free = on_wat_free; - - wat_interface.wat_con_ind = on_wat_con_ind; - wat_interface.wat_con_sts = on_wat_con_sts; - wat_interface.wat_rel_ind = on_wat_rel_ind; - wat_interface.wat_rel_cfm = on_wat_rel_cfm; - wat_interface.wat_sms_ind = on_wat_sms_ind; - wat_interface.wat_sms_sts = on_wat_sms_sts; - wat_interface.wat_span_sts = on_wat_span_status; - wat_interface.wat_dtmf_ind = on_wat_dtmf_ind; - - if (wat_register(&wat_interface)) { - ftdm_log(FTDM_LOG_DEBUG, "Failed registering interface to WAT library ...\n"); - return FTDM_FAIL; - } - - ftdm_log(FTDM_LOG_DEBUG, "Registered interface to WAT library\n"); - - wat_lib_initialized = 1; - return FTDM_SUCCESS; -} - -WAT_AT_CMD_RESPONSE_FUNC(on_dtmf_sent) -{ - ftdm_channel_t *ftdmchan = obj; - ftdm_span_t *span = ftdmchan->span; - int i = 0; - - if (success == WAT_TRUE) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "DTMF successfully transmitted on span %s\n", span->name); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Command execution failed on span %s. Err: %s\n", span->name, error); - } - - for (i = 0; tokens[i]; i++) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "%s\n", tokens[i]); - } - return i; -} - -static ftdm_status_t ftdm_gsm_send_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf) -{ - ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data; - wat_send_dtmf(ftdmchan->span->span_id, gsm_data->call_id, dtmf, on_dtmf_sent, ftdmchan); - return FTDM_SUCCESS; -} - -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling) -{ - wat_span_config_t span_config; - ftdm_gsm_span_data_t *gsm_data = NULL; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *citer = NULL; - ftdm_channel_t *ftdmchan = NULL; - ftdm_channel_t *dchan = NULL; - ftdm_channel_t *bchan = NULL; - ftdm_bool_t hwdtmf_detect = FTDM_FALSE; - ftdm_bool_t hwdtmf_generate = FTDM_FALSE; - - unsigned paramindex = 0; - const char *var = NULL; - const char *val = NULL; - char schedname[255]; - int cmdindex = 0; - - int codec = FTDM_CODEC_SLIN; - int interval = 20; - - /* libwat is smart enough to set good default values for the timers if they are set to 0 */ - memset(&span_config, 0, sizeof(span_config)); - - /* set some span defaults */ - span_config.moduletype = WAT_MODULE_TELIT; - span_config.hardware_dtmf = WAT_FALSE; - - if (FTDM_SUCCESS != init_wat_lib()) { - return FTDM_FAIL; - } - - if (!sig_cb) { - ftdm_log(FTDM_LOG_ERROR, "No signaling callback provided\n"); - return FTDM_FAIL; - } - - if (span->signal_type) { - ftdm_log(FTDM_LOG_ERROR, "Span %s is already configured for another signaling\n", span->name); - return FTDM_FAIL; - } - - /* verify the span has one d-channel */ - chaniter = ftdm_span_get_chan_iterator(span, NULL); - - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - return FTDM_FAIL; - } - - citer = ftdm_span_get_chan_iterator(span, chaniter); - for ( ; citer; citer = ftdm_iterator_next(citer)) { - ftdmchan = ftdm_iterator_current(citer); - - if ((NULL == dchan) && FTDM_IS_DCHAN(ftdmchan)) { - dchan = ftdmchan; - } - if ((NULL == bchan) && FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - bchan = ftdmchan; - } - - } - ftdm_iterator_free(chaniter); - - if (!dchan) { - ftdm_log(FTDM_LOG_CRIT, "Could not find a d-channel for GSM span %s!\n", span->name); - return FTDM_FAIL; - } - if (!bchan) { - ftdm_log(FTDM_LOG_CRIT, "Could not find a b-channel for GSM span %s!\n", span->name); - return FTDM_FAIL; - } - - gsm_data = ftdm_calloc(1, sizeof(*gsm_data)); - if (!gsm_data) { - return FTDM_FAIL; - } - gsm_data->dchan = dchan; - gsm_data->bchan = bchan; - - cmdindex = 0; - for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { - var = ftdm_parameters[paramindex].var; - val = ftdm_parameters[paramindex].val; - if (ftdm_strlen_zero_buf(val)) { - ftdm_log(FTDM_LOG_WARNING, "Ignoring empty GSM parameter %s for span %s\n", var, span->name); - continue; - } - ftdm_log(FTDM_LOG_DEBUG, "Reading GSM parameter %s=%s for span %s\n", var, val, span->name); - if (!strcasecmp(var, "moduletype")) { - span_config.moduletype = wat_str2wat_moduletype(val); - if (span_config.moduletype == WAT_MODULE_INVALID) { - ftdm_log(FTDM_LOG_ERROR, "Unknown GSM module type %s for span %s\n", val, span->name); - continue; - } - ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with moduletype %s\n", span->name, val); - } else if (!strcasecmp(var, "debug")) { - span_config.debug_mask = wat_str2debug(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with debug mask %s == 0x%X\n", span->name, val, span_config.debug_mask); - } else if (!strcasecmp(var, "hwdtmf")) { - hwdtmf_detect = FTDM_FALSE; - hwdtmf_generate = FTDM_FALSE; - if (!strcasecmp(val, "generate")) { - hwdtmf_generate = FTDM_TRUE; - } else if (!strcasecmp(val, "detect")) { - hwdtmf_detect = FTDM_TRUE; - } else if (!strcasecmp(val, "both") || ftdm_true(val)) { - hwdtmf_detect = FTDM_TRUE; - hwdtmf_generate = FTDM_TRUE; - } else { - span_config.hardware_dtmf = WAT_FALSE; - } - ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with hardware dtmf %s\n", span->name, val); - } else if (!strcasecmp(var, "conditional-forwarding-number")) { - ftdm_set_string(gsm_data->conditional_forward_number, val); - gsm_data->init_conditional_forwarding = FTDM_TRUE; - } else if (!strcasecmp(var, "conditional-forwarding-prefix")) { - ftdm_set_string(gsm_data->conditional_forward_prefix, val); - } else if (!strcasecmp(var, "immediate-forwarding-numbers")) { - char *state = NULL; - char *span_end = NULL; - char *number = NULL; - char *span_name = NULL; - int f = 0; - char *valdup = ftdm_strdup(val); - char *s = valdup; - - if (!ftdm_strlen_zero_buf(gsm_data->immediate_forward_numbers[0].number)) { - ftdm_log(FTDM_LOG_ERROR, "immediate-forwarding-numbers already parsed! failed to parse: %s\n", val); - goto ifn_parse_done; - } - - /* The string must be in the form [:], optionally multiple elements separated by comma */ - while ((number = strtok_r(s, ",", &state))) { - if (f == ftdm_array_len(gsm_data->immediate_forward_numbers)) { - ftdm_log(FTDM_LOG_ERROR, "Max number (%d) of immediate forwarding numbers reached!\n", f); - break; - } - - s = NULL; - span_end = strchr(number, ':'); - if (span_end) { - *span_end = '\0'; - span_name = number; - number = (span_end + 1); - ftdm_set_string(gsm_data->immediate_forward_numbers[f].span, span_name); - ftdm_log(FTDM_LOG_DEBUG, "Parsed immediate forwarding to span %s number %s\n", span_name, number); - } else { - ftdm_log(FTDM_LOG_DEBUG, "Parsed immediate forwarding to number %s\n", number); - } - ftdm_set_string(gsm_data->immediate_forward_numbers[f].number, number); - f++; - } -ifn_parse_done: - ftdm_safe_free(valdup); - } else if (!strcasecmp(var, "immediate-forwarding-prefix")) { - ftdm_set_string(gsm_data->immediate_forward_prefix, val); - } else if (!strcasecmp(var, "disable-forwarding-number")) { - ftdm_set_string(gsm_data->disable_forward_number, val); - } else if (!strcasecmp(var, "startup-command")) { - if (cmdindex < (ftdm_array_len(gsm_data->startup_commands) - 1)) { - ftdm_set_string(gsm_data->startup_commands[cmdindex], val); - ftdm_log(FTDM_LOG_DEBUG, "Adding startup command '%s' to GSM span %s\n", gsm_data->startup_commands[cmdindex], span->name); - cmdindex++; - } else { - ftdm_log(FTDM_LOG_ERROR, "Ignoring startup command '%s' ... max commands limit reached", val); - } - } else { - ftdm_log(FTDM_LOG_ERROR, "Ignoring unknown GSM parameter '%s'", var); - } - } - - /* Bind function pointers for control operations */ - span->start = ftdm_gsm_start; - span->stop = ftdm_gsm_stop; - span->destroy = ftdm_gsm_destroy; - span->sig_read = NULL; - span->sig_write = NULL; - if (hwdtmf_detect || hwdtmf_generate) { - span_config.hardware_dtmf = WAT_TRUE; - if (hwdtmf_generate) { - span->sig_send_dtmf = ftdm_gsm_send_dtmf; - } - if (hwdtmf_detect) { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SIG_DTMF_DETECTION); - } - } - span->signal_cb = sig_cb; - span->signal_type = FTDM_SIGTYPE_GSM; - span->signal_data = gsm_data; - span->outgoing_call = gsm_outgoing_call; - span->get_span_sig_status = ftdm_gsm_get_span_sig_status; - span->set_span_sig_status = ftdm_gsm_set_span_sig_status; - span->get_channel_sig_status = ftdm_gsm_get_channel_sig_status; - span->set_channel_sig_status = ftdm_gsm_set_channel_sig_status; - - span->state_map = &gsm_state_map; - span->state_processor = ftdm_gsm_state_advance; - - /* use signals queue */ - ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); - ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); - - /* we can skip states (going straight from RING to UP) */ - ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES); - - gsm_data->span = span; - span_map[span->span_id] = span; - - /* Setup the scheduler */ - snprintf(schedname, sizeof(schedname), "ftmod_gsm_%s", span->name); - if (ftdm_sched_create(&gsm_data->sched, schedname) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to setup scheduler for span %s!\n", span->name); - ftdm_gsm_destroy(span); - return FTDM_FAIL; - } - - /* Start the signaling stack */ - if (wat_span_config(span->span_id, &span_config)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to configure span %s for GSM signaling!!\n", span->name); - ftdm_gsm_destroy(span); - return FTDM_FAIL; - } - - ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_NATIVE_CODEC, &codec); - ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_CODEC, &codec); - ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_INTERVAL, &interval); - - return FTDM_SUCCESS; - -} - -#define GSM_POLL_INTERVAL_MS 20 -static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj) -{ - ftdm_channel_t *ftdmchan = NULL; - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_gsm_span_data_t *gsm_data = NULL; - ftdm_interrupt_t *data_sources[2] = {NULL, NULL}; - ftdm_wait_flag_t flags = FTDM_READ | FTDM_EVENTS; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_alarm_flag_t alarms; - char buffer[1024] = { 0 }; - ftdm_size_t bufsize = 0; - int waitms = 0; - - gsm_data = span->signal_data; - ftdm_assert_return(gsm_data != NULL, NULL, "No gsm data attached to span\n"); - - /* as long as this thread is running, this flag is set */ - ftdm_set_flag(gsm_data, FTDM_GSM_RUNNING); - - ftdm_log(FTDM_LOG_DEBUG, "GSM monitor thread for span %s started\n", span->name); - if (!gsm_data->dchan || ftdm_channel_open_chan(gsm_data->dchan) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open GSM d-channel of span %s!\n", span->name); - gsm_data->dchan = NULL; - goto done; - } - - /* Do not start if the link layer is not ready yet */ - ftdm_channel_get_alarms(gsm_data->dchan, &alarms); - if (alarms != FTDM_ALARM_NONE) { - ftdm_log(FTDM_LOG_WARNING, "Delaying initialization of span %s until alarms are cleared\n", span->name); - while (ftdm_running() && ftdm_test_flag(gsm_data, FTDM_GSM_SPAN_STARTED) && alarms != FTDM_ALARM_NONE) { - ftdm_channel_get_alarms(gsm_data->dchan, &alarms); - ftdm_sleep(100); - } - if (!ftdm_running() || !ftdm_test_flag(gsm_data, FTDM_GSM_SPAN_STARTED)) { - goto done; - } - } - - if (wat_span_start(span->span_id)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to start span %s!\n", span->name); - goto done; - } - - while (ftdm_running() && ftdm_test_flag(gsm_data, FTDM_GSM_SPAN_STARTED)) { - wat_span_run(span->span_id); - ftdm_sched_run(gsm_data->sched); - - waitms = wat_span_schedule_next(span->span_id); - if (waitms > GSM_POLL_INTERVAL_MS) { - waitms = GSM_POLL_INTERVAL_MS; - } - - flags = FTDM_READ | FTDM_EVENTS; - status = ftdm_channel_wait(gsm_data->dchan, &flags, waitms); - - /* check if this channel has a state change pending and process it if needed */ - ftdm_channel_lock(gsm_data->bchan); - ftdm_channel_advance_states(gsm_data->bchan); - - if (FTDM_SUCCESS == status && (flags & FTDM_READ)) { - bufsize = sizeof(buffer); - status = ftdm_channel_read(gsm_data->dchan, buffer, &bufsize); - if (status == FTDM_SUCCESS && bufsize > 0) { - wat_span_process_read(span->span_id, buffer, bufsize); - buffer[0] = 0; - } - } - - ftdm_channel_advance_states(gsm_data->bchan); - ftdm_channel_unlock(gsm_data->bchan); - - ftdm_span_trigger_signals(span); - - } - - if (wat_span_stop(span->span_id)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to stop GSM span %s!\n", span->name); - } - - if (wat_span_unconfig(span->span_id)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to unconfigure GSM span %s!\n", span->name); - } - -done: - if (data_sources[0]) { - ftdm_interrupt_destroy(&data_sources[0]); - } - - ftdm_log(FTDM_LOG_DEBUG, "GSM thread ending\n"); - ftdm_clear_flag(gsm_data, FTDM_GSM_RUNNING); - - return NULL; -} - - - -static FIO_IO_LOAD_FUNCTION(ftdm_gsm_io_init) -{ - assert(fio != NULL); - memset(&g_ftdm_gsm_interface, 0, sizeof(g_ftdm_gsm_interface)); - - g_ftdm_gsm_interface.name = "gsm"; - g_ftdm_gsm_interface.api = ftdm_gsm_api; - - *fio = &g_ftdm_gsm_interface; - - return (FTDM_SUCCESS); -} - -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - /* .name */ "gsm", - /* .io_load */ ftdm_gsm_io_init, - /* .io_unload */ NULL, - /* .sig_load */ NULL, - /* .sig_configure */ NULL, - /* .sig_unload */ NULL, - /* .configure_span_signaling */ ftdm_gsm_configure_span_signaling -}; - -/********************************************************************************/ -/* */ -/* COMMAND HANDLERS */ -/* */ -/********************************************************************************/ - - -// Version Command Handler -COMMAND_HANDLER(version) -{ - uint8_t current = 0, revision = 0, age = 0; - wat_version(¤t, &revision, &age); - stream->write_function(stream, "libwat version: %d.%d.%d\n", current, revision, age); - stream->write_function(stream, "+OK.\n"); - return FTDM_SUCCESS; -} - - -// Status Command Handler -COMMAND_HANDLER(status) -{ - int span_id = 0; - ftdm_span_t *span = NULL; - const wat_chip_info_t *chip_info = NULL; - const wat_sim_info_t *sim_info = NULL; - const wat_net_info_t *net_info = NULL; - const wat_sig_info_t *sig_info = NULL; - wat_pin_stat_t pin_stat = 0; - - span_id = atoi(argv[0]); - if (ftdm_span_find_by_name(argv[0], &span) != FTDM_SUCCESS && ftdm_span_find(span_id, &span) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR Failed to find GSM span '%s'\n", argv[1]); - return FTDM_FAIL; - } - - if (!span || !span->signal_data || (span->start != ftdm_gsm_start)) { - stream->write_function(stream, "-ERR '%s' is not a valid GSM span\n", argv[1]); - return FTDM_FAIL; - } - - chip_info = wat_span_get_chip_info(span->span_id); - sim_info = wat_span_get_sim_info(span->span_id); - net_info = wat_span_get_net_info(span->span_id); - sig_info = wat_span_get_sig_info(span->span_id); - - /* This is absolutely retarded and should be fixed in libwat - * why the hell would you return a pointer to an internal state enum instead of a copy? - * probably the same applies to the rest of the info (sim_info, chip_info, net_info, etc), - * but at least there you could have the lame excuse that you don't need to copy the whole struct */ - pin_stat = *wat_span_get_pin_info(span->span_id); - - stream->write_function(stream, "Span %d (%s):\n", span->span_id, span->name); - - stream->write_function(stream, "CHIP type - %s (%s), revision %s, serial %s \n", - chip_info->manufacturer, - chip_info->model, - chip_info->revision, - chip_info->serial); - - stream->write_function(stream, "SIM - Subscriber type %s, imsi %s\n", sim_info->subscriber_type, sim_info->imsi); - - stream->write_function(stream, "Subscriber - Number %s, Plan %s, validity %s\n", - sim_info->subscriber.digits, - wat_number_type2str(sim_info->subscriber.type), - wat_number_plan2str(sim_info->subscriber.plan), - wat_number_validity2str(sim_info->subscriber.validity)); - - stream->write_function(stream, "Network - status %s, Area Code %d, Cell ID %d, Operator %s\n", - wat_net_stat2str(net_info->stat), net_info->lac, net_info->ci, net_info->operator_name); - - - stream->write_function(stream, "Sig Info: rssi(%d) ber(%d)\n", sig_info->rssi, sig_info->ber); - - stream->write_function(stream, "PIN Status: %s\n", wat_pin_stat2str(pin_stat)); - - stream->write_function(stream, "\n"); - - stream->write_function(stream, "+OK.\n"); - - return FTDM_SUCCESS; -} - -// SMS Command Handler -COMMAND_HANDLER(sms) -{ - int span_id = 0, i; - uint32_t sms_id = 0; - ftdm_span_t *span = NULL; - wat_sms_event_t sms; - ftdm_gsm_span_data_t *gsm_data = NULL; - - span_id = atoi(argv[0]); - if (ftdm_span_find_by_name(argv[0], &span) != FTDM_SUCCESS && ftdm_span_find(span_id, &span) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR Failed to find GSM span '%s'\n", argv[1]); - return FTDM_FAIL; - } - - if (!span || !span->signal_data || (span->start != ftdm_gsm_start)) { - stream->write_function(stream, "-ERR '%s' is not a valid GSM span\n", argv[1]); - return FTDM_FAIL; - } - gsm_data = span->signal_data; - - memset(&sms, 0, sizeof(sms)); - strcpy(sms.to.digits, argv[1]); - sms.type = WAT_SMS_TXT; - sms.content.data[0] = '\0'; - for(i=2;ibchan); - - sms_id = gsm_data->sms_id >= WAT_MAX_SMSS_PER_SPAN ? 0 : gsm_data->sms_id; - gsm_data->sms_id++; - - ftdm_channel_unlock(gsm_data->bchan); - - if (WAT_SUCCESS != wat_sms_req(span->span_id, sms_id, &sms)) { - stream->write_function(stream, "Failed to Send SMS \n"); - } else { - stream->write_function(stream, "SMS Sent.\n"); - } - return FTDM_SUCCESS; -} - -WAT_AT_CMD_RESPONSE_FUNC(gsm_exec_cb) -{ - ftdm_gsm_exec_helper_t *helper = (ftdm_gsm_exec_helper_t *)obj; - ftdm_stream_handle_t *stream = helper->stream; - ftdm_span_t *span = helper->span; - int i = 0; - - if (success == WAT_TRUE) { - stream->write_function(stream, "Command executed successfully on span %s\n", span->name); - } else { - stream->write_function(stream, "Command execution failed on span %s. Err: %s\n", span->name, error); - } - - for (i = 0; tokens[i]; i++) { - stream->write_function(stream, "%s\n", tokens[i]); - } - - helper->cmd_pending = 0; - return i; -} - -// AT Command Handler -COMMAND_HANDLER(exec) -{ - int span_id = 0; - int sanity = 100; - ftdm_span_t *span = NULL; - ftdm_gsm_exec_helper_t helper; - - span_id = atoi(argv[0]); - if (ftdm_span_find_by_name(argv[0], &span) != FTDM_SUCCESS && ftdm_span_find(span_id, &span) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR Failed to find GSM span '%s'\n", argv[0]); - return FTDM_FAIL; - } - - if (!span || !span->signal_data || (span->start != ftdm_gsm_start)) { - stream->write_function(stream, "-ERR '%s' is not a valid GSM span\n", argv[0]); - return FTDM_FAIL; - } - - helper.stream = stream; - helper.span = span; - helper.cmd_pending = 1; - if (WAT_SUCCESS != wat_cmd_req(span->span_id, argv[1], gsm_exec_cb, &helper)) { - stream->write_function(stream, "Failed to send AT command on span %s\n", span->name); - } else { - stream->write_function(stream, "AT command sent on span %s\n", span->name); - } - - while (helper.cmd_pending && (--sanity > 0)) { - ftdm_sleep(100); - } - - if (sanity < 0) { - stream->write_function(stream, "Timed out waiting for respons for AT command on span %s\n", span->name); - } - return FTDM_SUCCESS; -} - -// AT Command Handler -COMMAND_HANDLER(call) -{ - int span_id = 0; - ftdm_span_t *span = NULL; - - span_id = atoi(argv[0]); - if (ftdm_span_find_by_name(argv[0], &span) != FTDM_SUCCESS && ftdm_span_find(span_id, &span) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR Failed to find GSM span '%s'\n", argv[0]); - return FTDM_FAIL; - } - - if (!span || !span->signal_data || (span->start != ftdm_gsm_start)) { - stream->write_function(stream, "-ERR '%s' is not a valid GSM span\n", argv[0]); - return FTDM_FAIL; - } - - ftdm_gsm_make_raw_call(span->signal_data, argv[1]); - stream->write_function(stream, "+OK\n"); - return FTDM_SUCCESS; -} - -// command map -static struct { - const char *cmd; // command - int argc; // minimum args - command_handler_t handler; // handling function -} GSM_COMMANDS[] = { - COMMAND(version, 0), - COMMAND(status, 1), - COMMAND(sms, 3), - COMMAND(exec, 2), - COMMAND(call, 2), -}; - -// main command API entry point -static FIO_API_FUNCTION(ftdm_gsm_api) -{ - - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - int i; - ftdm_status_t status = FTDM_FAIL; - ftdm_status_t syntax = FTDM_FAIL; - - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argc > 0) { - for (i = 0; i< ftdm_array_len(GSM_COMMANDS); i++) { - if (strcasecmp(argv[0], GSM_COMMANDS[i].cmd) == 0) { - if (argc -1 >= GSM_COMMANDS[i].argc) { - syntax = FTDM_SUCCESS; - status = GSM_COMMANDS[i].handler(stream, &argv[1], argc-1); - } - break; - } - } - } - - if (FTDM_SUCCESS != syntax) { - stream->write_function(stream, "%s", FT_SYNTAX); - } else if (FTDM_SUCCESS != status) { - stream->write_function(stream, "%s Command Failed\r\n", GSM_COMMANDS[i].cmd); - } - - ftdm_safe_free(mycmd); - - return FTDM_SUCCESS; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2008.vcproj deleted file mode 100644 index 0177d4246a..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2008.vcproj +++ /dev/null @@ -1,465 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2010.vcxproj.filters deleted file mode 100644 index 30824888fc..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2010.vcxproj.filters +++ /dev/null @@ -1,110 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c deleted file mode 100644 index fba15eaca2..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ /dev/null @@ -1,2927 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include -#include - -#ifdef WIN32 -#include -#else -#include -#endif - -#include "ftmod_isdn.h" - -#define LINE "--------------------------------------------------------------------------------" - -/* helper macros */ -#define FTDM_SPAN_IS_NT(x) (((ftdm_isdn_data_t *)(x)->signal_data)->mode == Q921_NT) - -#define DEFAULT_NATIONAL_PREFIX "0" -#define DEFAULT_INTERNATIONAL_PREFIX "00" - -/***************************************************************************************** - * PCAP - * Based on Helmut Kuper's () implementation, - * but using a different approach (needs a recent libpcap + wireshark) - *****************************************************************************************/ -#ifdef HAVE_PCAP -#include /* htons() */ -#include - -#define PCAP_SNAPLEN 1500 - -struct pcap_context { - pcap_dumper_t *dump; /*!< pcap file handle */ - pcap_t *handle; /*!< pcap lib context */ - char *filename; /*!< capture file name */ -}; - -static inline ftdm_status_t isdn_pcap_is_open(struct ftdm_isdn_data *isdn) -{ - return (isdn->pcap) ? 1 : 0; -} - -static inline ftdm_status_t isdn_pcap_capture_both(struct ftdm_isdn_data *isdn) -{ - return ((isdn->flags & (FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY)) == FTDM_ISDN_CAPTURE) ? 1 : 0; -} - -static inline ftdm_status_t isdn_pcap_capture_l3only(struct ftdm_isdn_data *isdn) -{ - return ((isdn->flags & FTDM_ISDN_CAPTURE) && (isdn->flags & FTDM_ISDN_CAPTURE_L3ONLY)) ? 1 : 0; -} - -static ftdm_status_t isdn_pcap_open(struct ftdm_isdn_data *isdn, char *filename) -{ - struct pcap_context *pcap = NULL; - - if (!isdn || ftdm_strlen_zero(filename)) - return FTDM_FAIL; - - pcap = malloc(sizeof(struct pcap_context)); - if (!pcap) { - ftdm_log(FTDM_LOG_ERROR, "Failed to allocate isdn pcap context\n"); - return FTDM_FAIL; - } - - memset(pcap, 0, sizeof(struct pcap_context)); - - pcap->filename = strdup(filename); - - pcap->handle = pcap_open_dead(DLT_LINUX_LAPD, PCAP_SNAPLEN); - if (!pcap->handle) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open pcap handle\n"); - goto error; - } - - pcap->dump = pcap_dump_open(pcap->handle, pcap->filename); - if (!pcap->dump) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open capture file: '%s'\n", pcap_geterr(pcap->handle)); - goto error; - } - - ftdm_log(FTDM_LOG_INFO, "Capture file '%s' opened\n", pcap->filename); - - isdn->pcap = pcap; - - return FTDM_SUCCESS; -error: - if (pcap->handle) - pcap_close(pcap->handle); - if (pcap->filename) - free(pcap->filename); - - free(pcap); - - return FTDM_FAIL; -} - -static ftdm_status_t isdn_pcap_close(struct ftdm_isdn_data *isdn) -{ - struct pcap_context *pcap = NULL; - long size; - - if (!isdn || !isdn->pcap) - return FTDM_FAIL; - - pcap = isdn->pcap; - - isdn->flags &= ~(FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY); - isdn->pcap = NULL; - - pcap_dump_flush(pcap->dump); - - size = pcap_dump_ftell(pcap->dump); - ftdm_log(FTDM_LOG_INFO, "File '%s' captured %ld bytes of data\n", pcap->filename, size); - - pcap_dump_close(pcap->dump); - pcap_close(pcap->handle); - - free(pcap->filename); - free(pcap); - - return FTDM_SUCCESS; -} - -static inline void isdn_pcap_start(struct ftdm_isdn_data *isdn) -{ - if (!isdn->pcap) - return; - - isdn->flags |= FTDM_ISDN_CAPTURE; -} - -static inline void isdn_pcap_stop(struct ftdm_isdn_data *isdn) -{ - isdn->flags &= ~FTDM_ISDN_CAPTURE; -} - -#ifndef ETH_P_LAPD -#define ETH_P_LAPD 0x0030 -#endif - -struct isdn_sll_hdr { - uint16_t slltype; - uint16_t sllhatype; - uint16_t slladdrlen; - uint8_t slladdr[8]; - uint16_t sllproto; -}; - -/* Fake Q.921 I-frame */ -//static const char q921_fake_frame[] = { 0x00, 0x00, 0x00, 0x00 }; - -enum { - ISDN_PCAP_INCOMING = 0, - ISDN_PCAP_INCOMING_BCAST = 1, - ISDN_PCAP_OUTGOING = 4, -}; - -static ftdm_status_t isdn_pcap_write(struct ftdm_isdn_data *isdn, unsigned char *buf, ftdm_ssize_t len, int direction) -{ - unsigned char frame[PCAP_SNAPLEN]; - struct pcap_context *pcap; - struct isdn_sll_hdr *sll_hdr = (struct isdn_sll_hdr *)frame; - struct pcap_pkthdr hdr; - int offset = sizeof(struct isdn_sll_hdr); - int nbytes; - - if (!isdn || !isdn->pcap || !buf || !len) - return FTDM_FAIL; - - pcap = isdn->pcap; - - /* Update SLL header */ - sll_hdr->slltype = htons(direction); - sll_hdr->sllhatype = 0; - sll_hdr->slladdrlen = 1; - sll_hdr->slladdr[0] = (isdn->mode == Q921_NT) ? 1 : 0; /* TODO: NT/TE */ - sll_hdr->sllproto = htons(ETH_P_LAPD); - -#if 0 - /* Q.931-only mode: copy fake Q.921 header */ - if (isdn->flags & FTDM_ISDN_CAPTURE_L3ONLY) { - /* copy fake q921 header */ - memcpy(frame + offset, q921_fake_frame, sizeof(q921_fake_frame)); - offset += sizeof(q921_fake_frame); - } -#endif - - /* Copy data */ - nbytes = (len > (PCAP_SNAPLEN - offset)) ? (PCAP_SNAPLEN - offset) : len; - memcpy(frame + offset, buf, nbytes); - - /* Update timestamp */ - memset(&hdr, 0, sizeof(struct pcap_pkthdr)); - gettimeofday(&hdr.ts, NULL); - hdr.caplen = offset + nbytes; - hdr.len = hdr.caplen; - - /* Write packet */ - pcap_dump((unsigned char *)pcap->dump, &hdr, frame); - - return FTDM_SUCCESS; -} -#endif /* HAVE_PCAP */ - - -static L2ULONG ftdm_time_now(void) -{ - return (L2ULONG)ftdm_current_time_in_ms(); -} - -/** - * \brief Returns the signalling status on a channel - * \param ftdmchan Channel to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(isdn_get_channel_sig_status) -{ - *status = FTDM_SIG_STATE_DOWN; - - ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data; - if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) { - *status = FTDM_SIG_STATE_UP; - } - return FTDM_SUCCESS; -} - -/** - * \brief Returns the signalling status on a span - * \param span Span to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(isdn_get_span_sig_status) -{ - *status = FTDM_SIG_STATE_DOWN; - - ftdm_isdn_data_t *isdn_data = span->signal_data; - if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) { - *status = FTDM_SIG_STATE_UP; - } - return FTDM_SUCCESS; -} - -/** - * \brief Create outgoing channel - * \param ftdmchan Channel to create outgoing call on - * \return Success or failure - */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call) -{ - return FTDM_SUCCESS; -} - -/** - * \brief Create outgoing channel, let module select the channel to use - * \param span Span to create outgoing call on - * \param caller_data - * \return Success or failure - */ -#ifdef __TODO__ -static FIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request) -{ -#if 1 /* FIXME caller_data.raw_data does not exist anymore, see docs/variables.txt for more info */ - Q931mes_Generic empty_gen; - Q931mes_Generic *gen = &empty_gen; - - memset(&empty_gen, 0, sizeof(empty_gen)) ; -#else - Q931mes_Generic *gen = (Q931mes_Generic *) caller_data->raw_data; -#endif - Q931ie_BearerCap BearerCap; - Q931ie_ChanID ChanID = { 0 }; - Q931ie_CallingNum CallingNum; - Q931ie_CallingNum *ptrCallingNum; - Q931ie_CalledNum CalledNum; - Q931ie_CalledNum *ptrCalledNum; - Q931ie_Display Display, *ptrDisplay; - Q931ie_HLComp HLComp; /* High-Layer Compatibility IE */ - Q931ie_ProgInd Progress; /* Progress Indicator IE */ - ftdm_status_t status = FTDM_FAIL; - ftdm_isdn_data_t *isdn_data = span->signal_data; - int sanity = 60000; - int codec = 0; - - /* - * get codec type - */ - ftdm_channel_command(span->channels[chan_id], FTDM_COMMAND_GET_NATIVE_CODEC, &codec); - - /* - * Q.931 Setup Message - */ - Q931InitMesGeneric(gen); - gen->MesType = Q931mes_SETUP; - gen->CRVFlag = 0; /* outgoing call */ - - /* - * Bearer Capability IE - */ - Q931InitIEBearerCap(&BearerCap); - BearerCap.CodStand = Q931_CODING_ITU; /* ITU-T = 0, ISO/IEC = 1, National = 2, Network = 3 */ - BearerCap.ITC = Q931_ITC_SPEECH; /* Speech */ - BearerCap.TransMode = 0; /* Circuit = 0, Packet = 1 */ - BearerCap.ITR = Q931_ITR_64K; /* 64k */ - BearerCap.Layer1Ident = 1; - BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? Q931_UIL1P_G711A : Q931_UIL1P_G711U; /* U-law = 2, A-law = 3 */ - gen->BearerCap = Q931AppendIE(gen, (L3UCHAR *) &BearerCap); - - /* - * Channel ID IE - */ - Q931InitIEChanID(&ChanID); - ChanID.IntType = FTDM_SPAN_IS_BRI(span) ? 0 : 1; /* PRI = 1, BRI = 0 */ - - if (!FTDM_SPAN_IS_NT(span)) { - ChanID.PrefExcl = (isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL) ? 0 : 1; /* 0 = preferred, 1 exclusive */ - } else { - ChanID.PrefExcl = 1; /* always exclusive in NT-mode */ - } - - if (ChanID.IntType) { - ChanID.InfoChanSel = 1; /* None = 0, See Slot = 1, Any = 3 */ - ChanID.ChanMapType = 3; /* B-Chan */ - ChanID.ChanSlot = (unsigned char)chan_id; - } else { - ChanID.InfoChanSel = (unsigned char)chan_id & 0x03; /* None = 0, B1 = 1, B2 = 2, Any = 3 */ - } - gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID); - - /* - * Progress IE - */ - Q931InitIEProgInd(&Progress); - Progress.CodStand = Q931_CODING_ITU; /* 0 = ITU */ - Progress.Location = 0; /* 0 = User, 1 = Private Network */ - Progress.ProgDesc = 3; /* 1 = Not end-to-end ISDN */ - gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *)&Progress); - - /* - * Display IE - */ - if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE) && FTDM_SPAN_IS_NT(span)) { - Q931InitIEDisplay(&Display); - Display.Size = Display.Size + (unsigned char)strlen(caller_data->cid_name); - gen->Display = Q931AppendIE(gen, (L3UCHAR *) &Display); - ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf); - ftdm_copy_string((char *)ptrDisplay->Display, caller_data->cid_name, strlen(caller_data->cid_name)+1); - } - - /* - * Calling Number IE - */ - Q931InitIECallingNum(&CallingNum); - CallingNum.TypNum = Q931_TON_UNKNOWN; - CallingNum.NumPlanID = Q931_NUMPLAN_E164; - CallingNum.PresInd = Q931_PRES_ALLOWED; - CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED; - CallingNum.Size = CallingNum.Size + (unsigned char)strlen(caller_data->cid_num.digits); - gen->CallingNum = Q931AppendIE(gen, (L3UCHAR *) &CallingNum); - ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf); - ftdm_copy_string((char *)ptrCallingNum->Digit, caller_data->cid_num.digits, strlen(caller_data->cid_num.digits)+1); - - - /* - * Called number IE - */ - Q931InitIECalledNum(&CalledNum); - CalledNum.TypNum = Q931_TON_UNKNOWN; - CalledNum.NumPlanID = Q931_NUMPLAN_E164; - CalledNum.Size = CalledNum.Size + (unsigned char)strlen(caller_data->ani.digits); - gen->CalledNum = Q931AppendIE(gen, (L3UCHAR *) &CalledNum); - ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf); - ftdm_copy_string((char *)ptrCalledNum->Digit, caller_data->ani.digits, strlen(caller_data->ani.digits)+1); - - /* - * High-Layer Compatibility IE (Note: Required for AVM FritzBox) - */ - Q931InitIEHLComp(&HLComp); - HLComp.CodStand = Q931_CODING_ITU; /* ITU */ - HLComp.Interpret = 4; /* only possible value */ - HLComp.PresMeth = 1; /* High-layer protocol profile */ - HLComp.HLCharID = 1; /* Telephony = 1, Fax G2+3 = 4, Fax G4 = 65 (Class I)/ 68 (Class II or III) */ - gen->HLComp = Q931AppendIE(gen, (L3UCHAR *) &HLComp); - - caller_data->call_state = FTDM_CALLER_STATE_DIALING; - Q931Rx43(&isdn_data->q931, gen, gen->Size); - - isdn_data->outbound_crv[gen->CRV] = caller_data; - //isdn_data->channels_local_crv[gen->CRV] = ftdmchan; - - while (ftdm_running() && caller_data->call_state == FTDM_CALLER_STATE_DIALING) { - ftdm_sleep(1); - - if (!--sanity) { - caller_data->call_state = FTDM_CALLER_STATE_FAIL; - break; - } - } - isdn_data->outbound_crv[gen->CRV] = NULL; - - if (caller_data->call_state == FTDM_CALLER_STATE_SUCCESS) { - ftdm_channel_t *new_chan = NULL; - int fail = 1; - - new_chan = NULL; - if (caller_data->chan_id > 0 && caller_data->chan_id <= ftdm_span_get_chan_count(span)) { - new_chan = ftdm_span_get_channel(span, caller_data->chan_id); - } - - if (new_chan && (status = ftdm_channel_open_chan(new_chan) == FTDM_SUCCESS)) { - if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE) || new_chan->state != FTDM_CHANNEL_STATE_DOWN) { - if (new_chan->state == FTDM_CHANNEL_STATE_DOWN || new_chan->state >= FTDM_CHANNEL_STATE_TERMINATING) { - int x = 0; - ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n"); - - for (x = 0; x < 200; x++) { - if (!ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) { - break; - } - ftdm_sleep(5); - } - } - if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) { - ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n", - new_chan->span_id, - new_chan->chan_id, - new_chan->physical_span_id, - new_chan->physical_chan_id - ); - new_chan = NULL; - } - } - - if (new_chan && new_chan->state == FTDM_CHANNEL_STATE_DOWN) { - struct Q931_Call *call = NULL; - - memset(&new_chan->caller_data, 0, sizeof(new_chan->caller_data)); - ftdm_set_flag(new_chan, FTDM_CHANNEL_OUTBOUND); - ftdm_set_state_locked(new_chan, FTDM_CHANNEL_STATE_DIALING); - - call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV); - Q931CallSetPrivate(call, new_chan); - - switch(gen->MesType) { - case Q931mes_ALERTING: - new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA; - break; - case Q931mes_CONNECT: - new_chan->init_state = FTDM_CHANNEL_STATE_UP; - break; - default: - new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS; - break; - } - - fail = 0; - } - } - - if (!fail) { - *ftdmchan = new_chan; - return FTDM_SUCCESS; - } else { - Q931ie_Cause cause; - gen->MesType = Q931mes_DISCONNECT; - cause.IEId = Q931ie_CAUSE; - cause.Size = sizeof(Q931ie_Cause); - cause.CodStand = 0; - cause.Location = 1; - cause.Recom = 1; - //should we be casting here.. or do we need to translate value? - cause.Value = (unsigned char) FTDM_CAUSE_WRONG_CALL_STATE; - *cause.Diag = '\0'; - gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause); - Q931Rx43(&isdn_data->q931, gen, gen->Size); - - if (gen->CRV) { - Q931ReleaseCRV(&isdn_data->q931, gen->CRV); - } - - if (new_chan) { - ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n"); - } else { - ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n"); - } - } - } - - *ftdmchan = NULL; - return FTDM_FAIL; - -} -#endif /* __TODO__ */ - -static L3INT ftdm_isdn_931_err(void *pvt, L3INT id, L3INT p1, L3INT p2) -{ - ftdm_log(FTDM_LOG_ERROR, "ERROR: [%s] [%d] [%d]\n", q931_error_to_name(id), p1, p2); - return 0; -} - -/** - * \brief The new call event handler - * \note W000t!!! \o/ ;D - * \todo A lot - */ -static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *event, void *priv) -{ - Q931_TrunkInfo_t *trunk = NULL; - ftdm_isdn_data_t *isdn_data = NULL; - ftdm_span_t *span = priv; - - assert(span); - assert(call); - assert(event); - - trunk = Q931CallGetTrunk(call); - assert(trunk); - - isdn_data = span->signal_data; - assert(isdn_data); - - if (Q931CallIsGlobal(call)) { - /* - * Global event - */ - ftdm_log(FTDM_LOG_DEBUG, "Received global event from Q.931\n"); - } else { - ftdm_channel_t *ftdmchan = NULL; - ftdm_sigmsg_t sig; - int call_crv = Q931CallGetCRV(call); - int type; - - /* - * Call-specific event - */ - ftdm_log(FTDM_LOG_DEBUG, "Received call-specific event from Q.931 for call %d [%hu]\n", Q931CallGetCRV(call), Q931CallGetCRV(call)); - - /* - * Try to get associated zap channel - * and init sigmsg struct if there is one - */ - ftdmchan = Q931CallGetPrivate(call); - if (ftdmchan) { - memset(&sig, 0, sizeof(ftdm_sigmsg_t)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - } - - type = Q931CallEventGetType(event); - - if (type == Q931_EVENT_TYPE_CRV) { - - ftdm_log(FTDM_LOG_DEBUG, "\tCRV event\n"); - - switch (Q931CallEventGetId(event)) { - case Q931_EVENT_RELEASE_CRV: - { - /* WARNING contains old interface code, yuck! */ - if (!ftdmchan) { - ftdm_log(FTDM_LOG_DEBUG, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv); - return; - } - - if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN && - ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_HANGUP_COMPLETE) - { - ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d not in DOWN state, cleaning up\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan)); - - /* - * Send hangup signal to mod_freetdm - */ - if (!sig.channel->caller_data.hangup_cause) { - sig.channel->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; - } - - sig.event_id = FTDM_SIGEVENT_STOP; - ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig); - - /* Release zap channel */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - return; - } - break; - default: - ftdm_log(FTDM_LOG_ERROR, "Unknown CRV event: %d\n", Q931CallEventGetId(event)); - return; - } - } - else if (type == Q931_EVENT_TYPE_TIMER) { - struct Q931_CallTimerEvent *timer_evt = Q931CallEventGetData(event); - - ftdm_log(FTDM_LOG_DEBUG, "\tTimer event\n"); - assert(timer_evt->id); - - switch (timer_evt->id) { - case Q931_TIMER_T303: - /* - * SETUP timeout - * - * TE-mode: Q931_EVENT_SETUP_CONFIRM (error) - * NT-mode: Q931_EVENT_RELEASE_INDICATION - */ - { - /* WARNING contains old interface code, yuck! */ - if (!ftdmchan) { - ftdm_log(FTDM_LOG_ERROR, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv); - return; - } - - ftdm_log(FTDM_LOG_DEBUG, "Call setup failed on channel %d:%d\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan)); - - /* - * Send signal to mod_freetdm - */ - sig.channel->caller_data.hangup_cause = FTDM_CAUSE_NETWORK_OUT_OF_ORDER; - - sig.event_id = FTDM_SIGEVENT_STOP; - ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig); - - /* Release zap channel */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - return; - } - break; - - default: - ftdm_log(FTDM_LOG_ERROR, "Unhandled timer event %d\n", timer_evt->id); - } - } - else if (type == Q931_EVENT_TYPE_MESSAGE) { - struct Q931_CallMessageEvent *msg_evt = Q931CallEventGetData(event); - - ftdm_log(FTDM_LOG_DEBUG, "\tMessage event\n"); - assert(msg_evt); - - /* - * Slowly move stuff from the old event handler into this part... - */ - switch (Q931CallEventGetId(event)) { - case Q931_EVENT_SETUP_CONFIRM: - case Q931_EVENT_SETUP_COMPLETE_INDICATION: /* CONNECT */ - { - /* WARNING contains old interface code, yuck! */ - if (!ftdmchan) { - ftdm_log(FTDM_LOG_ERROR, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv); - return; - } - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - } - break; - - default: - ftdm_log(FTDM_LOG_DEBUG, "Not yet handled message event %d\n", Q931CallEventGetId(event)); - } - } - else { - ftdm_log(FTDM_LOG_ERROR, "Unknown event type %d\n", type); - } - } -} - -/** - * Copy callednum, readding prefix as needed - */ -static void __isdn_get_number(const char *digits, const int ton, char *buf, int size) -{ - int offset = 0; - - if (!digits || !buf || size <= 0) - return; - - switch (ton) { - case Q931_TON_NATIONAL: - offset = strlen(DEFAULT_NATIONAL_PREFIX); - memcpy(buf, DEFAULT_NATIONAL_PREFIX, offset); - break; - case Q931_TON_INTERNATIONAL: - offset = strlen(DEFAULT_INTERNATIONAL_PREFIX); - memcpy(buf, DEFAULT_INTERNATIONAL_PREFIX, offset); - break; - default: - break; - } - - strncpy(&buf[offset], digits, size - (offset + 1)); - buf[size - 1] = '\0'; -} - -#define isdn_get_number(num, buf) \ - __isdn_get_number((const char *)(num)->Digit, (num)->TypNum, (char *)buf, sizeof(buf)) - - -/** - * \brief The old call event handler (err, call message handler) - * \todo This one must die! - */ -static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic *msg, int mlen) -{ - Q931mes_Generic *gen = (Q931mes_Generic *) msg; - ftdm_span_t *span = (ftdm_span_t *) pvt; - ftdm_isdn_data_t *isdn_data = span->signal_data; - ftdm_channel_t *ftdmchan = NULL; - int chan_id = 0; - int chan_hunt = 0; - - if (Q931IsIEPresent(gen->ChanID)) { - Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf); - - if (chanid->IntType) - chan_id = chanid->ChanSlot; - else - chan_id = chanid->InfoChanSel; - - /* "any" channel specified */ - if (chanid->InfoChanSel == 3) { - chan_hunt++; - } - } else if (FTDM_SPAN_IS_NT(span)) { - /* no channel ie */ - chan_hunt++; - } - - assert(span != NULL); - assert(isdn_data != NULL); - - /* ftdm channel is stored in call private */ - if (call) { - ftdmchan = Q931CallGetPrivate(call); - if (!ftdmchan) { - ftdm_log(FTDM_LOG_DEBUG, "[s%d] No channel associated to call [%#x] private\n", - ftdm_span_get_id(span), Q931CallGetCRV(call)); - } - } - - ftdm_log(FTDM_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d] CRV: %d (%#hx, CTX: %s)\n", - gen->MesType, gen->Size, gen->CRV, gen->CRV, gen->CRVFlag ? "Terminator" : "Originator"); - -#ifdef __TODO__ - /* - * This code block is needed for isdn_channel_request() - * isdn_data->outbound_crv has been removed so another way to pass data around is required - */ - if (gen->CRVFlag && (caller_data = isdn_data->outbound_crv[gen->CRV])) { - if (chan_id) { - caller_data->chan_id = chan_id; - } - - switch(gen->MesType) { - case Q931mes_STATUS: - case Q931mes_CALL_PROCEEDING: - break; - case Q931mes_ALERTING: - case Q931mes_PROGRESS: - case Q931mes_CONNECT: - caller_data->call_state = FTDM_CALLER_STATE_SUCCESS; - break; - default: - caller_data->call_state = FTDM_CALLER_STATE_FAIL; - break; - } - - return 0; - } -#endif - ftdm_log(FTDM_LOG_DEBUG, "ftdmchan %p (%d:%d) via CRV[%#hx]\n", - ftdmchan, - ((ftdmchan) ? ftdm_channel_get_span_id(ftdmchan) : -1), - ((ftdmchan) ? ftdm_channel_get_id(ftdmchan) : -1), - gen->CRV); - - if (gen->ProtDisc == 3) { - switch(gen->MesType) { - case Q931mes_SERVICE: - { - Q931ie_ChangeStatus *changestatus = Q931GetIEPtr(gen->ChangeStatus, gen->buf); - if (ftdmchan) { - switch (changestatus->NewStatus) { - case 0: /* change status to "in service" */ - { - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED); - ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d in service\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan)); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - break; - case 1: - { /* change status to "maintenance" */ - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - break; - case 2: - { /* change status to "out of service" */ - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - break; - default: /* unknown */ - { - break; - } - } - } - } - break; - default: - break; - } - } else { - switch(gen->MesType) { - case Q931mes_RESTART: - { - if (chan_id) { - ftdmchan = ftdm_span_get_channel(span, chan_id); - } - if (ftdmchan) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } else { - uint32_t i; - - for (i = 1; i < ftdm_span_get_chan_count(span); i++) { - ftdmchan = ftdm_span_get_channel(span, chan_id); - - /* Skip channels that are down and D-Channels (#OpenZAP-39) */ - if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN || - ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_DQ921) - continue; - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - } - } - break; - case Q931mes_RELEASE: - case Q931mes_RELEASE_COMPLETE: - { - const char *what = gen->MesType == Q931mes_RELEASE ? "Release" : "Release Complete"; - if (ftdmchan) { - if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_TERMINATING || - ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_HANGUP) - { - if (gen->MesType == Q931mes_RELEASE) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - else if (gen->MesType == Q931mes_RELEASE_COMPLETE && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALTONE) { - /* Go DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - else if ((gen->MesType == Q931mes_RELEASE && ftdm_channel_get_state(ftdmchan) <= FTDM_CHANNEL_STATE_UP) || - (gen->MesType == Q931mes_RELEASE_COMPLETE && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALING)) { - - /* - * Don't keep inbound channels open if the remote side hangs up before we answered - */ - Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf); - ftdm_sigmsg_t sig; - - memset(&sig, 0, sizeof(sig)); - sig.span_id = ftdm_channel_get_span_id(ftdmchan); - sig.chan_id = ftdm_channel_get_id(ftdmchan); - sig.channel = ftdmchan; - sig.channel->caller_data.hangup_cause = (cause) ? cause->Value : FTDM_CAUSE_NORMAL_UNSPECIFIED; - - sig.event_id = FTDM_SIGEVENT_STOP; - ftdm_span_send_signal(span, &sig); - - ftdm_log(FTDM_LOG_DEBUG, "Received %s in state %s, requested hangup for channel %d:%d\n", what, - ftdm_channel_get_state_str(ftdmchan), - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan)); - } else { - ftdm_log(FTDM_LOG_DEBUG, "Ignoring %s on channel %d in state %s\n", what, - ftdm_channel_get_id(ftdmchan), ftdm_channel_get_state_str(ftdmchan)); - } - } else { - ftdm_log(FTDM_LOG_CRIT, "Received %s with no matching channel %d\n", what, chan_id); - } - } - break; - case Q931mes_DISCONNECT: - { - if (ftdmchan) { - Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf); - ftdmchan->caller_data.hangup_cause = cause->Value; - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } else { - ftdm_log(FTDM_LOG_CRIT, "Received Disconnect with no matching channel %d\n", chan_id); - } - } - break; - case Q931mes_ALERTING: - { - if (ftdmchan) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { - ftdm_log(FTDM_LOG_CRIT, "Received Alerting with no matching channel %d\n", chan_id); - } - } - break; - case Q931mes_PROGRESS: - { - if (ftdmchan) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } else { - ftdm_log(FTDM_LOG_CRIT, "Received Progress with no matching channel %d\n", chan_id); - } - } - break; - case Q931mes_CONNECT: -#if 0 /* Handled by new event code */ - { - if (ftdmchan) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - -#if 0 /* Auto-Ack is enabled, we actually don't need this */ - gen->MesType = Q931mes_CONNECT_ACKNOWLEDGE; - gen->CRVFlag = 0; /* outbound */ - Q931Rx43(&isdn_data->q931, gen, gen->Size); -#endif - } else { - ftdm_log(FTDM_LOG_CRIT, "Received Connect with no matching channel %d\n", chan_id); - } - } -#endif - break; - case Q931mes_SETUP: - { - Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf); - Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf); - int overlap_dial = 0; - int fail_cause = 0; - int fail = 1; - - if (ftdmchan && ftdmchan == Q931CallGetPrivate(call)) { - ftdm_log(FTDM_LOG_INFO, "Duplicate SETUP message(?) for Channel %d:%d ~ %d:%d in state %s [ignoring]\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), - ftdm_channel_get_ph_span_id(ftdmchan), - ftdm_channel_get_ph_id(ftdmchan), - ftdm_channel_get_state_str(ftdmchan)); - break; - } - - ftdmchan = NULL; - /* - * Channel selection for incoming calls: - */ - if (FTDM_SPAN_IS_NT(span) && chan_hunt) { - int x; - - /* - * In NT-mode with channel selection "any", - * try to find a free channel - */ - for (x = 1; x <= ftdm_span_get_chan_count(span); x++) { - ftdm_channel_t *zc = ftdm_span_get_channel(span, x); - - if (!ftdm_test_flag(zc, FTDM_CHANNEL_INUSE) && ftdm_channel_get_state(zc) == FTDM_CHANNEL_STATE_DOWN) { - ftdmchan = zc; - break; - } - } - } - else if (!FTDM_SPAN_IS_NT(span) && chan_hunt) { - /* - * In TE-mode this ("any") is invalid - */ - fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE; - - ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (network side didn't specify a channel)\n"); - } - else { - /* - * Otherwise simply try to select the channel we've been told - * - * TODO: NT mode is abled to select a different channel if the one chosen - * by the TE side is already in use - */ - if (chan_id > 0 && chan_id < FTDM_MAX_CHANNELS_SPAN && chan_id <= ftdm_span_get_chan_count(span)) { - ftdmchan = ftdm_span_get_channel(span, chan_id); - } - else { - /* invalid channel id */ - fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE; - - ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (none selected or out of bounds)\n"); - } - } - - if (!callednum || ftdm_strlen_zero((char *)callednum->Digit)) { - if (FTDM_SPAN_IS_NT(span)) { - ftdm_log(FTDM_LOG_NOTICE, "No destination number found, assuming overlap dial\n"); - overlap_dial++; - } else { - ftdm_log(FTDM_LOG_ERROR, "No destination number found\n"); - ftdmchan = NULL; - } - } - - if (ftdmchan) { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) || ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) { - if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN || ftdm_channel_get_state(ftdmchan) >= FTDM_CHANNEL_STATE_TERMINATING) - { - int x = 0; - ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), - ftdm_channel_get_ph_span_id(ftdmchan), - ftdm_channel_get_ph_id(ftdmchan)); - - for (x = 0; x < 200; x++) { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) { - break; - } - ftdm_sleep(5); - } - } - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) { - ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), - ftdm_channel_get_ph_span_id(ftdmchan), - ftdm_channel_get_ph_id(ftdmchan)); - ftdmchan = NULL; - } - } - - if (ftdmchan && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan); - - memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - - if (ftdmchan->call_data) { - memset(ftdmchan->call_data, 0, sizeof(ftdm_isdn_bchan_data_t)); - } - - /* copy number readd prefix as needed */ - isdn_get_number(callingnum, caller_data->cid_num.digits); - isdn_get_number(callingnum, caller_data->cid_name); - isdn_get_number(callingnum, caller_data->ani.digits); - - if (!overlap_dial) { - isdn_get_number(callednum, caller_data->dnis.digits); - } - - ftdmchan->caller_data.call_reference = gen->CRV; - Q931CallSetPrivate(call, ftdmchan); - - gen->CRVFlag = !(gen->CRVFlag); - - fail = 0; - } - } - - if (fail) { - Q931ie_Cause cause; - - gen->MesType = Q931mes_DISCONNECT; - gen->CRVFlag = 1; /* inbound call */ - - cause.IEId = Q931ie_CAUSE; - cause.Size = sizeof(Q931ie_Cause); - cause.CodStand = Q931_CODING_ITU; - cause.Location = 1; - cause.Recom = 1; - //should we be casting here.. or do we need to translate value? - cause.Value = (unsigned char)((fail_cause) ? fail_cause : FTDM_CAUSE_WRONG_CALL_STATE); - *cause.Diag = '\0'; - gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause); - Q931Rx43(&isdn_data->q931, gen, gen->Size); - - if (gen->CRV) { - Q931ReleaseCRV(&isdn_data->q931, gen->CRV); - } - - if (ftdmchan) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Channel is busy\n"); - } else { - ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n"); - } - - } else { - Q931ie_ChanID ChanID; - - /* - * Update Channel ID IE - */ - Q931InitIEChanID(&ChanID); - ChanID.IntType = FTDM_SPAN_IS_BRI(ftdmchan->span) ? 0 : 1; /* PRI = 1, BRI = 0 */ - ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdmchan->span) ? 1 : 0; /* Exclusive in NT-mode = 1, Preferred otherwise = 0 */ - if (ChanID.IntType) { - ChanID.InfoChanSel = 1; /* None = 0, See Slot = 1, Any = 3 */ - ChanID.ChanMapType = 3; /* B-Chan */ - ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan); - } else { - ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03; /* None = 0, B1 = 1, B2 = 2, Any = 3 */ - } - gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID); - - if (overlap_dial) { - Q931ie_ProgInd progress; - - /* - * Setup Progress indicator - */ - progress.IEId = Q931ie_PROGRESS_INDICATOR; - progress.Size = sizeof(Q931ie_ProgInd); - progress.CodStand = Q931_CODING_ITU; /* ITU */ - progress.Location = 1; /* private network serving the local user */ - progress.ProgDesc = 8; /* call is not end-to-end isdn = 1, in-band information available = 8 */ - gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *) &progress); - - /* - * Send SETUP ACK - */ - gen->MesType = Q931mes_SETUP_ACKNOWLEDGE; - gen->CRVFlag = 1; /* inbound call */ - Q931Rx43(&isdn_data->q931, gen, gen->Size); - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALTONE); - } else { - /* - * Advance to RING state - */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - } - } - break; - - case Q931mes_CALL_PROCEEDING: - { - if (ftdmchan) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received CALL PROCEEDING message for channel\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } else { - ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING with no matching channel %d\n", chan_id); - } - } - break; - case Q931mes_CONNECT_ACKNOWLEDGE: - { - if (ftdmchan) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Received CONNECT_ACK message for channel\n"); - } else { - ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK with no matching channel %d\n", chan_id); - } - } - break; - - case Q931mes_INFORMATION: - { - if (ftdmchan) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received INFORMATION message for channel\n"); - - if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALTONE) { - char digit = '\0'; - - /* - * overlap dial digit indication - */ - if (Q931IsIEPresent(gen->CalledNum)) { - ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->call_data; - Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf); - int pos; - - digit = callednum->Digit[strlen((char *)callednum->Digit) - 1]; - if (digit == '#') { - callednum->Digit[strlen((char *)callednum->Digit) - 1] = '\0'; - } - - /* TODO: make this more safe with strncat() */ - pos = strlen(ftdmchan->caller_data.dnis.digits); - strcat(&ftdmchan->caller_data.dnis.digits[pos], (char *)callednum->Digit); - - /* update timer */ - data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout; - - ftdm_log(FTDM_LOG_DEBUG, "Received new overlap digit (%s), destination number: %s\n", callednum->Digit, ftdmchan->caller_data.dnis.digits); - } - - if (Q931IsIEPresent(gen->SendComplete) || digit == '#') { - ftdm_log(FTDM_LOG_DEBUG, "Leaving overlap dial mode\n"); - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - } - } else { - ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message with no matching channel\n"); - } - } - break; - - default: - ftdm_log(FTDM_LOG_CRIT, "Received unhandled message %d (%#x)\n", (int)gen->MesType, (int)gen->MesType); - break; - } - } - - return 0; -} - -static int ftdm_isdn_921_23(void *pvt, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *msg, L2INT mlen) -{ - ftdm_span_t *span = pvt; - ftdm_isdn_data_t *isdn_data = span->signal_data; - int ret, offset = (ind == Q921_DL_DATA) ? 4 : 3; - char bb[4096] = ""; - - switch(ind) { - case Q921_DL_DATA: - case Q921_DL_UNIT_DATA: - print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb)); - ftdm_log(FTDM_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)mlen - offset, LINE, bb); -#ifdef HAVE_PCAP - if (isdn_pcap_capture_l3only(isdn_data)) { - isdn_pcap_write(isdn_data, msg, mlen, (ind == Q921_DL_UNIT_DATA) ? ISDN_PCAP_INCOMING_BCAST : ISDN_PCAP_INCOMING); - } -#endif - default: - ret = Q931Rx23(&isdn_data->q931, ind, tei, msg, mlen); - if (ret != 0) - ftdm_log(FTDM_LOG_DEBUG, "931 parse error [%d] [%s]\n", ret, q931_error_to_name(ret)); - break; - } - - return ((ret >= 0) ? 1 : 0); -} - -static int ftdm_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen) -{ - ftdm_span_t *span = (ftdm_span_t *) pvt; - ftdm_size_t len = (ftdm_size_t) mlen; - ftdm_isdn_data_t *isdn_data = span->signal_data; - - assert(span != NULL); - -#ifdef HAVE_PCAP - if (isdn_pcap_capture_both(isdn_data)) { - isdn_pcap_write(isdn_data, msg, mlen, ISDN_PCAP_OUTGOING); - } -#endif - return ftdm_channel_write(isdn_data->dchan, msg, len, &len) == FTDM_SUCCESS ? 0 : -1; -} - -static __inline__ void state_advance(ftdm_channel_t *ftdmchan) -{ - ftdm_span_t *span = ftdm_channel_get_span(ftdmchan); - ftdm_isdn_data_t *isdn_data = NULL; - ftdm_sigmsg_t sig; - ftdm_status_t status; - - Q931mes_Generic empty_gen; - Q931mes_Generic *gen = &empty_gen; - struct Q931_Call *call = NULL; - - Q931InitMesGeneric(gen); - - isdn_data = span->signal_data; - assert(isdn_data); - - call = Q931GetCallByCRV(&isdn_data->q931, ftdmchan->caller_data.call_reference); - if (call) { - gen->CRV = Q931CallGetCRV(call); - gen->CRVFlag = Q931CallGetDirection(call) == Q931_DIRECTION_INBOUND ? 1 : 0; - } - - ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), - ftdm_channel_get_state_str(ftdmchan)); - - memset(&sig, 0, sizeof(sig)); - sig.span_id = ftdm_channel_get_span_id(ftdmchan); - sig.chan_id = ftdm_channel_get_id(ftdmchan); - sig.channel = ftdmchan; - - /* Acknowledge channel state change */ - ftdm_channel_complete_state(ftdmchan); - - switch (ftdm_channel_get_state(ftdmchan)) { - case FTDM_CHANNEL_STATE_DOWN: - { - if (gen->CRV) { - Q931CallSetPrivate(call, NULL); - Q931ReleaseCRV(&isdn_data->q931, gen->CRV); - } - ftdmchan->caller_data.call_reference = 0; - ftdm_channel_close(&ftdmchan); - } - break; - case FTDM_CHANNEL_STATE_PROGRESS: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS; - if ((status = ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig) != FTDM_SUCCESS)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - gen->MesType = Q931mes_CALL_PROCEEDING; - - if (FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan))) { - Q931ie_ChanID ChanID; - - /* - * Set new Channel ID - */ - Q931InitIEChanID(&ChanID); - ChanID.IntType = FTDM_SPAN_IS_BRI(ftdm_channel_get_span(ftdmchan)) ? 0 : 1; /* PRI = 1, BRI = 0 */ - ChanID.PrefExcl = 1; /* always exclusive in NT-mode */ - - if (ChanID.IntType) { - ChanID.InfoChanSel = 1; /* None = 0, See Slot = 1, Any = 3 */ - ChanID.ChanMapType = 3; /* B-Chan */ - ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan); - } else { - ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03; /* None = 0, B1 = 1, B2 = 2, Any = 3 */ - } - gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID); - } - - Q931Rx43(&isdn_data->q931, gen, gen->Size); - } - } - break; - case FTDM_CHANNEL_STATE_DIALTONE: - { - ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->call_data; - - if (data) { - data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout; - } - } - break; - case FTDM_CHANNEL_STATE_RING: - { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_START; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } - } - break; - case FTDM_CHANNEL_STATE_RESTART: - { - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED; - sig.event_id = FTDM_SIGEVENT_RESTART; - status = ftdm_span_send_signal(span, &sig); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - return; - } - } - gen->MesType = Q931mes_ALERTING; - Q931Rx43(&isdn_data->q931, gen, gen->Size); - } - } - break; - case FTDM_CHANNEL_STATE_UP: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_UP; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - return; - } - } - - gen->MesType = Q931mes_CONNECT; - - Q931Rx43(&isdn_data->q931, gen, gen->Size); - } - } - break; - case FTDM_CHANNEL_STATE_DIALING: - if (!(isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan); - Q931ie_BearerCap BearerCap; - Q931ie_ChanID ChanID; - Q931ie_CallingNum CallingNum; - Q931ie_CallingNum *ptrCallingNum; - Q931ie_CalledNum CalledNum; - Q931ie_CalledNum *ptrCalledNum; - Q931ie_Display Display, *ptrDisplay; - Q931ie_HLComp HLComp; /* High-Layer Compatibility IE */ - Q931ie_ProgInd Progress; /* Progress Indicator IE */ - int codec = 0; - - /* - * get codec type - */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_NATIVE_CODEC, &codec); - - /* - * Q.931 Setup Message - */ - Q931InitMesGeneric(gen); - gen->MesType = Q931mes_SETUP; - gen->CRVFlag = 0; /* outbound(?) */ - - /* - * Bearer Capability IE - */ - Q931InitIEBearerCap(&BearerCap); - BearerCap.CodStand = Q931_CODING_ITU; /* ITU-T = 0, ISO/IEC = 1, National = 2, Network = 3 */ - BearerCap.ITC = Q931_ITC_SPEECH; /* Speech */ - BearerCap.TransMode = 0; /* Circuit = 0, Packet = 1 */ - BearerCap.ITR = Q931_ITR_64K; /* 64k = 16, Packet mode = 0 */ - BearerCap.Layer1Ident = 1; - BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? 3 : 2; /* U-law = 2, A-law = 3 */ - gen->BearerCap = Q931AppendIE(gen, (L3UCHAR *) &BearerCap); - - /* - * ChannelID IE - */ - Q931InitIEChanID(&ChanID); - ChanID.IntType = FTDM_SPAN_IS_BRI(ftdm_channel_get_span(ftdmchan)) ? 0 : 1; /* PRI = 1, BRI = 0 */ - ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan)) ? 1 : 0; /* Exclusive in NT-mode = 1, Preferred otherwise = 0 */ - if (ChanID.IntType) { - ChanID.InfoChanSel = 1; /* None = 0, See Slot = 1, Any = 3 */ - ChanID.ChanMapType = 3; /* B-Chan */ - ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan); - } else { - ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03; /* None = 0, B1 = 1, B2 = 2, Any = 3 */ - } - gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID); - - /* - * Progress IE - */ - Q931InitIEProgInd(&Progress); - Progress.CodStand = Q931_CODING_ITU; /* 0 = ITU */ - Progress.Location = 0; /* 0 = User, 1 = Private Network */ - Progress.ProgDesc = 3; /* 1 = Not end-to-end ISDN */ - gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *)&Progress); - - /* - * Display IE - */ - if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE) && FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan))) { - Q931InitIEDisplay(&Display); - Display.Size = Display.Size + (unsigned char)strlen(caller_data->cid_name); - gen->Display = Q931AppendIE(gen, (L3UCHAR *) &Display); - ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf); - ftdm_copy_string((char *)ptrDisplay->Display, caller_data->cid_name, strlen(caller_data->cid_name) + 1); - } - - /* - * CallingNum IE - */ - Q931InitIECallingNum(&CallingNum); - CallingNum.TypNum = caller_data->ani.type; - CallingNum.NumPlanID = Q931_NUMPLAN_E164; - CallingNum.PresInd = Q931_PRES_ALLOWED; - CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED; - CallingNum.Size = CallingNum.Size + (unsigned char)strlen(caller_data->cid_num.digits); - gen->CallingNum = Q931AppendIE(gen, (L3UCHAR *) &CallingNum); - ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf); - ftdm_copy_string((char *)ptrCallingNum->Digit, caller_data->cid_num.digits, strlen(caller_data->cid_num.digits) + 1); - - /* - * CalledNum IE - */ - Q931InitIECalledNum(&CalledNum); - CalledNum.TypNum = Q931_TON_UNKNOWN; - CalledNum.NumPlanID = Q931_NUMPLAN_E164; - CalledNum.Size = CalledNum.Size + (unsigned char)strlen(caller_data->ani.digits); - gen->CalledNum = Q931AppendIE(gen, (L3UCHAR *) &CalledNum); - ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf); - ftdm_copy_string((char *)ptrCalledNum->Digit, caller_data->ani.digits, strlen(caller_data->ani.digits) + 1); - - /* - * High-Layer Compatibility IE (Note: Required for AVM FritzBox) - */ - Q931InitIEHLComp(&HLComp); - HLComp.CodStand = Q931_CODING_ITU; /* ITU */ - HLComp.Interpret = 4; /* only possible value */ - HLComp.PresMeth = 1; /* High-layer protocol profile */ - HLComp.HLCharID = Q931_HLCHAR_TELEPHONY; /* Telephony = 1, Fax G2+3 = 4, Fax G4 = 65 (Class I)/ 68 (Class II or III) */ /* TODO: make accessible from user layer */ - gen->HLComp = Q931AppendIE(gen, (L3UCHAR *) &HLComp); - - Q931Rx43(&isdn_data->q931, gen, gen->Size); - - /* - * Support code for the new event handling system - * Remove this as soon as we have the new api to set up calls - */ - if (gen->CRV) { - call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV); - if (call) { - ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV); - - Q931CallSetPrivate(call, ftdmchan); - ftdmchan->caller_data.call_reference = gen->CRV; - } - } - } - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - { - /* reply RELEASE with RELEASE_COMPLETE message */ - if (ftdm_channel_get_last_state(ftdmchan) == FTDM_CHANNEL_STATE_HANGUP) { - gen->MesType = Q931mes_RELEASE_COMPLETE; - - Q931Rx43(&isdn_data->q931, gen, gen->Size); - } - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - case FTDM_CHANNEL_STATE_HANGUP: - { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan); - Q931ie_Cause cause; - - ftdm_log(FTDM_LOG_DEBUG, "Hangup: Call direction %s\n", - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound"); - - cause.IEId = Q931ie_CAUSE; - cause.Size = sizeof(Q931ie_Cause); - cause.CodStand = Q931_CODING_ITU; /* ITU */ - cause.Location = 1; /* private network */ - cause.Recom = 1; /* */ - - /* - * BRI PTMP needs special handling here... - * TODO: cleanup / refine (see above) - */ - if (ftdm_channel_get_last_state(ftdmchan) == FTDM_CHANNEL_STATE_RING) { - /* - * inbound call [was: number unknown (= not found in routing state)] - * (in Q.931 spec terms: Reject request) - */ - if (!FTDM_SPAN_IS_NT(span)) { - gen->MesType = Q931mes_RELEASE_COMPLETE; /* TE mode: Reject call */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - gen->MesType = Q931mes_DISCONNECT; /* NT mode: Disconnect and wait */ - //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - } - - //cause.Value = (unsigned char) FTDM_CAUSE_UNALLOCATED; - cause.Value = (unsigned char) caller_data->hangup_cause; - *cause.Diag = '\0'; - gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause); - Q931Rx43(&isdn_data->q931, gen, gen->Size); - - /* we're done, release channel */ - ////ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - else if (ftdm_channel_get_last_state(ftdmchan) <= FTDM_CHANNEL_STATE_PROGRESS) { - /* - * just release all unanswered calls [was: inbound call, remote side hung up before we answered] - */ - gen->MesType = Q931mes_RELEASE; - - cause.Value = (unsigned char) caller_data->hangup_cause; - *cause.Diag = '\0'; - gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause); - Q931Rx43(&isdn_data->q931, gen, gen->Size); - - /* this will be triggered by the RELEASE_COMPLETE reply */ - /* ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); */ - } - else { - /* - * call connected, hangup - */ - gen->MesType = Q931mes_DISCONNECT; - - cause.Value = (unsigned char) caller_data->hangup_cause; - *cause.Diag = '\0'; - gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause); - Q931Rx43(&isdn_data->q931, gen, gen->Size); - } - } - break; - case FTDM_CHANNEL_STATE_TERMINATING: - { - ftdm_log(FTDM_LOG_DEBUG, "Terminating: Call direction %s\n", - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound"); - - sig.event_id = FTDM_SIGEVENT_STOP; - status = ftdm_span_send_signal(span, &sig); - - gen->MesType = Q931mes_RELEASE; - Q931Rx43(&isdn_data->q931, gen, gen->Size); - } - default: - break; - } -} - -static __inline__ void check_state(ftdm_span_t *span) -{ - if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) { - uint32_t j; - - ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE); - - for (j = 1; j <= ftdm_span_get_chan_count(span); j++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, j); - - if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_channel_lock(chan); - ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE); - state_advance(chan); - ftdm_channel_unlock(chan); - } - } - } -} - - -static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event) -{ - ftdm_alarm_flag_t alarmbits; - ftdm_sigmsg_t sig; - - memset(&sig, 0, sizeof(sig)); - sig.span_id = ftdm_channel_get_span_id(event->channel); - sig.chan_id = ftdm_channel_get_id(event->channel); - sig.channel = event->channel; - - ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n", - ftdm_oob_event2str(event->enum_id), - ftdm_channel_get_span_id(event->channel), - ftdm_channel_get_id(event->channel), - ftdm_channel_get_state_str(event->channel)); - - switch (event->enum_id) { - case FTDM_OOB_ALARM_TRAP: - { - sig.event_id = FTDM_OOB_ALARM_TRAP; - if (ftdm_channel_get_state(event->channel) != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RESTART); - } - ftdm_set_flag(event->channel, FTDM_CHANNEL_SUSPENDED); - ftdm_channel_get_alarms(event->channel, &alarmbits); - ftdm_span_send_signal(span, &sig); - - ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) has alarms [%s]\n", - ftdm_channel_get_span_id(event->channel), - ftdm_channel_get_id(event->channel), - ftdm_channel_get_ph_span_id(event->channel), - ftdm_channel_get_ph_id(event->channel), - ftdm_channel_get_last_error(event->channel)); - } - break; - case FTDM_OOB_ALARM_CLEAR: - { - sig.event_id = FTDM_OOB_ALARM_CLEAR; - ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED); - ftdm_channel_get_alarms(event->channel, &alarmbits); - ftdm_span_send_signal(span, &sig); - } - break; -#ifdef __BROKEN_BY_FREETDM_CONVERSION__ - case FTDM_OOB_DTMF: /* Taken from ozmod_analog, minus the CALLWAITING state handling */ - { - const char * digit_str = (const char *)event->data; - - if (digit_str) { - fio_event_cb_t event_callback = NULL; - - ftdm_channel_queue_dtmf(event->channel, digit_str); - if (span->event_callback) { - event_callback = span->event_callback; - } else if (event->channel->event_callback) { - event_callback = event->channel->event_callback; - } - - if (event_callback) { - event->channel->event_header.channel = event->channel; - event->channel->event_header.e_type = FTDM_EVENT_DTMF; - event->channel->event_header.data = (void *)digit_str; - event_callback(event->channel, &event->channel->event_header); - event->channel->event_header.e_type = FTDM_EVENT_NONE; - event->channel->event_header.data = NULL; - } - ftdm_safe_free(event->data); - } - } - break; -#endif - } - - return FTDM_SUCCESS; -} - - -static __inline__ void check_events(ftdm_span_t *span) -{ - ftdm_status_t status = ftdm_span_poll_event(span, 5, NULL); - - switch (status) { - case FTDM_SUCCESS: - { - ftdm_event_t *event; - - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { - if (event->enum_id == FTDM_OOB_NOOP) { - continue; - } - if (process_event(span, event) != FTDM_SUCCESS) { - break; - } - } - } - break; - case FTDM_FAIL: - { - ftdm_log(FTDM_LOG_DEBUG, "Event Failure! %d\n", ftdm_running()); - } - break; - default: - break; - } -} - - -static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map) -{ - ftdm_buffer_t *dt_buffer = ts->user_data; - int wrote; - - if (!dt_buffer) { - return -1; - } - - wrote = teletone_mux_tones(ts, map); - ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2); - return 0; -} - -static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_isdn_data_t *isdn_data = span->signal_data; - ftdm_buffer_t *dt_buffer = NULL; - teletone_generation_session_t ts = {{{{0}}}};; - unsigned char frame[1024]; - int x, interval; - - ftdm_log(FTDM_LOG_DEBUG, "ISDN tones thread starting.\n"); - ftdm_set_flag(isdn_data, FTDM_ISDN_TONES_RUNNING); - - if (ftdm_buffer_create(&dt_buffer, 1024, 1024, 0) != FTDM_SUCCESS) { - snprintf(isdn_data->dchan->last_error, sizeof(isdn_data->dchan->last_error), "memory error!"); - ftdm_log(FTDM_LOG_ERROR, "MEM ERROR\n"); - goto done; - } - ftdm_buffer_set_loops(dt_buffer, -1); - - /* get a tone generation friendly interval to avoid distortions */ - for (x = 1; x <= ftdm_span_get_chan_count(span); x++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, x); - - if (ftdm_channel_get_type(chan) != FTDM_CHAN_TYPE_DQ921) { - ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval); - break; - } - } - if (!interval) { - interval = 20; - } - ftdm_log(FTDM_LOG_NOTICE, "Tone generating interval %d\n", interval); - - /* init teletone */ - teletone_init_session(&ts, 0, teletone_handler, dt_buffer); - ts.rate = 8000; - ts.duration = ts.rate; - - /* main loop */ - while (ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) { - ftdm_wait_flag_t flags; - ftdm_status_t status; - int last_chan_state = 0; - int gated = 0; - L2ULONG now = ftdm_time_now(); - - /* - * check b-channel states and generate & send tones if neccessary - */ - for (x = 1; x <= ftdm_span_get_chan_count(span); x++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, x); - ftdm_size_t len = sizeof(frame), rlen; - ftdm_isdn_bchan_data_t *data = chan->call_data; - - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_DQ921) { - continue; - } - - /* - * Generate tones based on current bchan state - * (Recycle buffer content if succeeding channels share the - * same state, this saves some cpu cycles) - */ - switch (ftdm_channel_get_state(chan)) { - case FTDM_CHANNEL_STATE_DIALTONE: - { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - - /* check overlap dial timeout first before generating tone */ - if (data && data->digit_timeout && data->digit_timeout <= now) { - if (strlen(caller_data->dnis.digits) > 0) { - ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, advancing to RING state\n"); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RING); - } else { - /* no digits received, hangup */ - ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, no digits received, going to HANGUP state\n"); - caller_data->hangup_cause = FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE; /* TODO: probably wrong cause value */ - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - data->digit_timeout = 0; - continue; - } - - if (last_chan_state != ftdm_channel_get_state(chan)) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, span->tone_map[FTDM_TONEMAP_DIAL]); - last_chan_state = ftdm_channel_get_state(chan); - } - } - break; - - case FTDM_CHANNEL_STATE_RING: - { - if (last_chan_state != ftdm_channel_get_state(chan)) { - ftdm_buffer_zero(dt_buffer); - teletone_run(&ts, span->tone_map[FTDM_TONEMAP_RING]); - last_chan_state = ftdm_channel_get_state(chan); - } - } - break; - - default: /* Not in a tone generating state, go to next round */ - continue; - } - - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { - if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - continue; - } - ftdm_log(FTDM_LOG_NOTICE, "Successfully opened channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - } - - flags = FTDM_READ; - - status = ftdm_channel_wait(chan, &flags, (gated) ? 0 : interval); - switch (status) { - case FTDM_FAIL: - continue; - - case FTDM_TIMEOUT: - gated = 1; - continue; - - default: - if (!(flags & FTDM_READ)) { - continue; - } - } - gated = 1; - - status = ftdm_channel_read(chan, frame, &len); - if (status != FTDM_SUCCESS || len <= 0) { - continue; - } - - /* - * Teletone operates on SLIN data (2 bytes per sample). - * Convert the length of non-SLIN codecs, so we read - * the right amount of samples from the buffer. - */ - if (chan->effective_codec != FTDM_CODEC_SLIN) { - len *= 2; - } - - /* seek to current offset */ - ftdm_buffer_seek(dt_buffer, data->offset); - - /* - * ftdm_channel_read() can read up to sizeof(frame) bytes - * (in certain situations). Avoid overflowing the stack (and smashing dt_buffer) - * if the codec is not slin and we had to double the length. - */ - len = ftdm_min(len, sizeof(frame)); - rlen = ftdm_buffer_read_loop(dt_buffer, frame, len); - - if (chan->effective_codec != FTDM_CODEC_SLIN) { - fio_codec_t codec_func = NULL; - - if (chan->native_codec == FTDM_CODEC_ULAW) { - codec_func = fio_slin2ulaw; - } else if (chan->native_codec == FTDM_CODEC_ALAW) { - codec_func = fio_slin2alaw; - } - - /* - * Convert SLIN to native format (a-law/u-law), - * input size is 2 bytes per sample, output size - * (after conversion) is one byte per sample - * (= max. half the input size). - */ - if (codec_func) { - status = codec_func(frame, sizeof(frame), &rlen); - } else { - snprintf(chan->last_error, sizeof(chan->last_error), "codec error!"); - goto done; - } - } - - if (ftdm_channel_write(chan, frame, sizeof(frame), &rlen) == FTDM_SUCCESS) { - /* - * Advance offset in teletone buffer by amount - * of data actually written to channel. - */ - if (chan->effective_codec != FTDM_CODEC_SLIN) { - data->offset += rlen << 1; /* Teletone buffer is in SLIN (= rlen * 2) */ - } else { - data->offset += rlen; - } - - /* Limit offset to [0..Rate(Samples/s)-1] in SLIN (2 bytes per sample) units. */ - data->offset %= (ts.rate << 1); - } - } - - /* - * sleep a bit if there was nothing to do - */ - if (!gated) { - ftdm_sleep(interval); - } - } - -done: - if (ts.buffer) { - teletone_destroy_session(&ts); - } - - if (dt_buffer) { - ftdm_buffer_destroy(&dt_buffer); - } - - ftdm_log(FTDM_LOG_DEBUG, "ISDN tone thread ended.\n"); - ftdm_clear_flag(isdn_data, FTDM_ISDN_TONES_RUNNING); - - return NULL; -} - -static void *ftdm_isdn_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_isdn_data_t *isdn_data = span->signal_data; - unsigned char frame[1024]; - ftdm_size_t len = sizeof(frame); - int errs = 0; - -#ifdef WIN32 - timeBeginPeriod(1); -#endif - - ftdm_log(FTDM_LOG_DEBUG, "ISDN thread starting.\n"); - ftdm_set_flag(isdn_data, FTDM_ISDN_RUNNING); - - Q921Start(&isdn_data->q921); - Q931Start(&isdn_data->q931); - - while (ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) { - ftdm_wait_flag_t flags = FTDM_READ; - ftdm_status_t status = ftdm_channel_wait(isdn_data->dchan, &flags, 100); - - Q921TimerTick(&isdn_data->q921); - Q931TimerTick(&isdn_data->q931); - check_state(span); - check_events(span); - - /* - * - */ - switch (status) { - case FTDM_FAIL: - { - ftdm_log(FTDM_LOG_ERROR, "D-Chan Read Error!\n"); - snprintf(span->last_error, sizeof(span->last_error), "D-Chan Read Error!"); - if (++errs == 10) { - isdn_data->dchan->state = FTDM_CHANNEL_STATE_UP; - goto done; - } - } - break; - case FTDM_TIMEOUT: - { - errs = 0; - } - break; - default: - { - if (flags & FTDM_READ) { - len = sizeof(frame); - if (ftdm_channel_read(isdn_data->dchan, frame, &len) != FTDM_SUCCESS) { - ftdm_log_chan_msg(isdn_data->dchan, FTDM_LOG_ERROR, "Failed to read from D-Channel\n"); - continue; - } - if (len > 0) { -#ifdef HAVE_PCAP - if (isdn_pcap_capture_both(isdn_data)) { - isdn_pcap_write(isdn_data, frame, len, ISDN_PCAP_INCOMING); - } -#endif - Q921QueueHDLCFrame(&isdn_data->q921, frame, (int)len); - Q921Rx12(&isdn_data->q921); - - /* Successful read, reset error counter */ - errs = 0; - } - } else { - ftdm_log(FTDM_LOG_DEBUG, "No Read FLAG!\n"); - } - } - break; - } - } - -done: - ftdm_channel_close(&isdn_data->dchan); - ftdm_clear_flag(isdn_data, FTDM_ISDN_RUNNING); - -#ifdef WIN32 - timeEndPeriod(1); -#endif -#ifdef HAVE_PCAP - if (isdn_pcap_is_open(isdn_data)) { - isdn_pcap_close(isdn_data); - } -#endif - ftdm_log(FTDM_LOG_DEBUG, "ISDN thread ended.\n"); - return NULL; -} - -static int q931_rx_32(void *pvt, Q921DLMsg_t ind, L3UCHAR tei, L3UCHAR *msg, L3INT mlen) -{ - ftdm_span_t *span = pvt; - ftdm_isdn_data_t *isdn_data = span->signal_data; - int offset = 4; - char bb[4096] = ""; - - switch(ind) { - case Q921_DL_UNIT_DATA: - offset = 3; - - case Q921_DL_DATA: - print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb)); - ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)mlen - offset, LINE, bb); - break; - - default: - break; - } - -#ifdef HAVE_PCAP - if (isdn_pcap_capture_l3only(isdn_data)) { - isdn_pcap_write(isdn_data, msg, mlen, ISDN_PCAP_OUTGOING); - } -#endif - return Q921Rx32(&isdn_data->q921, ind, tei, msg, mlen); -} - -static int ftdm_isdn_q921_log(void *pvt, Q921LogLevel_t level, char *msg, L2INT size) -{ - ftdm_span_t *span = (ftdm_span_t *) pvt; - - ftdm_log("Span", "Q.921", span->span_id, (int)level, "%s", msg); - return 0; -} - -static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, const char *msg, L3INT size) -{ - ftdm_span_t *span = (ftdm_span_t *) pvt; - - ftdm_log("Span", "Q.931", span->span_id, (int)level, "%s", msg); - return 0; -} - -static ftdm_state_map_t isdn_state_map = { - { - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - - /****************************************/ - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, - FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - } -}; - -/** - * \brief Stop signalling on span - */ -static ftdm_status_t ftdm_isdn_stop(ftdm_span_t *span) -{ - ftdm_isdn_data_t *isdn_data = span->signal_data; - - if (!ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) { - return FTDM_FAIL; - } - - ftdm_set_flag(isdn_data, FTDM_ISDN_STOP); - - while (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) { - ftdm_sleep(100); - } - - while (ftdm_test_flag(isdn_data, FTDM_ISDN_TONES_RUNNING)) { - ftdm_sleep(100); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Start signalling on span - */ -static ftdm_status_t ftdm_isdn_start(ftdm_span_t *span) -{ - ftdm_isdn_data_t *isdn_data = span->signal_data; - ftdm_status_t ret; - - if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) { - return FTDM_FAIL; - } - - ftdm_clear_flag(isdn_data, FTDM_ISDN_STOP); - ret = ftdm_thread_create_detached(ftdm_isdn_run, span); - - if (ret != FTDM_SUCCESS) { - return ret; - } - - if (FTDM_SPAN_IS_NT(span) && !(isdn_data->opts & FTDM_ISDN_OPT_DISABLE_TONES)) { - ret = ftdm_thread_create_detached(ftdm_isdn_tones_run, span); - } - return ret; -} - - -/*###################################################################* - * (text) value parsing / translation - *###################################################################*/ - -static int32_t parse_loglevel(const char *level) -{ - if (!level) - return -1; - - if (!strcasecmp(level, "debug")) { - return FTDM_LOG_LEVEL_DEBUG; - } else if (!strcasecmp(level, "info")) { - return FTDM_LOG_LEVEL_INFO; - } else if (!strcasecmp(level, "notice")) { - return FTDM_LOG_LEVEL_NOTICE; - } else if (!strcasecmp(level, "warning")) { - return FTDM_LOG_LEVEL_WARNING; - } else if (!strcasecmp(level, "error")) { - return FTDM_LOG_LEVEL_ERROR; - } else if (!strcasecmp(level, "alert")) { - return FTDM_LOG_LEVEL_ALERT; - } else if (!strcasecmp(level, "crit")) { - return FTDM_LOG_LEVEL_CRIT; - } else if (!strcasecmp(level, "emerg")) { - return FTDM_LOG_LEVEL_EMERG; - } else { - return -1; - } -} - -static int parse_opts(const char *in, uint32_t *flags) -{ - if (!in || !flags) - return -1; - - if (strstr(in, "suggest_channel")) { - *flags |= FTDM_ISDN_OPT_SUGGEST_CHANNEL; - } - if (strstr(in, "omit_display")) { - *flags |= FTDM_ISDN_OPT_OMIT_DISPLAY_IE; - } - if (strstr(in, "disable_tones")) { - *flags |= FTDM_ISDN_OPT_DISABLE_TONES; - } - - return 0; -} - -static int parse_dialect(const char *in, uint32_t *dialect) -{ - if (!in || !dialect) - return -1; - -#if __UNSUPPORTED__ - if (!strcasecmp(in, "national")) { - *dialect = Q931_Dialect_National; - return 0; - } - if (!strcasecmp(in, "dms")) { - *dialect = Q931_Dialect_DMS; - return 0; - } -#endif - if (!strcasecmp(in, "5ess")) { - *dialect = Q931_Dialect_5ESS; - return 0; - } - if (!strcasecmp(in, "dss1") || !strcasecmp(in, "euroisdn")) { - *dialect = Q931_Dialect_DSS1; - return 0; - } - if (!strcasecmp(in, "q931")) { - *dialect = Q931_Dialect_Q931; - return 0; - } - - return -1; -} - - -/*###################################################################* - * API commands - *###################################################################*/ - -static const char isdn_api_usage[] = -#ifdef HAVE_PCAP - "isdn capture [q931only]\n" - "isdn capture \n" -#endif - "isdn loglevel \n" - "isdn dump calls\n" - "isdn help"; - - -/** - * isdn_api - */ -static FIO_API_FUNCTION(isdn_api) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (data) { - mycmd = strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (!argc || !strcasecmp(argv[0], "help")) { - stream->write_function(stream, "%s\n", isdn_api_usage); - goto done; - } - else if (!strcasecmp(argv[0], "dump")) { - ftdm_isdn_data_t *isdn_data = NULL; - ftdm_span_t *span = NULL; - int span_id = 0; - - /* dump calls */ - - if (argc < 3) { - stream->write_function(stream, "-ERR not enough arguments.\n"); - goto done; - } - - span_id = atoi(argv[1]); - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - isdn_data = span->signal_data; - } else { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - - if (!strcasecmp(argv[2], "calls")) { - /* dump all calls to log */ - Q931DumpAllCalls(&isdn_data->q931); - stream->write_function(stream, "+OK call information dumped to log\n"); - goto done; - } - } - else if (!strcasecmp(argv[0], "loglevel")) { - ftdm_isdn_data_t *isdn_data = NULL; - ftdm_span_t *span = NULL; - int span_id = 0; - int layer = 0; - int level = 0; - - /* loglevel [level] */ - - if (argc < 3) { - stream->write_function(stream, "-ERR not enough arguments.\n"); - goto done; - } - - span_id = atoi(argv[1]); - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - isdn_data = span->signal_data; - } else { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - - if (!strcasecmp(argv[2], "q921")) { - layer = 0x01; - } else if (!strcasecmp(argv[2], "q931")) { - layer = 0x02; - } else if (!strcasecmp(argv[2], "all")) { - layer = 0x03; - } else { - stream->write_function(stream, "-ERR invalid layer\n"); - goto done; - } - - if (argc > 3) { - /* set loglevel */ - if ((level = parse_loglevel(argv[3])) < 0) { - stream->write_function(stream, "-ERR invalid loglevel\n"); - goto done; - } - - if (layer & 0x01) { /* q921 */ - Q921SetLogLevel(&isdn_data->q921, (Q921LogLevel_t)level); - } - if (layer & 0x02) { /* q931 */ - Q931SetLogLevel(&isdn_data->q931, (Q931LogLevel_t)level); - } - stream->write_function(stream, "+OK loglevel set"); - } else { - /* get loglevel */ - if (layer & 0x01) { - stream->write_function(stream, "Q.921 loglevel: %s\n", - Q921GetLogLevelName(&isdn_data->q921)); - } - if (layer & 0x02) { - stream->write_function(stream, "Q.931 loglevel: %s\n", - Q931GetLogLevelName(&isdn_data->q931)); - } - stream->write_function(stream, "+OK"); - } - goto done; - } -#ifdef HAVE_PCAP - else if (!strcasecmp(argv[0], "capture")) { - ftdm_isdn_data_t *isdn_data = NULL; - ftdm_span_t *span = NULL; - int span_id = 0; - - /* capture [q931only] */ - /* capture */ - - if (argc < 3) { - stream->write_function(stream, "-ERR not enough arguments.\n"); - goto done; - } - - span_id = atoi(argv[1]); - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - isdn_data = span->signal_data; - } else { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - - if (!strcasecmp(argv[2], "start")) { - char *filename = NULL; - - if (argc < 4) { - stream->write_function(stream, "-ERR not enough parameters.\n"); - goto done; - } - - if (isdn_pcap_is_open(isdn_data)) { - stream->write_function(stream, "-ERR capture is already running.\n"); - goto done; - } - - filename = argv[3]; - - if (isdn_pcap_open(isdn_data, filename) != FTDM_SUCCESS) { - stream->write_function(stream, "-ERR failed to open capture file.\n"); - goto done; - } - - if (argc > 4 && !strcasecmp(argv[4], "q931only")) { - isdn_data->flags |= FTDM_ISDN_CAPTURE_L3ONLY; - } - isdn_pcap_start(isdn_data); - - stream->write_function(stream, "+OK capture started.\n"); - goto done; - } - else if (!strcasecmp(argv[2], "stop")) { - - if (!isdn_pcap_is_open(isdn_data)) { - stream->write_function(stream, "-ERR capture is not running.\n"); - goto done; - } - - isdn_pcap_stop(isdn_data); - isdn_pcap_close(isdn_data); - - stream->write_function(stream, "+OK capture stopped.\n"); - goto done; - } - else if (!strcasecmp(argv[2], "suspend")) { - - if (!isdn_pcap_is_open(isdn_data)) { - stream->write_function(stream, "-ERR capture is not running.\n"); - goto done; - } - isdn_pcap_stop(isdn_data); - - stream->write_function(stream, "+OK capture suspended.\n"); - goto done; - } - else if (!strcasecmp(argv[2], "resume")) { - - if (!isdn_pcap_is_open(isdn_data)) { - stream->write_function(stream, "-ERR capture is not running.\n"); - goto done; - } - isdn_pcap_start(isdn_data); - - stream->write_function(stream, "+OK capture resumed.\n"); - goto done; - } - else { - stream->write_function(stream, "-ERR wrong action.\n"); - goto done; - } - } -#endif - else { - stream->write_function(stream, "-ERR invalid command.\n"); - } -done: - ftdm_safe_free(mycmd); - - return FTDM_SUCCESS; -} - -static int parse_mode(const char *mode) -{ - if (!mode) - return -1; - - if (!strcasecmp(mode, "user") || !strcasecmp(mode, "cpe")) { - return Q931_TE; - } - if (!strcasecmp(mode, "net") || !strcasecmp(mode, "network")) { - return Q931_NT; - } - - return -1; -} - -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span) -{ - Q931Dialect_t dialect = Q931_Dialect_National; - ftdm_channel_t *dchan = NULL; - ftdm_isdn_data_t *isdn_data; - int32_t digit_timeout = 0; - const char *tonemap = "us"; - int dchan_count = 0, bchan_count = 0; - int q921loglevel = -1; - int q931loglevel = -1; - uint32_t i; - - if (span->signal_type) { - ftdm_log(FTDM_LOG_ERROR, "Span is already configured for signalling [%d]\n", span->signal_type); - snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d]", span->signal_type); - return FTDM_FAIL; - } - - if (ftdm_span_get_trunk_type(span) >= FTDM_TRUNK_NONE) { - ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1\n", ftdm_span_get_trunk_type_str(span)); - span->trunk_type = FTDM_TRUNK_T1; - } - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - - switch (ftdm_channel_get_type(chan)) { - case FTDM_CHAN_TYPE_DQ921: - if (dchan_count > 1) { - ftdm_log(FTDM_LOG_ERROR, "Span has more than 1 D-Channel!\n"); - snprintf(span->last_error, sizeof(span->last_error), "Span has more than 1 D-Channel!"); - return FTDM_FAIL; - } - - if (ftdm_channel_open(ftdm_span_get_id(span), i, &dchan) == FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_DEBUG, "opening d-channel #%d %d:%d\n", dchan_count, - ftdm_channel_get_span_id(dchan), ftdm_channel_get_id(dchan)); - dchan->state = FTDM_CHANNEL_STATE_UP; - } - - dchan_count++; - break; - - case FTDM_CHAN_TYPE_B: - bchan_count++; - break; - - default: - break; - } - } - if (!dchan_count) { - ftdm_log(FTDM_LOG_ERROR, "Span has no D-Channel!\n"); - snprintf(span->last_error, sizeof(span->last_error), "Span has no D-Channel!"); - return FTDM_FAIL; - } - if (!bchan_count) { - ftdm_log(FTDM_LOG_ERROR, "Span has no B-Channels!\n"); - snprintf(span->last_error, sizeof(span->last_error), "Span has no B-Channels!"); - return FTDM_FAIL; - } - - isdn_data = malloc(sizeof(*isdn_data)); - assert(isdn_data != NULL); - - memset(isdn_data, 0, sizeof(*isdn_data)); - dialect = Q931_Dialect_Q931; - - /* Use trunk_mode span parameter to set default */ - switch (ftdm_span_get_trunk_mode(span)) { - case FTDM_TRUNK_MODE_NET: - ftdm_log(FTDM_LOG_INFO, "Span '%s' [s%d] defaulting to NET mode\n", - ftdm_span_get_name(span), ftdm_span_get_id(span)); - isdn_data->mode = Q931_NT; - break; - default: - ftdm_log(FTDM_LOG_INFO, "Span '%s' [s%d] defaulting to USER mode\n", - ftdm_span_get_name(span), ftdm_span_get_id(span)); - isdn_data->mode = Q931_TE; - break; - } - - for (i = 0; ftdm_parameters[i].var; i++) { - const char *var = ftdm_parameters[i].var; - const char *val = ftdm_parameters[i].val; - - if (ftdm_strlen_zero(var)) { - ftdm_log(FTDM_LOG_WARNING, "Skipping variable with no name\n"); - continue; - } - - if (ftdm_strlen_zero(val)) { - ftdm_log(FTDM_LOG_ERROR, "Variable '%s' has no value\n", var); - return FTDM_FAIL; - } - - if (!strcasecmp(var, "mode")) { - if ((isdn_data->mode = parse_mode(val)) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown mode '%s'\n", val); - snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown mode [%s]!", val); - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "dialect")) { - if (parse_dialect(val, &dialect) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown dialect '%s'\n", val); - snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown dialect [%s]!", val); - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "opts")) { - if (parse_opts(val, &isdn_data->opts) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown options '%s'\n", val); - snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown options [%s]!", val); - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "tonemap")) { - tonemap = (const char *)val; - } else if (!strcasecmp(var, "digit_timeout")) { - digit_timeout = atoi(val); - if (digit_timeout < 3000 || digit_timeout > 30000) { - ftdm_log(FTDM_LOG_WARNING, "Digit timeout %d ms outside of range (3000 - 30000 ms), using default (10000 ms)\n", digit_timeout); - digit_timeout = DEFAULT_DIGIT_TIMEOUT; - } - } else if (!strcasecmp(var, "q921loglevel")) { - if ((q921loglevel = parse_loglevel(val)) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val); - snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val); - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "q931loglevel")) { - if ((q931loglevel = parse_loglevel(val)) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val); - snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val); - return FTDM_FAIL; - } - } else { - ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s'\n", var); - snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var); - return FTDM_FAIL; - } - } - - if (!digit_timeout) { - digit_timeout = DEFAULT_DIGIT_TIMEOUT; - } - - /* Check if modes match and log a message if they do not. Just to be on the safe side. */ - if (isdn_data->mode == Q931_TE && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) { - ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for TE/CPE/USER mode, while port is running in NT/NET mode. You may want to check your 'trunk_mode' settings.\n", - ftdm_span_get_name(span)); - } - else if (isdn_data->mode == Q931_NT && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_CPE) { - ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for NT/NET mode, while port is running in TE/CPE/USER mode. You may want to check your 'trunk_mode' settings.\n", - ftdm_span_get_name(span)); - } - - /* allocate per b-chan data */ - if (isdn_data->mode == Q931_NT) { - ftdm_isdn_bchan_data_t *data; - - data = malloc(bchan_count * sizeof(ftdm_isdn_bchan_data_t)); - if (!data) { - return FTDM_FAIL; - } - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++, data++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - chan->call_data = data; - memset(data, 0, sizeof(ftdm_isdn_bchan_data_t)); - } - } - } - - isdn_data->dchan = dchan; - isdn_data->digit_timeout = digit_timeout; - - Q921_InitTrunk(&isdn_data->q921, - 0, - 0, - isdn_data->mode, - (ftdm_span_get_trunk_type(span) == FTDM_TRUNK_BRI_PTMP) ? Q921_PTMP : Q921_PTP, - 0, - ftdm_isdn_921_21, - (Q921Tx23CB_t)ftdm_isdn_921_23, - span, - span); - - Q921SetLogCB(&isdn_data->q921, &ftdm_isdn_q921_log, span); - Q921SetLogLevel(&isdn_data->q921, (Q921LogLevel_t)q921loglevel); - - Q931InitTrunk(&isdn_data->q931, - dialect, - isdn_data->mode, - span->trunk_type, - ftdm_isdn_931_34, - (Q931Tx32CB_t)q931_rx_32, - ftdm_isdn_931_err, - span, - span); - - Q931SetLogCB(&isdn_data->q931, &ftdm_isdn_q931_log, span); - Q931SetLogLevel(&isdn_data->q931, (Q931LogLevel_t)q931loglevel); - - /* Register new event hander CB */ - Q931SetCallEventCB(&isdn_data->q931, ftdm_isdn_call_event, span); - - /* TODO: hmm, maybe drop the "Trunk" prefix */ - Q931TrunkSetAutoRestartAck(&isdn_data->q931, 1); - Q931TrunkSetAutoConnectAck(&isdn_data->q931, 1); - Q931TrunkSetAutoServiceAck(&isdn_data->q931, 1); - Q931TrunkSetStatusEnquiry(&isdn_data->q931, 0); - - span->state_map = &isdn_state_map; - span->signal_data = isdn_data; - span->signal_type = FTDM_SIGTYPE_ISDN; - span->signal_cb = sig_cb; - span->start = ftdm_isdn_start; - span->stop = ftdm_isdn_stop; - span->outgoing_call = isdn_outgoing_call; - - span->get_channel_sig_status = isdn_get_channel_sig_status; - span->get_span_sig_status = isdn_get_span_sig_status; - -#ifdef __TODO__ - if ((isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) { - span->channel_request = isdn_channel_request; - span->flags |= FTDM_SPAN_SUGGEST_CHAN_ID; - } -#endif - ftdm_span_load_tones(span, tonemap); - - return FTDM_SUCCESS; -} - -/** - * ISDN module io interface - * \note This is really ugly... - */ -static ftdm_io_interface_t isdn_interface = { - .name = "isdn", - .api = isdn_api -}; - -/** - * \brief ISDN module io interface init callback - */ -static FIO_IO_LOAD_FUNCTION(isdn_io_load) -{ - assert(fio != NULL); - - *fio = &isdn_interface; - - return FTDM_SUCCESS; -} - -/** - * \brief ISDN module load callback - */ -static FIO_SIG_LOAD_FUNCTION(isdn_load) -{ - Q931Initialize(); - - Q921SetGetTimeCB(ftdm_time_now); - Q931SetGetTimeCB(ftdm_time_now); - - return FTDM_SUCCESS; -} - -/** - * \brief ISDN module shutdown callback - */ -static FIO_SIG_UNLOAD_FUNCTION(isdn_unload) -{ - return FTDM_SUCCESS; -}; - -ftdm_module_t ftdm_module = { - .name = "isdn", - .io_load = isdn_io_load, - .io_unload = NULL, - .sig_load = isdn_load, - .sig_unload = isdn_unload, - .configure_span_signaling = isdn_configure_span -}; - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet expandtab: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.h b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.h deleted file mode 100644 index 378f901320..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FTDM_ISDN_H -#define FTDM_ISDN_H - -#define DEFAULT_DIGIT_TIMEOUT 10000 /* default overlap timeout: 10 seconds */ - - -typedef enum { - FTDM_ISDN_OPT_NONE = 0, - FTDM_ISDN_OPT_SUGGEST_CHANNEL = (1 << 0), - FTDM_ISDN_OPT_OMIT_DISPLAY_IE = (1 << 1), /*!< Do not send Caller name in outgoing SETUP message (= Display IE) */ - FTDM_ISDN_OPT_DISABLE_TONES = (1 << 2), /*!< Disable tone generating thread (NT mode) */ - - FTDM_ISDN_OPT_MAX = (2 << 0) -} ftdm_isdn_opts_t; - -typedef enum { - FTDM_ISDN_RUNNING = (1 << 0), - FTDM_ISDN_TONES_RUNNING = (1 << 1), - FTDM_ISDN_STOP = (1 << 2), - - FTDM_ISDN_CAPTURE = (1 << 3), - FTDM_ISDN_CAPTURE_L3ONLY = (1 << 4) -} ftdm_isdn_flag_t; - -#ifdef HAVE_PCAP -struct pcap_context; -#endif - -struct ftdm_isdn_data { - Q921Data_t q921; - Q931_TrunkInfo_t q931; - ftdm_channel_t *dchan; - uint32_t flags; - int32_t mode; - int32_t digit_timeout; - ftdm_isdn_opts_t opts; -#ifdef HAVE_PCAP - struct pcap_context *pcap; -#endif -}; - -typedef struct ftdm_isdn_data ftdm_isdn_data_t; - - -/* b-channel private data */ -struct ftdm_isdn_bchan_data -{ - ftdm_time_t digit_timeout; - int offset; /* offset in teletone buffer */ -}; - -typedef struct ftdm_isdn_bchan_data ftdm_isdn_bchan_data_t; - - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet expandtab: - */ - diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c deleted file mode 100644 index 03f2fc3c8b..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ /dev/null @@ -1,3248 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * Copyright (c) 2010, Stefan Knoblich - * Copyright (c) 2012-2013, Stefan Knoblich - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "private/ftdm_core.h" -#include "ftmod_libpri.h" - - -static ftdm_status_t ftdm_libpri_start(ftdm_span_t *span); -static ftdm_io_interface_t ftdm_libpri_interface; - -static int on_timeout_t302(struct lpwrap_pri *spri, struct lpwrap_timer *timer); -static int on_timeout_t316(struct lpwrap_pri *spri, struct lpwrap_timer *timer); -static int on_timeout_t3xx(struct lpwrap_pri *spri, struct lpwrap_timer *timer); - - -static void _ftdm_channel_set_state_force(ftdm_channel_t *chan, const ftdm_channel_state_t state) -{ - assert(chan); - chan->state = state; -} - -/** - * \brief Unloads libpri IO module - * \return Success - */ -static FIO_IO_UNLOAD_FUNCTION(ftdm_libpri_unload) -{ - return FTDM_SUCCESS; -} - -/** - * \brief Returns the signalling status on a channel - * \param ftdmchan Channel to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ - -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(isdn_get_channel_sig_status) -{ - *status = FTDM_SIG_STATE_DOWN; - - ftdm_libpri_data_t *isdn_data = ftdmchan->span->signal_data; - if (ftdm_test_flag(&(isdn_data->spri), LPWRAP_PRI_READY)) { - *status = FTDM_SIG_STATE_UP; - } - return FTDM_SUCCESS; -} - -/** - * \brief Returns the signalling status on a span - * \param span Span to get status on - * \param status Pointer to set signalling status - * \return Success or failure - */ - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(isdn_get_span_sig_status) -{ - *status = FTDM_SIG_STATE_DOWN; - - ftdm_libpri_data_t *isdn_data = span->signal_data; - if (ftdm_test_flag(&(isdn_data->spri), LPWRAP_PRI_READY)) { - *status = FTDM_SIG_STATE_UP; - } - return FTDM_SUCCESS; -} - - -/** - * \brief Starts a libpri channel (outgoing call) - * \param ftdmchan Channel to initiate call on - * \return Success or failure - */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call) -{ - ftdm_unused_arg(ftdmchan); - return FTDM_SUCCESS; -} - -/** - * \brief Requests an libpri channel on a span (outgoing call) - * \param span Span where to get a channel (unused) - * \param chan_id Specific channel to get (0 for any) (unused) - * \param direction Call direction (unused) - * \param caller_data Caller information (unused) - * \param ftdmchan Channel to initialise (unused) - * \return Failure - */ -static FIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request) -{ - ftdm_unused_arg(span); - ftdm_unused_arg(chan_id); - ftdm_unused_arg(direction); - ftdm_unused_arg(caller_data); - ftdm_unused_arg(ftdmchan); - return FTDM_FAIL; -} - - -/** - * \brief Logs a libpri message - * \param pri libpri structure - * \param s Message string - */ -static void s_pri_message(struct pri *pri, char *s) -{ - struct lpwrap_pri *spri = pri_get_userdata(pri); - - if (spri && spri->dchan) { - ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "%s", s); - } else { - ftdm_log(FTDM_LOG_DEBUG, "%s", s); - } -} - -/** - * \brief Logs a libpri error - * \param pri libpri structure - * \param s Error string - */ -static void s_pri_error(struct pri *pri, char *s) -{ - struct lpwrap_pri *spri = pri_get_userdata(pri); - - if (spri && spri->dchan) { - ftdm_log_chan(spri->dchan, FTDM_LOG_ERROR, "%s", s); - } else { - ftdm_log(FTDM_LOG_ERROR, "%s", s); - } -} - - -#define PRI_DEBUG_Q921_ALL (PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE) -#define PRI_DEBUG_Q931_ALL (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q931_ANOMALY) - -static const struct ftdm_libpri_debug { - const char *name; - const int flags; -} ftdm_libpri_debug[] = { - /* NOTE: order is important for print_debug() */ - { "q921_all", PRI_DEBUG_Q921_ALL }, - { "q921_raw", PRI_DEBUG_Q921_RAW }, - { "q921_dump", PRI_DEBUG_Q921_DUMP }, - { "q921_state", PRI_DEBUG_Q921_STATE }, - - { "q931_all", PRI_DEBUG_Q931_ALL }, - { "q931_dump", PRI_DEBUG_Q931_DUMP }, - { "q931_state", PRI_DEBUG_Q931_STATE }, - { "q931_anomaly", PRI_DEBUG_Q931_ANOMALY }, - - { "config", PRI_DEBUG_CONFIG }, - { "apdu", PRI_DEBUG_APDU }, - { "aoc", PRI_DEBUG_AOC } -}; - -/** - * \brief Parses a debug string to flags - * \param in Debug string to parse for - * \return Flags or -1 if nothing matched - */ -static int parse_debug(const char *in, uint32_t *flags) -{ - int res = -1; - int i; - - if (!in || !flags) - return -1; - - if (!strcmp(in, "all")) { - *flags = PRI_DEBUG_ALL; - return 0; - } - if (strstr(in, "none")) { - *flags = 0; - return 0; - } - - for (i = 0; i < ftdm_array_len(ftdm_libpri_debug); i++) { - if (strstr(in, ftdm_libpri_debug[i].name)) { - *flags |= ftdm_libpri_debug[i].flags; - res = 0; - } - } - return res; -} - -#ifdef HAVE_LIBPRI_MAINT_SERVICE -/** - * \brief Parses a change status string to flags - * \param in change status string to parse for - * \return Flags - */ -static int parse_change_status(const char *in) -{ - int flags = 0; - if (!in) { - return 0; - } - - if (strstr(in, "in_service") || strstr(in, "in")) { - flags = SERVICE_CHANGE_STATUS_INSERVICE; - } - if (strstr(in, "maintenance") || strstr(in, "maint")) { - flags = SERVICE_CHANGE_STATUS_MAINTENANCE; - } - if (strstr(in, "out_of_service") || strstr(in, "out")) { - flags = SERVICE_CHANGE_STATUS_OUTOFSERVICE; - } - - - return flags; -} -#endif - - -static int print_debug(uint32_t flags, char *tmp, const int size) -{ - int offset = 0; - int res = 0; - int i; - - if ((flags & PRI_DEBUG_ALL) == PRI_DEBUG_ALL) { - strcat(tmp, "all"); - return 0; - } - else if (!flags) { - strcat(tmp, "none"); - return 0; - } - - for (i = 0; i < ftdm_array_len(ftdm_libpri_debug); i++) { - if ((flags & ftdm_libpri_debug[i].flags) == ftdm_libpri_debug[i].flags) { - res = snprintf(&tmp[offset], size - offset, "%s,", ftdm_libpri_debug[i].name); - if (res <= 0 || res == (size - offset)) - goto out; - offset += res; - flags &= ~ftdm_libpri_debug[i].flags; /* remove detected flags to make *_all work correctly */ - } - } - -out: - tmp[offset - 1] = '\0'; - return 0; -} - - -/*************************************************************** - * MSN filter - ***************************************************************/ - -/** - * Initialize MSN filter data structures - * \param[in] isdn_data Span private data - * \return FTDM_SUCCESS, FTDM_FAIL - */ -static int msn_filter_init(ftdm_libpri_data_t *isdn_data) -{ - if (!isdn_data) - return FTDM_FAIL; - - isdn_data->msn_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - if (!isdn_data->msn_hash) - return FTDM_FAIL; - - if (ftdm_mutex_create(&isdn_data->msn_mutex)) { - hashtable_destroy(isdn_data->msn_hash); - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - -/** - * Destroy MSN filter data structures - * \param[in] isdn_data Span private data - * \return FTDM_SUCCESS, FTDM_FAIL - */ -static int msn_filter_destroy(ftdm_libpri_data_t *isdn_data) -{ - if (!isdn_data) - return FTDM_FAIL; - - if (isdn_data->msn_hash) - hashtable_destroy(isdn_data->msn_hash); - if (isdn_data->msn_mutex) - ftdm_mutex_destroy(&isdn_data->msn_mutex); - - return FTDM_SUCCESS; -} - -/** - * Check if the given string is a valid MSN/DDI - * (i.e.: Not empty, not longer than FDM_DIGITS_LIMIT and all numbers) - * \param[in] str String to check - * \return FTDM_SUCCESS, FTDM_FAIL - */ -static int msn_filter_verify(const char *str) -{ - if (ftdm_strlen_zero(str) || strlen(str) >= FTDM_DIGITS_LIMIT) - return FTDM_FALSE; - - if (ftdm_is_number(str) != FTDM_SUCCESS) - return FTDM_FALSE; - - return FTDM_TRUE; -} - -/** - * Add a new MSN/DDI to the filter - * \param[in] isdn_data Span private data - * \param[in] msn New MSN/DDI to add - * \return FTDM_SUCCESS, FTDM_FAIL - */ -static int msn_filter_add(ftdm_libpri_data_t *isdn_data, const char *msn) -{ - static const int value = 0xdeadbeef; - char *key = NULL; - int ret = FTDM_SUCCESS; - - if (!isdn_data || !msn_filter_verify(msn)) - return FTDM_FAIL; - - ftdm_mutex_lock(isdn_data->msn_mutex); - - /* check for duplicates (ignore if already in set) */ - if (hashtable_search(isdn_data->msn_hash, (void *)msn)) { - ret = FTDM_SUCCESS; - goto out; - } - - /* Copy MSN (transient string), hashtable will free it in hashtable_destroy() */ - key = ftdm_strdup(msn); - if (!key) { - ret = FTDM_FAIL; - goto out; - } - - /* add MSN to list/hash */ - if (!hashtable_insert(isdn_data->msn_hash, (void *)key, (void *)&value, HASHTABLE_FLAG_FREE_KEY)) { - ftdm_safe_free(key); - ret = FTDM_FAIL; - } -out: - ftdm_mutex_unlock(isdn_data->msn_mutex); - return ret; -} - - -/** - * Check if a DNIS (destination number) is a valid MSN/DDI - * \param[in] isdn_data Span private data - * \param[in] msn Number to check - * \retval FTDM_TRUE \p msn is a valid MSN/DDI or filter list is empty - * \retval FTDM_FALSE \p msn is not a valid MSN/DDI - */ -static int msn_filter_match(ftdm_libpri_data_t *isdn_data, const char *msn) -{ - int ret = FTDM_FALSE; - - if (!isdn_data) - return FTDM_FALSE; - /* No number? return match found */ - if (ftdm_strlen_zero(msn)) - return FTDM_TRUE; - - ftdm_mutex_lock(isdn_data->msn_mutex); - - /* No MSN configured? */ - if (hashtable_count(isdn_data->msn_hash) <= 0) { - ret = FTDM_TRUE; - goto out; - } - /* Search for a matching MSN */ - if (hashtable_search(isdn_data->msn_hash, (void *)msn)) - ret = FTDM_TRUE; -out: - ftdm_mutex_unlock(isdn_data->msn_mutex); - return ret; -} - -/** - * Helper function to iterate over MSNs in the filter hash (handles locking) - * \param[in] isdn_data Span private data - * \param[in] func Callback function that is invoked for each entry - * \param[in] data Private data passed to callback - * \return FTDM_SUCCESS, FTDM_FAIL - */ -static int msn_filter_foreach(ftdm_libpri_data_t *isdn_data, int (* func)(const char *, void *), void *data) -{ - ftdm_hash_iterator_t *iter = NULL; - int ret = FTDM_SUCCESS; - - if (!isdn_data || !func) - return FTDM_FAIL; - - /* iterate over MSNs */ - ftdm_mutex_lock(isdn_data->msn_mutex); - - for (iter = hashtable_first(isdn_data->msn_hash); iter; iter = hashtable_next(iter)) { - const void *msn = NULL; - - hashtable_this(iter, &msn, NULL, NULL); - - if (ftdm_strlen_zero((const char *)msn)) - break; - if ((ret = func(msn, data)) != FTDM_SUCCESS) - break; - } - - ftdm_mutex_unlock(isdn_data->msn_mutex); - return ret; -} - - -/*************************************************************** - * Module API (CLI) interface - ***************************************************************/ - -static const char *ftdm_libpri_usage = - "Usage:\n" - "libpri kill \n" - "libpri reset \n" - "libpri restart \n" -#ifdef HAVE_LIBPRI_MAINT_SERVICE - "libpri maintenance \n" -#endif - "libpri debug [all|none|flag,...flagN]\n" - "libpri msn \n" - "\n" - "Possible debug flags:\n" - "\tq921_raw - Q.921 Raw messages\n" - "\tq921_dump - Q.921 Decoded messages\n" - "\tq921_state - Q.921 State machine changes\n" - "\tq921_all - Enable all Q.921 debug options\n" - "\n" - "\tq931_dump - Q.931 Messages\n" - "\tq931_state - Q.931 State machine changes\n" - "\tq931_anomaly - Q.931 Anomalies\n" - "\tq931_all - Enable all Q.931 debug options\n" - "\n" - "\tapdu - Application protocol data unit\n" - "\taoc - Advice of Charge messages\n" - "\tconfig - Configuration\n" - "\n" - "\tnone - Disable debugging\n" - "\tall - Enable all debug options\n"; - - -/** - * Custom data handle for list iterator functions - */ -struct msn_list_cb_private { - ftdm_stream_handle_t *stream; - unsigned int count; -}; - -/** - * "ftdm libpri msn " API command callback - * function for msn_filter_foreach() - */ -static int msn_list_cb(const char *msn, void *priv) -{ - struct msn_list_cb_private *data = priv; - ftdm_stream_handle_t *stream = data->stream; - - if (!stream || ftdm_strlen_zero(msn)) - return FTDM_FAIL; - - stream->write_function(stream, "\t%s\n", msn); - data->count++; - return FTDM_SUCCESS; -} - - -/** - * \brief API function to kill or debug a libpri span - * \param stream API stream handler - * \param data String containing argurments - * \return Flags - */ -static FIO_API_FUNCTION(ftdm_libpri_api) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argc == 1) { - if (!strcasecmp(argv[0], "help") || !strcasecmp(argv[0], "usage")) { - stream->write_function(stream, ftdm_libpri_usage); - goto done; - } - } else if (argc == 2) { - if (!strcasecmp(argv[0], "kill")) { - int span_id = atoi(argv[1]); - ftdm_span_t *span = NULL; - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - ftdm_libpri_data_t *isdn_data = span->signal_data; - - if (span->start != ftdm_libpri_start) { - stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n", - __FILE__, ftdm_span_get_name(span)); - goto done; - } - - ftdm_clear_flag(&(isdn_data->spri), LPWRAP_PRI_READY); - stream->write_function(stream, "%s: +OK killed.\n", __FILE__); - goto done; - } else { - stream->write_function(stream, "%s: -ERR span '%s' not found.\n", - __FILE__, argv[0]); - goto done; - } - } - if (!strcasecmp(argv[0], "msn")) { - ftdm_span_t *span = NULL; - struct msn_list_cb_private data; - data.stream = stream; - data.count = 0; - - if (ftdm_span_find_by_name(argv[1], &span) != FTDM_SUCCESS) { - stream->write_function(stream, "%s: -ERR span '%s' not found.\n", - __FILE__, argv[1]); - goto done; - } - if (span->start != ftdm_libpri_start) { - stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n", - __FILE__, ftdm_span_get_name(span)); - goto done; - } - - /* header */ - stream->write_function(stream, "------------------------------------------------------------------------------\n"); - - if (msn_filter_foreach(span->signal_data, msn_list_cb, &data)) { - stream->write_function(stream, "-ERR: Failed to list MSN(s)\n"); - goto done; - } - if (data.count == 0) { - stream->write_function(stream, "\t\t\t -- no entries --\n"); - } - - /* footer */ - stream->write_function(stream, "---------------------------------------------------------------[ %02d MSN(s) ]--\n", - data.count); - stream->write_function(stream, "+OK"); - goto done; - } - } else if (argc >= 2) { - if (!strcasecmp(argv[0], "debug")) { - ftdm_span_t *span = NULL; - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { - ftdm_libpri_data_t *isdn_data = span->signal_data; - uint32_t flags = 0; - - if (span->start != ftdm_libpri_start) { - stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n", - __FILE__, ftdm_span_get_name(span)); - goto done; - } - - if (argc == 2) { - char tmp[100] = { 0 }; - print_debug(pri_get_debug(isdn_data->spri.pri), tmp, sizeof(tmp)); - stream->write_function(stream, "%s: +OK current debug flags: '%s'\n", __FILE__, tmp); - goto done; - } - - if (parse_debug(argv[2], &flags) == -1) { - stream->write_function(stream, "%s: -ERR invalid debug flags given\n", __FILE__); - goto done; - } - - pri_set_debug(isdn_data->spri.pri, flags); - stream->write_function(stream, "%s: +OK debug %s.\n", __FILE__, (flags) ? "enabled" : "disabled"); - goto done; - } else { - stream->write_function(stream, "%s: -ERR span '%s' not found.\n", - __FILE__, argv[0]); - goto done; - } - } - if (!strcasecmp(argv[0], "reset")) { - ftdm_span_t *span = NULL; - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { - ftdm_libpri_data_t *isdn_data = span->signal_data; - - if (span->start != ftdm_libpri_start) { - stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n", - __FILE__, ftdm_span_get_name(span)); - goto done; - } - - pri_restart(isdn_data->spri.pri); - stream->write_function(stream, "%s: +OK reset.\n", __FILE__); - goto done; - } else { - stream->write_function(stream, "%s: -ERR span '%s' not found.\n", - __FILE__, argv[0]); - goto done; - } - } - if (!strcasecmp(argv[0], "restart") && argc == 3) { - ftdm_span_t *span = NULL; - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { - ftdm_libpri_data_t *isdn_data = span->signal_data; - - if (span->start != ftdm_libpri_start) { - stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n", - __FILE__, ftdm_span_get_name(span)); - goto done; - } - if (!strcasecmp(argv[2], "all")) { - int j; - for(j = 1; j <= span->chan_count; j++) { - pri_reset(isdn_data->spri.pri, j); - ftdm_sleep(50); - } - } else { - pri_reset(isdn_data->spri.pri, atoi(argv[2])); - } - stream->write_function(stream, "%s: +OK restart set.\n", __FILE__); - goto done; - } else { - stream->write_function(stream, "%s: -ERR span '%s' not found.\n", - __FILE__, argv[0]); - goto done; - } - } -#ifdef HAVE_LIBPRI_MAINT_SERVICE - if (!strcasecmp(argv[0], "maintenance") && argc > 3) { - ftdm_span_t *span = NULL; - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { - ftdm_libpri_data_t *isdn_data = span->signal_data; - - if (span->start != ftdm_libpri_start) { - stream->write_function(stream, "%s: -ERR '%s' is not a libpri span.\n", - __FILE__, ftdm_span_get_name(span)); - goto done; - } - if (!isdn_data->service_message_support) { - stream->write_function(stream, "%s: -ERR service message support is disabled\n", __FILE__); - goto done; - } - if (!strcasecmp(argv[2], "all")) { - int j; - for(j = 1; j <= span->chan_count; j++) { - pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), j, parse_change_status(argv[3])); - ftdm_sleep(50); - } - } else { - pri_maintenance_service(isdn_data->spri.pri, atoi(argv[1]), atoi(argv[2]), parse_change_status(argv[3])); - } - stream->write_function(stream, "%s: +OK change status set.\n", __FILE__); - goto done; - } else { - stream->write_function(stream, "%s: -ERR span '%s' not found.\n", - __FILE__, argv[0]); - goto done; - } - } -#endif - } else { - /* zero args print usage */ - stream->write_function(stream, ftdm_libpri_usage); - goto done; - } - - stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__); - -done: - ftdm_safe_free(mycmd); - - return FTDM_SUCCESS; -} - - -/** - * \brief Loads libpri IO module - * \param fio FreeTDM IO interface - * \return Success - */ -static FIO_IO_LOAD_FUNCTION(ftdm_libpri_io_init) -{ - assert(fio != NULL); - - memset(&ftdm_libpri_interface, 0, sizeof(ftdm_libpri_interface)); - ftdm_libpri_interface.name = "libpri"; - ftdm_libpri_interface.api = &ftdm_libpri_api; - - *fio = &ftdm_libpri_interface; - - return FTDM_SUCCESS; -} - -/** - * \brief Loads libpri signaling module - * \param fio FreeTDM IO interface - * \return Success - */ -static FIO_SIG_LOAD_FUNCTION(ftdm_libpri_init) -{ - pri_set_error(s_pri_error); - pri_set_message(s_pri_message); - return FTDM_SUCCESS; -} - -/** - * \brief libpri state map - */ -static ftdm_state_map_t isdn_state_map = { - { - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - - /****************************************/ - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, - FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - } -}; - -/** - * \brief Handler for channel state change - * \param ftdmchan Channel to handle - * \note This function MUST be called with the channel locked - */ -static ftdm_status_t state_advance(ftdm_channel_t *chan) -{ - ftdm_span_t *span = ftdm_channel_get_span(chan); - ftdm_libpri_data_t *isdn_data = span->signal_data; - ftdm_libpri_b_chan_t *chan_priv = chan->call_data; - q931_call *call = chan_priv->call; - ftdm_status_t status; - ftdm_sigmsg_t sig; - - ftdm_log(FTDM_LOG_DEBUG, "-- %d:%d STATE [%s]\n", - ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan), ftdm_channel_get_state_str(chan)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdm_channel_get_id(chan); - sig.span_id = ftdm_channel_get_span_id(chan); - sig.channel = chan; - - ftdm_channel_complete_state(chan); - - switch (ftdm_channel_get_state(chan)) { - case FTDM_CHANNEL_STATE_DOWN: - { - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - ftdm_channel_t *chtmp = chan; - - if (call) { - /* pri call destroy is done by libpri itself (on release_ack) */ - chan_priv->call = NULL; - } - - /* Stop T302 */ - lpwrap_stop_timer(&isdn_data->spri, &chan_priv->t302); - - /* Stop T316 and reset counter */ - lpwrap_stop_timer(&isdn_data->spri, &chan_priv->t316); - chan_priv->t316_timeout_cnt = 0; - - /* Unset remote hangup */ - chan_priv->peerhangup = 0; - - if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - } - } - } - break; - - case FTDM_CHANNEL_STATE_PROGRESS: - { - if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - } else if (call) { - /* - * Even if we have no media, sending progress without PI is forbidden - * by Q.931 3.1.8, so a protocol error will be issued from libpri - * and from remote equipment. - * So just pretend we have PI. - */ - pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); - } else { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - break; - - case FTDM_CHANNEL_STATE_RINGING: - { - if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_RINGING; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - } else if (call) { -// pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); - pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); - } else { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - break; - - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - } else if (call) { - /* make sure channel is open in this state (outbound handled in on_proceeding()) */ - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { - ftdm_channel_open_chan(chan); - } - pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); - } else { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - break; - - case FTDM_CHANNEL_STATE_PROCEED: - { - if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { - /* PROCEED from other end, notify user */ - sig.event_id = FTDM_SIGEVENT_PROCEED; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to send PROCEED sigevent on Channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - } else if (call) { - pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); - } else { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - break; - - case FTDM_CHANNEL_STATE_COLLECT: /* Overlap receive */ - { - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { - if (!call) { - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "No call handle\n"); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - else if (pri_need_more_info(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0)) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "Failed to send INFORMATION request\n"); - - /* hangup call */ - caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - else { - /* Start T302 */ - lpwrap_start_timer(&isdn_data->spri, &chan_priv->t302, - isdn_data->overlap_timeout_ms, &on_timeout_t302); - } - } else { - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "Overlap receiving on outbound call?\n"); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - break; - - case FTDM_CHANNEL_STATE_RING: - { - /* - * This needs more auditing for BRI PTMP: - * does pri_acknowledge() steal the call from other devices? (yes, it does) - */ - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { - if (call) { - pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); -// pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); - sig.event_id = FTDM_SIGEVENT_START; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - } else { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - } - break; - - case FTDM_CHANNEL_STATE_RESTART: - { - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - chan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED; - sig.event_id = FTDM_SIGEVENT_RESTART; - status = ftdm_span_send_signal(span, &sig); - - if (ftdm_span_get_trunk_type(span) == FTDM_TRUNK_BRI_PTMP) { - /* Just put the channel into DOWN state, libpri won't send RESTART on BRI PTMP */ - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); - - } else if (!(chan_priv->flags & FTDM_LIBPRI_B_REMOTE_RESTART)) { - /* Locally triggered restart, send RESTART to remote, wait for ACK */ - pri_reset(isdn_data->spri.pri, ftdm_channel_get_id(chan)); - /* Start T316 */ - lpwrap_start_timer(&isdn_data->spri, &chan_priv->t316, isdn_data->t316_timeout_ms, &on_timeout_t316); - } else { - /* Remote restart complete, clear flag (RESTART ACK already sent by libpri) */ - chan_priv->flags &= ~FTDM_LIBPRI_B_REMOTE_RESTART; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); - } - } - } - break; - - case FTDM_CHANNEL_STATE_UP: - { - if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { - sig.event_id = FTDM_SIGEVENT_UP; - if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - } else if (call) { - /* make sure channel is open in this state (outbound handled in on_answer()) */ - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { - ftdm_channel_open_chan(chan); - } - pri_answer(isdn_data->spri.pri, call, 0, 1); - } else { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - break; - - case FTDM_CHANNEL_STATE_DIALING: - if (isdn_data) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - struct pri_sr *sr; - int caller_ton; - int called_ton; - - if (!(call = pri_new_call(isdn_data->spri.pri))) { - ftdm_log(FTDM_LOG_ERROR, "Failed to create new call on channel %d:%d\n", - ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan)); - /* TODO: set hangup cause? */ - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - return FTDM_SUCCESS; - } - - caller_ton = caller_data->cid_num.type; - switch (caller_ton) { - case FTDM_TON_NATIONAL: - caller_ton = PRI_NATIONAL_ISDN; - break; - case FTDM_TON_INTERNATIONAL: - caller_ton = PRI_INTERNATIONAL_ISDN; - break; - case FTDM_TON_SUBSCRIBER_NUMBER: - caller_ton = PRI_LOCAL_ISDN; - break; - default: - caller_ton = isdn_data->ton; - } - - called_ton = caller_data->dnis.type; - switch (called_ton) { - case FTDM_TON_NATIONAL: - called_ton = PRI_NATIONAL_ISDN; - break; - case FTDM_TON_INTERNATIONAL: - called_ton = PRI_INTERNATIONAL_ISDN; - break; - case FTDM_TON_SUBSCRIBER_NUMBER: - called_ton = PRI_LOCAL_ISDN; - break; - default: - called_ton = isdn_data->ton; - } - - chan_priv->call = call; - - sr = pri_sr_new(); - if (!sr) { - ftdm_log(FTDM_LOG_ERROR, "Failed to create new setup request on channel %d:%d\n", - ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan)); - /* TODO: handle error properly */ - } - assert(sr); - - pri_sr_set_channel(sr, ftdm_channel_get_id(chan), 1, 0); - pri_sr_set_bearer(sr, PRI_TRANS_CAP_SPEECH, isdn_data->layer1); - - pri_sr_set_called(sr, caller_data->dnis.digits, called_ton, 1); - pri_sr_set_caller(sr, caller_data->cid_num.digits, - ((isdn_data->opts & FTMOD_LIBPRI_OPT_OMIT_DISPLAY_IE) ? NULL : caller_data->cid_name), - caller_ton, - ((caller_data->pres != 1) ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_PROHIB_USER_NUMBER_NOT_SCREENED)); - - if (!(isdn_data->opts & FTMOD_LIBPRI_OPT_OMIT_REDIRECTING_NUMBER_IE)) { - pri_sr_set_redirecting(sr, caller_data->cid_num.digits, caller_ton, - PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, PRI_REDIR_UNCONDITIONAL); - } -#ifdef HAVE_LIBPRI_AOC - if (isdn_data->opts & FTMOD_LIBPRI_OPT_FACILITY_AOC) { - /* request AOC on call */ - pri_sr_set_aoc_charging_request(sr, (PRI_AOC_REQUEST_S | PRI_AOC_REQUEST_E | PRI_AOC_REQUEST_D)); - ftdm_log(FTDM_LOG_DEBUG, "Requesting AOC-S/D/E on call\n"); - } -#endif - if (pri_setup(isdn_data->spri.pri, call, sr)) { - caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); - } - - pri_sr_free(sr); - } - break; - - case FTDM_CHANNEL_STATE_HANGUP: - { - if (call) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause); - - if (chan_priv->peerhangup) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - } - } - } - break; - - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - { -// if (call) { -// pri_destroycall(isdn_data->spri.pri, call); -// chan_priv->call = NULL; -// } - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); - } - break; - - case FTDM_CHANNEL_STATE_TERMINATING: - { - sig.event_id = FTDM_SIGEVENT_STOP; - status = ftdm_span_send_signal(span, &sig); - /* user moves us to HANGUP and from there we go to DOWN */ - } - default: - break; - } - return FTDM_SUCCESS; -} - -/** - * \brief Checks current state on a span - * \param span Span to check status on - */ -static __inline__ void check_state(ftdm_span_t *span) -{ - if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) { - uint32_t j; - - ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE); - - for (j = 1; j <= ftdm_span_get_chan_count(span); j++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, j); - ftdm_channel_lock(chan); - ftdm_channel_advance_states(chan); - ftdm_channel_unlock(chan); - } - } -} - - -/** - * \brief Handler for libpri keypad digit event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_keypad_digit(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->ring.channel); - - ftdm_unused_arg(event_type); - - if (!chan) { - ftdm_log(FTDM_LOG_ERROR, "-- Keypad event on invalid channel %d:%d\n", - ftdm_span_get_id(span), pevent->ring.channel); - return 0; - } - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "-- Keypad event received, incoming digits: '%s'\n", - pevent->digit.digits); - - /* Enqueue DTMF digits on channel */ - ftdm_channel_queue_dtmf(chan, pevent->digit.digits); - return 0; -} - - -/** - * \brief Handler for libpri information event (overlap receiving) - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_information(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->ring.channel); - ftdm_libpri_b_chan_t *chan_priv = NULL; - ftdm_caller_data_t *caller_data = NULL; - ftdm_libpri_data_t *isdn_data = span->signal_data; - - ftdm_unused_arg(event_type); - - if (!chan) { - ftdm_log(FTDM_LOG_CRIT, "-- Info on channel %d:%d but it's not in use?\n", ftdm_span_get_id(span), pevent->ring.channel); - return 0; - } - - caller_data = ftdm_channel_get_caller_data(chan); - chan_priv = chan->call_data; - - switch (ftdm_channel_get_state(chan)) { - case FTDM_CHANNEL_STATE_COLLECT: /* TE-mode overlap receiving */ - case FTDM_CHANNEL_STATE_DIALTONE: /* NT-mode overlap receiving */ - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "-- Incoming INFORMATION indication, received digits: '%s', number complete: %c, collected digits: '%s'\n", - pevent->ring.callednum, - pevent->ring.complete ? 'Y' : 'N', - caller_data->dnis.digits); - - /* Stop T302 */ - lpwrap_stop_timer(spri, &chan_priv->t302); - - /* append digits to dnis */ - if (!ftdm_strlen_zero(pevent->ring.callednum)) { - int digits = strlen(pevent->ring.callednum); - int offset = strlen(caller_data->dnis.digits); - int len = 0; - - if (strchr(pevent->ring.callednum, '#')) { - pevent->ring.complete = 1; - digits--; - } - - len = ftdm_min(sizeof(caller_data->dnis.digits) - 1 - offset, digits); /* max. length without terminator */ - if (len < digits) { - ftdm_log_chan(chan, FTDM_LOG_WARNING, "Digit string of length %d exceeds available space %d of DNIS, truncating!\n", - digits, len); - } - if (len) { - ftdm_copy_string(&caller_data->dnis.digits[offset], (char *)pevent->ring.callednum, len + 1); /* max. length with terminator */ - caller_data->dnis.digits[offset + len] = '\0'; - } - } - if (pevent->ring.complete) { - ftdm_log_chan_msg(chan, FTDM_LOG_DEBUG, "Number complete indication received, moving channel to RING state\n"); - /* notify switch */ - ftdm_set_state(chan, FTDM_CHANNEL_STATE_RING); - } else { - /* Restart T302 */ - lpwrap_start_timer(spri, &chan_priv->t302, isdn_data->overlap_timeout_ms, &on_timeout_t302); - } - break; - default: - ftdm_log_chan(chan, FTDM_LOG_ERROR, "-- INFORMATION indication in invalid state '%s'\n", - ftdm_channel_get_state_str(chan)); - } - return 0; -} - -/** - * \brief Handler for libpri hangup event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel); - ftdm_libpri_b_chan_t *chan_priv = chan->call_data; - - if (!chan) { - ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel); - return 0; - } - - ftdm_channel_lock(chan); - - switch (event_type) { - case LPWRAP_PRI_EVENT_HANGUP_REQ: /* DISCONNECT */ - if (ftdm_channel_get_state(chan) >= FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n", - ftdm_channel_get_state_str(chan)); - goto done; - } - ftdm_log(FTDM_LOG_DEBUG, "-- Hangup REQ on channel %d:%d\n", - ftdm_span_get_id(spri->span), pevent->hangup.channel); - - chan->caller_data.hangup_cause = pevent->hangup.cause; - - switch (ftdm_channel_get_state(chan)) { - case FTDM_CHANNEL_STATE_DIALTONE: - case FTDM_CHANNEL_STATE_COLLECT: - ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP); - break; - default: - ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING); - } - break; - - case LPWRAP_PRI_EVENT_HANGUP_ACK: /* RELEASE_COMPLETE */ - ftdm_log(FTDM_LOG_DEBUG, "-- Hangup ACK on channel %d:%d\n", - ftdm_span_get_id(spri->span), pevent->hangup.channel); - - switch (ftdm_channel_get_state(chan)) { - case FTDM_CHANNEL_STATE_RESTART: - /* ACK caused by DL FAILURE in DISC REQ */ - ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN); - break; - default: - ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - break; - } - break; - - case LPWRAP_PRI_EVENT_HANGUP: /* "RELEASE/RELEASE_COMPLETE/other" */ - ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", - ftdm_span_get_id(spri->span), pevent->hangup.channel); - - chan_priv->peerhangup = 1; - - switch (ftdm_channel_get_state(chan)) { - case FTDM_CHANNEL_STATE_DIALING: - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_UP: - chan->caller_data.hangup_cause = pevent->hangup.cause; - ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING); - break; - case FTDM_CHANNEL_STATE_HANGUP: - /* this will send "RELEASE_COMPLETE", eventually */ - pri_hangup(spri->pri, pevent->hangup.call, chan->caller_data.hangup_cause); - chan->caller_data.hangup_cause = pevent->hangup.cause; - ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - break; - case FTDM_CHANNEL_STATE_RESTART: - /* - * We got an hungup doing a restart, normally beacause link has been lost during - * a call and the T309 timer has expired. So destroy it :) (DL_RELEASE_IND) - */ - pri_destroycall(spri->pri, pevent->hangup.call); - ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN); - break; -// case FTDM_CHANNEL_STATE_TERMINATING: -// ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP); -// break; -// case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: -// ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN); -// break; - } - break; - default: - break; - } - -done: - ftdm_channel_unlock(chan); - return 0; -} - -/** - * \brief Handler for libpri answer event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_answer(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->answer.channel); - - ftdm_unused_arg(event_type); - - if (chan) { - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { - ftdm_log(FTDM_LOG_DEBUG, "-- Call answered, opening B-Channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - - ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING); - goto out; - } - } - ftdm_log(FTDM_LOG_DEBUG, "-- Answer on channel %d:%d\n", ftdm_span_get_id(span), pevent->answer.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_UP); - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Answer on channel %d:%d but it's not in the span?\n", - ftdm_span_get_id(span), pevent->answer.channel); - } -out: - return 0; -} - -/** - * \brief Handler for libpri proceeding event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_proceeding(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->proceeding.channel); - - ftdm_unused_arg(event_type); - - if (chan) { - /* Open channel if inband information is available */ - if (pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE || pevent->proceeding.progressmask & PRI_PROG_CALL_NOT_E2E_ISDN) { - ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, B-Channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN) && (ftdm_channel_open_chan(chan) != FTDM_SUCCESS)) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - - ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING); - goto out; - } - } - ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROCEED); - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d but it's not in the span?\n", - ftdm_span_get_id(span), pevent->proceeding.channel); - } -out: - return 0; -} - -/** - * \brief Handler for libpri progress event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - * \note also uses pri_event->proceeding - */ -static int on_progress(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->proceeding.channel); - - ftdm_unused_arg(event_type); - - if (chan) { - /* Open channel if inband information is available */ - if (pevent->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE || pevent->proceeding.progressmask & PRI_PROG_CALL_NOT_E2E_ISDN) { - ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, B-Channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN) && (ftdm_channel_open_chan(chan) != FTDM_SUCCESS)) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - - ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING); - goto out; - } - ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d with media\n", ftdm_span_get_id(span), pevent->proceeding.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS); - } - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d but it's not in the span?\n", - ftdm_span_get_id(span), pevent->proceeding.channel); - } -out: - return 0; -} - -/** - * \brief Handler for libpri ringing event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->ringing.channel); - - ftdm_unused_arg(event_type); - - if (chan) { - /* we may get on_ringing even when we're already in FTDM_CHANNEL_STATE_PROGRESS_MEDIA */ -// if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { -// /* dont try to move to STATE_PROGRESS to avoid annoying veto warning */ -// return 0; -// } - - /* Open channel if inband information is available */ - if ((pevent->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE)) { - ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, B-Channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN) && (ftdm_channel_open_chan(chan) != FTDM_SUCCESS)) { - ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - - ftdm_log(FTDM_LOG_ERROR, "-- Error opening channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING); - goto out; - } - ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d with media\n", ftdm_span_get_id(span), pevent->proceeding.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { -// ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS); - ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RINGING); - } - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d but it's not in the span?\n", - ftdm_span_get_id(span), pevent->ringing.channel); - } -out: - return 0; -} - - -/** - * Look up FreeTDM channel by call reference value - * \param[in] span Span object - * \param[in] crv CRV to search for - * \return Channel on success, NULL otherwise - */ -static ftdm_channel_t *find_channel_by_cref(ftdm_span_t *span, const int cref) -{ - ftdm_iterator_t *c_iter, *c_cur; - ftdm_channel_t *chan = NULL; - - if (!span || cref <= 0) - return NULL; - - ftdm_mutex_lock(span->mutex); - - c_iter = ftdm_span_get_chan_iterator(span, NULL); - - /* Iterate over all channels on this span */ - for (c_cur = c_iter; c_cur; c_cur = ftdm_iterator_next(c_cur)) { - ftdm_channel_t *cur = ftdm_iterator_current(c_cur); - ftdm_caller_data_t *caller_data = NULL; - - if (ftdm_channel_get_type(cur) != FTDM_CHAN_TYPE_B) - continue; - - caller_data = ftdm_channel_get_caller_data(cur); - - if (caller_data->call_reference == cref) { - chan = cur; - break; - } - } - - ftdm_iterator_free(c_iter); - ftdm_mutex_unlock(span->mutex); - return chan; -} - - -/** - * Hunt for free channel (NT-mode only) - * \param[in] span Span to hunt on - * \param[in] hint Channel ID hint (preferred by remote end) - * \param[in] excl Is the hint exclusive (or preferred)? - * \param[out] chan Selected channel - * \retval FTDM_SUCCESS A free channel has been found - * \retval FTDM_FAIL No free channels could be found on the span - * \retval FTDM_EBUSY The channel indicated in the exclusive hint is already in use - */ -static ftdm_status_t hunt_channel(ftdm_span_t *span, const int hint, const ftdm_bool_t excl, ftdm_channel_t **chan) -{ - ftdm_iterator_t *c_iter, *c_cur; - ftdm_channel_t *tmp = NULL; - int ret = FTDM_FAIL; - - /* lock span */ - ftdm_mutex_lock(span->mutex); - - /* Check hint */ - if (hint > 0) { - tmp = ftdm_span_get_channel(span, hint); - if (!tmp) { - ftdm_log(FTDM_LOG_NOTICE, "Invalid channel hint '%d' given (out of bounds)\n", hint); - } - else if (!ftdm_test_flag(tmp, FTDM_CHANNEL_INUSE) && ftdm_channel_get_type(tmp) == FTDM_CHAN_TYPE_B) { - ftdm_log(FTDM_LOG_DEBUG, "Using channel '%d' from hint\n", ftdm_channel_get_id(tmp)); - ftdm_channel_use(tmp); - ret = FTDM_SUCCESS; - *chan = tmp; - goto out; - } - else if (excl) { - ftdm_log(FTDM_LOG_NOTICE, "Channel '%d' in exclusive hint is not available\n", - ftdm_channel_get_id(tmp)); - ret = FTDM_EBUSY; - goto out; - } - } - - c_iter = ftdm_span_get_chan_iterator(span, NULL); - - /* Iterate over all channels on this span */ - for (c_cur = c_iter; c_cur; c_cur = ftdm_iterator_next(c_cur)) { - tmp = ftdm_iterator_current(c_cur); - - if (ftdm_channel_get_type(tmp) != FTDM_CHAN_TYPE_B) - continue; - - if (!ftdm_test_flag(tmp, FTDM_CHANNEL_INUSE)) { - ftdm_channel_use(tmp); - ret = FTDM_SUCCESS; - *chan = tmp; - break; - } - } - - ftdm_iterator_free(c_iter); -out: - ftdm_mutex_unlock(span->mutex); - return ret; -} - - -/** - * \brief Handler for libpri ring event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 on success - */ -static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_span_t *span = spri->span; - ftdm_libpri_data_t *isdn_data = span->signal_data; - ftdm_libpri_b_chan_t *chan_priv = NULL; - ftdm_channel_t *chan = NULL; - ftdm_caller_data_t *caller_data = NULL; - int ret = 0; - - ftdm_unused_arg(event_type); - - /* - * Check if call has an associated channel (duplicate ring event) - */ - if ((chan = find_channel_by_cref(span, pevent->ring.cref))) { - ftdm_log_chan_msg(chan, FTDM_LOG_NOTICE, "-- Duplicate ring received (ignored)\n"); - return ret; - } - - if (isdn_data->mode == PRI_NETWORK) { - /* - * Always hunt for a free channel in NT-mode, - * but use the pre-selected one as hint - */ - switch (hunt_channel(span, pevent->ring.channel, !pevent->ring.flexible, &chan)) { - case FTDM_SUCCESS: /* OK channel found */ - break; - case FTDM_EBUSY: /* Exclusive channel hint is not available */ - ftdm_log(FTDM_LOG_ERROR, "-- New call without channel on span '%s' [NOTE: Initial SETUP w/o channel selection is not supported by FreeTDM]\n", - ftdm_span_get_name(span)); - pri_hangup(spri->pri, pevent->ring.call, PRI_CAUSE_CHANNEL_UNACCEPTABLE); - return ret; - default: - ftdm_log(FTDM_LOG_ERROR, "-- New call without channel on span '%s' [NOTE: Initial SETUP w/o channel selection is not supported by FreeTDM]\n", - ftdm_span_get_name(span)); - pri_hangup(spri->pri, pevent->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION); - return ret; - } - - ftdm_channel_lock(chan); - - } else if (pevent->ring.channel == -1) { - /* - * TE-mode incoming call without channel selection (not supported) - */ - ftdm_log(FTDM_LOG_ERROR, "-- New call without channel on span '%s' [NOTE: Initial SETUP w/o channel selection is not supported by FreeTDM]\n", - ftdm_span_get_name(span)); - pri_destroycall(spri->pri, pevent->ring.call); - return ret; - } else { - /* - * TE-mode, check MSN filter, ignore calls that aren't for this PTMP terminal - */ - if (!msn_filter_match(isdn_data, pevent->ring.callednum)) { - ftdm_log(FTDM_LOG_INFO, "-- MSN filter not matching incoming DNIS '%s', ignoring call\n", - pevent->ring.callednum); - pri_destroycall(spri->pri, pevent->ring.call); - return ret; - } - - /* - * TE-mode channel selection, use whatever the NT tells us to - */ - chan = ftdm_span_get_channel(span, pevent->ring.channel); - if (!chan) { - ftdm_log(FTDM_LOG_ERROR, "-- Unable to get channel %d:%d\n", - ftdm_span_get_id(span), pevent->ring.channel); - pri_hangup(spri->pri, pevent->ring.call, PRI_CAUSE_DESTINATION_OUT_OF_ORDER); - return ret; - } - - ftdm_channel_lock(chan); - - if (ftdm_channel_get_state(chan) != FTDM_CHANNEL_STATE_DOWN || ftdm_test_flag(chan, FTDM_CHANNEL_INUSE)) { - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "-- Selected channel is already in use\n"); - pri_hangup(spri->pri, pevent->ring.call, PRI_CAUSE_DESTINATION_OUT_OF_ORDER); - goto done; - } - - /* Reserve channel */ - if (ftdm_channel_use(chan) != FTDM_SUCCESS) { - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "-- Error reserving channel\n"); - pri_hangup(spri->pri, pevent->ring.call, PRI_CAUSE_DESTINATION_OUT_OF_ORDER); - goto done; - } - } - - /* Get per-channel private data */ - chan_priv = chan->call_data; - - if (chan_priv->call) { - /* we could drop the incoming call, but most likely the pointer is just a ghost of the past, - * this check is just to detect potentially unreleased pointers */ - ftdm_log_chan(chan, FTDM_LOG_WARNING, "Channel already has call %p!\n", chan_priv->call); - chan_priv->call = NULL; - } - - caller_data = ftdm_channel_get_caller_data(chan); - - memset(caller_data, 0, sizeof(*caller_data)); - - /* Save CRV, so we can do proper duplicate RING detection */ - caller_data->call_reference = pevent->ring.cref; - - ftdm_set_string(caller_data->cid_num.digits, (char *)pevent->ring.callingnum); - ftdm_set_string(caller_data->ani.digits, (char *)pevent->ring.callingani); - ftdm_set_string(caller_data->dnis.digits, (char *)pevent->ring.callednum); - ftdm_set_string(caller_data->rdnis.digits, (char *)pevent->ring.redirectingnum); - - if (pevent->ring.callingpres == PRES_ALLOWED_USER_NUMBER_NOT_SCREENED) { - caller_data->pres = FTDM_PRES_ALLOWED; - caller_data->screen = FTDM_SCREENING_NOT_SCREENED; - } else if (pevent->ring.callingpres == PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN) { - caller_data->pres = FTDM_PRES_ALLOWED; - caller_data->screen = FTDM_SCREENING_VERIFIED_PASSED; - } else if (pevent->ring.callingpres == PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN) { - caller_data->pres = FTDM_PRES_ALLOWED; - caller_data->screen = FTDM_SCREENING_VERIFIED_FAILED; - } else if (pevent->ring.callingpres == PRES_ALLOWED_NETWORK_NUMBER) { - caller_data->pres = FTDM_PRES_ALLOWED; - caller_data->screen = FTDM_SCREENING_NETWORK_PROVIDED; - } else if (pevent->ring.callingpres == PRES_PROHIB_USER_NUMBER_NOT_SCREENED) { - caller_data->pres = FTDM_PRES_RESTRICTED; - caller_data->screen = FTDM_SCREENING_NOT_SCREENED; - } else if (pevent->ring.callingpres == PRES_PROHIB_USER_NUMBER_PASSED_SCREEN) { - caller_data->pres = FTDM_PRES_RESTRICTED; - caller_data->screen = FTDM_SCREENING_VERIFIED_PASSED; - } else if (pevent->ring.callingpres == PRES_PROHIB_USER_NUMBER_FAILED_SCREEN) { - caller_data->pres = FTDM_PRES_RESTRICTED; - caller_data->screen = FTDM_SCREENING_VERIFIED_FAILED; - } else if (pevent->ring.callingpres == PRES_PROHIB_NETWORK_NUMBER) { - caller_data->pres = FTDM_PRES_RESTRICTED; - caller_data->screen = FTDM_SCREENING_NETWORK_PROVIDED; - } else if (pevent->ring.callingpres == PRES_NUMBER_NOT_AVAILABLE) { - caller_data->pres = FTDM_PRES_NOT_AVAILABLE; - caller_data->screen = FTDM_SCREENING_NETWORK_PROVIDED; - } else { - caller_data->pres = FTDM_PRES_INVALID; - caller_data->screen = FTDM_SCREENING_INVALID; - } - - if (pevent->ring.callingplanani != -1) { - caller_data->ani.type = pevent->ring.callingplanani >> 4; - caller_data->ani.plan = pevent->ring.callingplanani & 0x0F; - } else { - /* the remote party did not sent a valid (according to libpri) ANI ton, - * so let's use the callingplan ton/type and hope is correct. - */ - caller_data->ani.type = pevent->ring.callingplan >> 4; - caller_data->ani.plan = pevent->ring.callingplan & 0x0F; - } - - caller_data->cid_num.type = pevent->ring.callingplan >> 4; - caller_data->cid_num.plan = pevent->ring.callingplan & 0x0F; - - caller_data->dnis.type = pevent->ring.calledplan >> 4; - caller_data->dnis.plan = pevent->ring.calledplan & 0x0F; - - if (!ftdm_strlen_zero((char *)pevent->ring.callingname)) { - ftdm_set_string(caller_data->cid_name, (char *)pevent->ring.callingname); - } else { - ftdm_set_string(caller_data->cid_name, (char *)pevent->ring.callingnum); - } - - if (pevent->ring.ani2 >= 0) { - snprintf(caller_data->aniII, 5, "%.2d", pevent->ring.ani2); - } - - // scary to trust this pointer, you'd think they would give you a copy of the call data so you own it...... - /* hurr, this is valid as along as nobody releases the call */ - chan_priv->call = pevent->ring.call; - - /* Open Channel if inband information is available */ - if ((pevent->ring.progressmask & PRI_PROG_INBAND_AVAILABLE)) { - /* Open channel if inband information is available */ - ftdm_log(FTDM_LOG_DEBUG, "-- In-band information available, opening B-Channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - - if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN) && ftdm_channel_open_chan(chan) != FTDM_SUCCESS) { -// ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - - ftdm_log(FTDM_LOG_WARNING, "-- Error opening channel %d:%d (ignored)\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - -// caller_data->hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER; -// ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING); -// goto done; - } - } - - ftdm_log(FTDM_LOG_NOTICE, "-- Ring on channel %d:%d (from %s to %s)\n", ftdm_span_get_id(span), pevent->ring.channel, - pevent->ring.callingnum, pevent->ring.callednum); - - /* Only go to RING state if we have the complete called number (indicated via pevent->complete flag) */ - if (!pevent->ring.complete && (isdn_data->overlap & FTMOD_LIBPRI_OVERLAP_RECEIVE)) { - ftdm_log(FTDM_LOG_DEBUG, "RING event without complete indicator, waiting for more digits\n"); - ftdm_set_state(chan, FTDM_CHANNEL_STATE_COLLECT); - } else { - ftdm_log(FTDM_LOG_DEBUG, "RING event with complete indicator (or overlap receive disabled)\n"); - ftdm_set_state(chan, FTDM_CHANNEL_STATE_RING); - } -done: - ftdm_channel_unlock(chan); - return ret; -} - - -/** - * Timeout handler for T302 (overlap receiving) - */ -static int on_timeout_t302(struct lpwrap_pri *spri, struct lpwrap_timer *timer) -{ - ftdm_libpri_b_chan_t *chan_priv = ftdm_container_of(timer, ftdm_libpri_b_chan_t, t302); - ftdm_channel_t *chan = chan_priv->channel; - - ftdm_unused_arg(spri); - - ftdm_log_chan_msg(chan, FTDM_LOG_INFO, "-- T302 timed out, going to state RING\n"); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RING); - return 0; -} - -/** - * Timeout handler for T316 (RESTART ACK timer) - */ -static int on_timeout_t316(struct lpwrap_pri *spri, struct lpwrap_timer *timer) -{ - ftdm_libpri_b_chan_t *chan_priv = ftdm_container_of(timer, ftdm_libpri_b_chan_t, t316); - ftdm_libpri_data_t *isdn_data = ftdm_container_of(spri, ftdm_libpri_data_t, spri); - ftdm_channel_t *chan = chan_priv->channel; - - if (++chan_priv->t316_timeout_cnt > isdn_data->t316_max_attempts) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "-- T316 timed out, channel reached restart attempt limit '%d' and is suspended\n", - isdn_data->t316_max_attempts); - - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_SUSPENDED); - } else { - ftdm_log_chan_msg(chan, FTDM_LOG_WARNING, "-- T316 timed out, resending RESTART request\n"); - pri_reset(spri->pri, ftdm_channel_get_id(chan)); - - /* Restart T316 */ - lpwrap_start_timer(spri, timer, isdn_data->t316_timeout_ms, &on_timeout_t316); - } - return 0; -} - - -/** - * Timeout handler for T3xx (NT-mode idle restart) - */ -static int on_timeout_t3xx(struct lpwrap_pri *spri, struct lpwrap_timer *timer) -{ - ftdm_span_t *span = spri->span; - ftdm_libpri_data_t *isdn_data = span->signal_data; - ftdm_iterator_t *c_iter, *c_cur; - - ftdm_log_chan_msg(isdn_data->dchan, FTDM_LOG_INFO, "-- T3xx timed out, restarting idle b-channels\n"); - ftdm_mutex_lock(span->mutex); - - c_iter = ftdm_span_get_chan_iterator(span, NULL); - - /* Iterate b-channels */ - for (c_cur = c_iter; c_cur; c_cur = ftdm_iterator_next(c_cur)) { - ftdm_channel_t *cur = ftdm_iterator_current(c_cur); - /* Skip non-b-channels */ - if (ftdm_channel_get_type(cur) != FTDM_CHAN_TYPE_B) - continue; - /* Restart idle b-channels */ - if (ftdm_channel_get_state(cur) == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(cur, FTDM_CHANNEL_INUSE)) { - ftdm_set_state_locked(cur, FTDM_CHANNEL_STATE_RESTART); - } - } - ftdm_iterator_free(c_iter); - ftdm_mutex_unlock(span->mutex); - - /* Start timer again */ - lpwrap_start_timer(spri, timer, isdn_data->idle_restart_timeout_ms, &on_timeout_t3xx); - return 0; -} - - -/** - * \brief Processes freetdm event - * \param span Span on which the event was fired - * \param event Event to be treated - * \return Success or failure - */ -static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event) -{ - ftdm_alarm_flag_t alarmbits; - - ftdm_unused_arg(span); - - ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d][%d:%d] STATE [%s]\n", - ftdm_oob_event2str(event->enum_id), - event->enum_id, - ftdm_channel_get_span_id(event->channel), - ftdm_channel_get_id(event->channel), - ftdm_channel_get_state_str(event->channel)); - - switch (event->enum_id) { - case FTDM_OOB_ALARM_TRAP: - { - if (ftdm_channel_get_state(event->channel) != FTDM_CHANNEL_STATE_DOWN) { - if (ftdm_channel_get_type(event->channel) == FTDM_CHAN_TYPE_B) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RESTART); - } - } - - ftdm_set_flag(event->channel, FTDM_CHANNEL_SUSPENDED); - ftdm_channel_get_alarms(event->channel, &alarmbits); - ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING, "channel has alarms!\n"); - } - break; - case FTDM_OOB_ALARM_CLEAR: - { - ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED); - ftdm_channel_get_alarms(event->channel, &alarmbits); - ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING, "channel alarms cleared!\n"); - } - break; - } - return FTDM_SUCCESS; -} - -/** - * \brief Checks for events on a span - * \param span Span to check for events - */ -static __inline__ void check_events(ftdm_span_t *span) -{ - ftdm_status_t status; - - status = ftdm_span_poll_event(span, 5, NULL); - - switch (status) { - case FTDM_SUCCESS: - { - ftdm_event_t *event; - - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { - if (event->enum_id == FTDM_OOB_NOOP) { - continue; - } - if (process_event(span, event) != FTDM_SUCCESS) { - break; - } - } - } - break; - - case FTDM_FAIL: - ftdm_log(FTDM_LOG_DEBUG, "Event Failure! %d\n", ftdm_running()); - ftdm_sleep(2000); - break; - - default: - break; - } -} - -/** - * \brief Checks flags on a pri span - * \param spri Pri wrapper structure (libpri, span, dchan) - * \return 0 on success, -1 on error - */ -static int check_flags(lpwrap_pri_t *spri) -{ - ftdm_span_t *span = spri->span; - check_state(span); - check_events(span); - return 0; -} - -/** - * \brief Handler for libpri restart event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_restart(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_channel_t *chan = NULL; - ftdm_span_t *span = spri->span; - int i; - - ftdm_unused_arg(event_type); - - if (pevent->restart.channel < 1) { - ftdm_log_chan_msg(spri->dchan, FTDM_LOG_DEBUG, "-- Restarting interface\n"); - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - chan = ftdm_span_get_channel(span, i); - if (!chan) - continue; - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - ftdm_libpri_b_chan_t *chan_priv = chan->call_data; - chan_priv->flags |= FTDM_LIBPRI_B_REMOTE_RESTART; /* Remote triggered RESTART, set flag */ - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } - } - } - else if ((chan = ftdm_span_get_channel(span, pevent->restart.channel))) { - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - ftdm_libpri_b_chan_t *chan_priv = chan->call_data; - - ftdm_log_chan_msg(chan, FTDM_LOG_DEBUG, "-- Restarting single channel\n"); - chan_priv->flags |= FTDM_LIBPRI_B_REMOTE_RESTART; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); - } else { - ftdm_log_chan_msg(chan, FTDM_LOG_NOTICE, "Ignoring RESTART on D-Channel\n"); - } - } - else { - ftdm_log(FTDM_LOG_ERROR, "Invalid restart indicator / channel id '%d' received\n", - pevent->restart.channel); - } - - _ftdm_channel_set_state_force(spri->dchan, FTDM_CHANNEL_STATE_UP); - return 0; -} - -/** - * \brief Handler for libpri restart acknowledge event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_restart_ack(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_channel_t *chan = NULL; - ftdm_span_t *span = spri->span; - int i; - - ftdm_unused_arg(event_type); - - if (pevent->restartack.channel < 1) { - ftdm_log_chan_msg(spri->dchan, FTDM_LOG_DEBUG, "-- Restart of interface completed\n"); - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - chan = ftdm_span_get_channel(span, i); - if (!chan) - continue; - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - ftdm_libpri_b_chan_t *chan_priv = chan->call_data; - if (!(chan_priv->flags & FTDM_LIBPRI_B_REMOTE_RESTART)) { - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); - } - } - } - } - else if ((chan = ftdm_span_get_channel(span, pevent->restart.channel))) { - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - ftdm_log_chan_msg(chan, FTDM_LOG_DEBUG, "-- Restart of channel completed\n"); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); - } else { - ftdm_log_chan_msg(chan, FTDM_LOG_NOTICE, "Ignoring RESTART ACK on D-Channel\n"); - } - } - else { - ftdm_log(FTDM_LOG_ERROR, "Invalid restart indicator / channel id '%d' received\n", - pevent->restartack.channel); - } - - _ftdm_channel_set_state_force(spri->dchan, FTDM_CHANNEL_STATE_UP); - return 0; -} - - - - -/* - * FACILITY Advice-On-Charge handler - */ -#if defined(HAVE_LIBPRI_AOC) && defined(PRI_EVENT_FACILITY) -static const char *aoc_billing_id(const int id) -{ - switch (id) { - case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE: - return "not available"; - case PRI_AOC_E_BILLING_ID_NORMAL: - return "normal"; - case PRI_AOC_E_BILLING_ID_REVERSE: - return "reverse"; - case PRI_AOC_E_BILLING_ID_CREDIT_CARD: - return "credit card"; - case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL: - return "call forwarding unconditional"; - case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY: - return "call forwarding busy"; - case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY: - return "call forwarding no reply"; - case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION: - return "call deflection"; - case PRI_AOC_E_BILLING_ID_CALL_TRANSFER: - return "call transfer"; - default: - return "unknown\n"; - } -} - -static float aoc_money_amount(const struct pri_aoc_amount *amount) -{ - switch (amount->multiplier) { - case PRI_AOC_MULTIPLIER_THOUSANDTH: - return amount->cost * 0.001f; - case PRI_AOC_MULTIPLIER_HUNDREDTH: - return amount->cost * 0.01f; - case PRI_AOC_MULTIPLIER_TENTH: - return amount->cost * 0.1f; - case PRI_AOC_MULTIPLIER_TEN: - return amount->cost * 10.0f; - case PRI_AOC_MULTIPLIER_HUNDRED: - return amount->cost * 100.0f; - case PRI_AOC_MULTIPLIER_THOUSAND: - return amount->cost * 1000.0f; - default: - return amount->cost; - } -} - -static int handle_facility_aoc_s(const struct pri_subcmd_aoc_s *aoc_s) -{ - /* Left as an excercise to the reader */ - ftdm_unused_arg(aoc_s); - return 0; -} - -static int handle_facility_aoc_d(const struct pri_subcmd_aoc_d *aoc_d) -{ - /* Left as an excercise to the reader */ - ftdm_unused_arg(aoc_d); - return 0; -} - -static int handle_facility_aoc_e(const struct pri_subcmd_aoc_e *aoc_e) -{ - char tmp[1024] = { 0 }; - int x = 0, offset = 0; - - switch (aoc_e->charge) { - case PRI_AOC_DE_CHARGE_FREE: - strcat(tmp, "\tcharge-type: none\n"); - offset = strlen(tmp); - break; - - case PRI_AOC_DE_CHARGE_CURRENCY: - sprintf(tmp, "\tcharge-type: money\n\tcharge-amount: %.2f\n\tcharge-currency: %s\n", - aoc_money_amount(&aoc_e->recorded.money.amount), - aoc_e->recorded.money.currency); - offset = strlen(tmp); - break; - - case PRI_AOC_DE_CHARGE_UNITS: - strcat(tmp, "\tcharge-type: units\n"); - offset = strlen(tmp); - - for (x = 0; x < aoc_e->recorded.unit.num_items; x++) { - sprintf(&tmp[offset], "\tcharge-amount: %ld (type: %d)\n", - aoc_e->recorded.unit.item[x].number, - aoc_e->recorded.unit.item[x].type); - offset += strlen(&tmp[offset]); - } - break; - - default: - strcat(tmp, "\tcharge-type: not available\n"); - offset = strlen(tmp); - } - - sprintf(&tmp[offset], "\tbilling-id: %s\n", aoc_billing_id(aoc_e->billing_id)); - offset += strlen(&tmp[offset]); - - strcat(&tmp[offset], "\tassociation-type: "); - offset += strlen(&tmp[offset]); - - switch (aoc_e->associated.charging_type) { - case PRI_AOC_E_CHARGING_ASSOCIATION_NOT_AVAILABLE: - strcat(&tmp[offset], "not available\n"); - break; - case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER: - sprintf(&tmp[offset], "number\n\tassociation-number: %s\n", aoc_e->associated.charge.number.str); - break; - case PRI_AOC_E_CHARGING_ASSOCIATION_ID: - sprintf(&tmp[offset], "id\n\tassociation-id: %d\n", aoc_e->associated.charge.id); - break; - default: - strcat(&tmp[offset], "unknown\n"); - } - - ftdm_log(FTDM_LOG_INFO, "AOC-E:\n%s", tmp); - return 0; -} -#endif - -#ifdef PRI_EVENT_FACILITY -/** - * \brief Handler for libpri facility events - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_facility(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - struct pri_event_facility *pfac = &pevent->facility; - int i = 0; - - if (!pevent) - return 0; - - ftdm_log(FTDM_LOG_DEBUG, "Got a FACILITY event on span %d:%d\n", ftdm_span_get_id(spri->span), pfac->channel); - - if (!pfac->subcmds || pfac->subcmds->counter_subcmd <= 0) - return 0; - - for (i = 0; i < pfac->subcmds->counter_subcmd; i++) { - struct pri_subcommand *sub = &pfac->subcmds->subcmd[i]; - int res = -1; - - switch (sub->cmd) { -#ifdef HAVE_LIBPRI_AOC - case PRI_SUBCMD_AOC_S: /* AOC-S: Start of call */ - res = handle_facility_aoc_s(&sub->u.aoc_s); - break; - case PRI_SUBCMD_AOC_D: /* AOC-D: During call */ - res = handle_facility_aoc_d(&sub->u.aoc_d); - break; - case PRI_SUBCMD_AOC_E: /* AOC-E: End of call */ - res = handle_facility_aoc_e(&sub->u.aoc_e); - break; - case PRI_SUBCMD_AOC_CHARGING_REQ: - ftdm_log(FTDM_LOG_NOTICE, "AOC Charging Request received\n"); - break; - case PRI_SUBCMD_AOC_CHARGING_REQ_RSP: - ftdm_log(FTDM_LOG_NOTICE, "AOC Charging Request Response received [aoc_s data: %s, req: %x, resp: %x]\n", - sub->u.aoc_request_response.valid_aoc_s ? "yes" : "no", - sub->u.aoc_request_response.charging_request, - sub->u.aoc_request_response.charging_response); - break; -#endif - default: - ftdm_log(FTDM_LOG_DEBUG, "FACILITY subcommand %d is not implemented, ignoring\n", sub->cmd); - } - - ftdm_log(FTDM_LOG_DEBUG, "FACILITY subcommand %d handler returned %d\n", sub->cmd, res); - } - - ftdm_log(FTDM_LOG_DEBUG, "Caught Event on span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type)); - return 0; -} -#endif - -/** - * \brief Handler for libpri dchan up event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_unused_arg(event_type); - ftdm_unused_arg(pevent); - - if (!ftdm_test_flag(spri, LPWRAP_PRI_READY)) { - ftdm_signaling_status_t status = FTDM_SIG_STATE_UP; - ftdm_span_t *span = spri->span; - ftdm_libpri_data_t *isdn_data = span->signal_data; - ftdm_sigmsg_t sig; - int i; - - ftdm_log(FTDM_LOG_INFO, "Span %d D-Channel UP!\n", ftdm_span_get_id(span)); - ftdm_set_flag(spri, LPWRAP_PRI_READY); - ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART); - - ftdm_log(FTDM_LOG_NOTICE, "%d:Signaling link status changed to %s\n", ftdm_span_get_id(span), ftdm_signaling_status2str(status)); - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - - memset(&sig, 0, sizeof(sig)); - sig.span_id = ftdm_channel_get_span_id(chan); - sig.chan_id = ftdm_channel_get_id(chan); - sig.channel = chan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - ftdm_span_send_signal(span, &sig); - } - - /* NT-mode idle b-channel restart timer */ - if (ftdm_span_get_trunk_type(span) != FTDM_TRUNK_BRI_PTMP && - isdn_data->mode == PRI_NETWORK && isdn_data->idle_restart_timeout_ms > 0) - { - ftdm_log_chan(isdn_data->dchan, FTDM_LOG_INFO, "Starting NT-mode idle b-channel restart timer (%d ms)\n", - isdn_data->idle_restart_timeout_ms); - lpwrap_start_timer(&isdn_data->spri, &isdn_data->t3xx, isdn_data->idle_restart_timeout_ms, &on_timeout_t3xx); - } - } - return 0; -} - -/** - * \brief Handler for libpri dchan down event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_unused_arg(event_type); - ftdm_unused_arg(pevent); - - if (ftdm_test_flag(spri, LPWRAP_PRI_READY)) { - ftdm_signaling_status_t status = FTDM_SIG_STATE_DOWN; - ftdm_span_t *span = spri->span; - ftdm_libpri_data_t *isdn_data = span->signal_data; - ftdm_sigmsg_t sig; - int i; - - ftdm_log(FTDM_LOG_INFO, "Span %d D-Channel DOWN!\n", ftdm_span_get_id(span)); - ftdm_clear_flag(spri, LPWRAP_PRI_READY); - ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART); - - ftdm_log(FTDM_LOG_NOTICE, "%d:Signaling link status changed to %s\n", ftdm_span_get_id(span), ftdm_signaling_status2str(status)); - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - - memset(&sig, 0, sizeof(sig)); - sig.span_id = ftdm_channel_get_span_id(chan); - sig.chan_id = ftdm_channel_get_id(chan); - sig.channel = chan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - - ftdm_span_send_signal(span, &sig); - - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - ftdm_libpri_b_chan_t *chan_priv = chan->call_data; - /* Stop T316 and reset counter */ - lpwrap_stop_timer(spri, &chan_priv->t316); - chan_priv->t316_timeout_cnt = 0; - } - } - - /* NT-mode idle b-channel restart timer */ - ftdm_log_chan_msg(isdn_data->dchan, FTDM_LOG_INFO, "Stopping NT-mode idle b-channel restart timer\n"); - lpwrap_stop_timer(&isdn_data->spri, &isdn_data->t3xx); - } - return 0; -} - -/** - * \brief Handler for any libpri event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_anything(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_log(FTDM_LOG_DEBUG, "-- Caught Event span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type)); - switch (pevent->e) { - case PRI_EVENT_CONFIG_ERR: - { - ftdm_log(FTDM_LOG_WARNING, "-- PRI error event: %s\n", pevent->err.err); - } - break; - } - return 0; -} - -/** - * \brief Handler for libpri io fail event - * \param spri Pri wrapper structure (libpri, span, dchan) - * \param event_type Event type (unused) - * \param pevent Event - * \return 0 - */ -static int on_io_fail(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - ftdm_unused_arg(pevent); - - ftdm_log(FTDM_LOG_DEBUG, "-- Caught Event span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type)); - return 0; -} - -/** - * \brief Main thread function for libpri span (monitor) - * \param me Current thread - * \param obj Span to run in this thread - * - * \todo Move all init stuff outside of loop or into ftdm_libpri_configure_span() - */ -static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_libpri_data_t *isdn_data = span->signal_data; - int down = 0; - int res = 0; - int i; - - ftdm_unused_arg(me); - - ftdm_set_flag(span, FTDM_SPAN_IN_THREAD); - isdn_data->dchan = NULL; - - /* - * Open D-Channel - */ - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_DQ921) { - if (ftdm_channel_open(ftdm_span_get_id(span), i, &isdn_data->dchan) == FTDM_SUCCESS) { - ftdm_log_chan_msg(chan, FTDM_LOG_DEBUG, "Opened D-Channel\n"); - break; - } else { - ftdm_log_chan_msg(chan, FTDM_LOG_CRIT, "Failed to open D-Channel\n"); - goto out; - } - } - } - - /* - * Initialize BRI/PRI context - */ - res = lpwrap_init_pri(&isdn_data->spri, span, isdn_data->dchan, - isdn_data->dialect, isdn_data->mode, isdn_data->debug_mask); - - if (res) { - ftdm_log(FTDM_LOG_CRIT, "Failed to initialize BRI/PRI on span %d\n", - ftdm_span_get_id(span)); - goto out; - } - -#ifdef HAVE_LIBPRI_AOC - /* - * Only enable facility on trunk if really required, - * this may help avoid problems on troublesome lines. - */ - if (isdn_data->opts & FTMOD_LIBPRI_OPT_FACILITY_AOC) { - pri_facility_enable(isdn_data->spri.pri); - } -#endif -#ifdef HAVE_LIBPRI_MAINT_SERVICE - /* Support the different switch of service status */ - if (isdn_data->service_message_support) { - pri_set_service_message_support(isdn_data->spri.pri, 1); - } -#endif - - /* Callbacks for libpri events */ - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_ANY, on_anything); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RING, on_ring); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RINGING, on_ringing); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_PROCEEDING, on_proceeding); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_PROGRESS, on_progress); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_ANSWER, on_answer); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_UP, on_dchan_up); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_DOWN, on_dchan_down); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_REQ, on_hangup); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_ACK, on_hangup); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP, on_hangup); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_INFO_RECEIVED, on_information); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_KEYPAD_DIGIT, on_keypad_digit); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RESTART, on_restart); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RESTART_ACK, on_restart_ack); - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_IO_FAIL, on_io_fail); -#ifdef PRI_EVENT_FACILITY - LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_FACILITY, on_facility); -#endif - - /* Callback invoked on each iteration of the lpwrap_run_pri() event loop */ - isdn_data->spri.on_loop = check_flags; - - /* - * Event loop - */ - while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { - if (down) { - ftdm_log(FTDM_LOG_INFO, "PRI back up on span %d\n", ftdm_span_get_id(span)); - ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART); - down = 0; - } - - lpwrap_run_pri(&isdn_data->spri); - - if (!ftdm_running() || ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { - break; - } - - ftdm_log(FTDM_LOG_CRIT, "PRI down on span %d\n", ftdm_span_get_id(span)); - if (isdn_data->spri.dchan) { - _ftdm_channel_set_state_force(isdn_data->spri.dchan, FTDM_CHANNEL_STATE_DOWN); - } - - if (!down) { - ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART); - check_state(span); - } - - check_state(span); - check_events(span); - - down = 1; - ftdm_sleep(5000); - } -out: - /* close d-channel, if set */ - if (isdn_data->dchan) { - if (ftdm_channel_close(&isdn_data->dchan) != FTDM_SUCCESS) { - ftdm_log_chan_msg(isdn_data->dchan, FTDM_LOG_ERROR, "Failed to close D-Channel\n"); - } - } - - ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", ftdm_span_get_id(span)); - - ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); - ftdm_clear_flag(isdn_data, FTMOD_LIBPRI_RUNNING); - - lpwrap_destroy_pri(&isdn_data->spri); - return NULL; -} - -/** - * \brief Stops a libpri span - * \param span Span to halt - * \return Success - * - * Sets a stop flag and waits for the thread to end - */ -static ftdm_status_t ftdm_libpri_stop(ftdm_span_t *span) -{ - ftdm_libpri_data_t *isdn_data = span->signal_data; - - if (!ftdm_test_flag(isdn_data, FTMOD_LIBPRI_RUNNING)) { - ftdm_log(FTDM_LOG_DEBUG, "Span %d already stopped, continuing anyway...\n", ftdm_span_get_id(span)); - return FTDM_SUCCESS; - } - - ftdm_log(FTDM_LOG_INFO, "Stopping span [s%d][%s]\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART); - check_state(span); - - ftdm_set_flag(span, FTDM_SPAN_STOP_THREAD); - lpwrap_stop_pri(&isdn_data->spri); - - while (ftdm_test_flag(span, FTDM_SPAN_IN_THREAD)) { - ftdm_sleep(100); - } - - check_state(span); - - return FTDM_SUCCESS; -} - -/** - * \brief Starts a libpri span - * \param span Span to halt - * \return Success or failure - * - * Launches a thread to monitor the span - */ -static ftdm_status_t ftdm_libpri_start(ftdm_span_t *span) -{ - ftdm_libpri_data_t *isdn_data = span->signal_data; - - if (ftdm_test_flag(isdn_data, FTMOD_LIBPRI_RUNNING)) { - return FTDM_FAIL; - } - - ftdm_log(FTDM_LOG_INFO, "Starting span [s%d][%s]\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD); - ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); - - ftdm_set_flag(isdn_data, FTMOD_LIBPRI_RUNNING); - - return ftdm_thread_create_detached(ftdm_libpri_run, span); -} - -/** - * \brief Converts a node string to node value - * \param node Node string to convert - * \return -1 on failure, node value on success - */ -static int parse_mode(const char *mode) -{ - if (!strcasecmp(mode, "cpe") || !strcasecmp(mode, "user")) - return PRI_CPE; - if (!strcasecmp(mode, "network") || !strcasecmp(mode, "net")) - return PRI_NETWORK; - - return -1; -} - -/** - * \brief Converts a switch string to switch value - * \param swtype Swtype string to convert - * \return Switch value - */ -static int parse_dialect(const char *dialect) -{ - if (!strcasecmp(dialect, "ni1")) - return PRI_SWITCH_NI1; - if (!strcasecmp(dialect, "ni2")) - return PRI_SWITCH_NI2; - if (!strcasecmp(dialect, "dms100")) - return PRI_SWITCH_DMS100; - if (!strcasecmp(dialect, "lucent5e") || !strcasecmp(dialect, "5ess")) - return PRI_SWITCH_LUCENT5E; - if (!strcasecmp(dialect, "att4ess") || !strcasecmp(dialect, "4ess")) - return PRI_SWITCH_ATT4ESS; - if (!strcasecmp(dialect, "euroisdn") || !strcasecmp(dialect, "q931")) - return PRI_SWITCH_EUROISDN_E1; - if (!strcasecmp(dialect, "gr303eoc")) - return PRI_SWITCH_GR303_EOC; - if (!strcasecmp(dialect, "gr303tmc")) - return PRI_SWITCH_GR303_TMC; - - return PRI_SWITCH_DMS100; -} - -/** - * \brief Converts a L1 string to L1 value - * \param l1 L1 string to convert - * \return L1 value - */ -static int parse_layer1(const char *val) -{ - if (!strcasecmp(val, "alaw")) - return PRI_LAYER_1_ALAW; - - return PRI_LAYER_1_ULAW; -} - -/** - * \brief Converts a DP string to DP value - * \param dp DP string to convert - * \return DP value - */ -static int parse_ton(const char *ton) -{ - if (!strcasecmp(ton, "international")) - return PRI_INTERNATIONAL_ISDN; - if (!strcasecmp(ton, "national")) - return PRI_NATIONAL_ISDN; - if (!strcasecmp(ton, "local")) - return PRI_LOCAL_ISDN; - if (!strcasecmp(ton, "private")) - return PRI_PRIVATE; - if (!strcasecmp(ton, "unknown")) - return PRI_UNKNOWN; - - return PRI_UNKNOWN; -} - -/** - * \brief Parse overlap string to value - * \param val String to parse - * \return Overlap flags - */ -static int parse_overlap_dial(const char *val) -{ - if (!strcasecmp(val, "yes") || !strcasecmp(val, "both")) - return FTMOD_LIBPRI_OVERLAP_BOTH; - if (!strcasecmp(val, "incoming") || !strcasecmp(val, "receive")) - return FTMOD_LIBPRI_OVERLAP_RECEIVE; - if (!strcasecmp(val, "outgoing") || !strcasecmp(val, "send")) - return FTMOD_LIBPRI_OVERLAP_SEND; - if (!strcasecmp(val, "no")) - return FTMOD_LIBPRI_OVERLAP_NONE; - - return -1; -} - -/** - * \brief Parses an option string to flags - * \param in String to parse for configuration options - * \return Flags - */ -static uint32_t parse_opts(const char *in) -{ - uint32_t flags = 0; - - if (!in) { - return 0; - } - - if (strstr(in, "suggest_channel")) { - flags |= FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL; - } - if (strstr(in, "omit_display")) { - flags |= FTMOD_LIBPRI_OPT_OMIT_DISPLAY_IE; - } - if (strstr(in, "omit_redirecting_number")) { - flags |= FTMOD_LIBPRI_OPT_OMIT_REDIRECTING_NUMBER_IE; - } - if (strstr(in, "aoc")) { - flags |= FTMOD_LIBPRI_OPT_FACILITY_AOC; - } - return flags; -} - -/** - * Parse timeout value with (convenience) modifier suffix - * \param[in] in Input string, e.g. '1d' = 1 day, '7w' = 7 weeks, '3s' = 3 seconds - * \todo Could be simplified by using strtol() instead of atoi() - */ -static int parse_timeout(const char *in) -{ - const char *p_end = NULL, *p_start = in; - int msec = 0; - - if (ftdm_strlen_zero(in)) - return 0; - - p_end = in + strlen(in); - - /* skip whitespace at start */ - while (p_start != p_end && *p_start == ' ') - p_start++; - - /* skip whitespace at end */ - while (p_end != p_start && (*p_end == ' ' || *p_end == '\0')) - p_end--; - - msec = atoi(p_start); - - switch (p_end[0]) { - case 's': /* seconds */ - msec *= 1000; - break; - case 'm': /* minutes */ - if (p_end[1] != 's') msec *= 60 * 1000; - break; - case 'h': /* hours */ - msec *= 3600 * 1000; - break; - case 'd': /* days */ - msec *= 86400 * 1000; - break; - case 'w': /* weeks */ - msec *= 604800 * 1000; - break; - default: /* miliseconds */ - break; - } - return msec; -} - -/** - * \brief Initialises a libpri span from configuration variables - * \param span Span to configure - * \param sig_cb Callback function for event signals - * \param ftdm_parameters List of configuration variables - * \return Success or failure - */ -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span) -{ - ftdm_libpri_data_t *isdn_data = NULL; - uint32_t bchan_count = 0; - uint32_t dchan_count = 0; - uint32_t i; - - if (ftdm_span_get_trunk_type(span) >= FTDM_TRUNK_NONE) { - ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1.\n", ftdm_span_get_trunk_type_str(span)); - ftdm_span_set_trunk_type(span, FTDM_TRUNK_T1); - } - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - - switch (ftdm_channel_get_type(chan)) { - case FTDM_CHAN_TYPE_DQ921: - if (dchan_count > 1) { - ftdm_log(FTDM_LOG_ERROR, "Span has more than 2 D-Channels!\n"); - return FTDM_FAIL; - } - dchan_count++; - break; - case FTDM_CHAN_TYPE_B: - bchan_count++; - break; - default: /* Ignore other channel types */ - break; - } - } - if (!dchan_count) { - ftdm_log(FTDM_LOG_ERROR, "Span has no D-Channel!\n"); - return FTDM_FAIL; - } - if (!bchan_count) { - ftdm_log(FTDM_LOG_ERROR, "Span has no B-Channels!\n"); - return FTDM_FAIL; - } - - isdn_data = ftdm_malloc(sizeof(*isdn_data)); - assert(isdn_data != NULL); - memset(isdn_data, 0, sizeof(*isdn_data)); - - /* set some default values */ - isdn_data->ton = PRI_UNKNOWN; - isdn_data->overlap_timeout_ms = OVERLAP_TIMEOUT_MS_DEFAULT; - isdn_data->idle_restart_timeout_ms = IDLE_RESTART_TIMEOUT_MS_DEFAULT; - - /* - * T316 restart ack timeout and retry limit - * (ITU-T Q.931 05/98 Paragraph 5.5.1 and Table 9-1) - */ - isdn_data->t316_timeout_ms = T316_TIMEOUT_MS_DEFAULT; - isdn_data->t316_max_attempts = T316_ATTEMPT_LIMIT_DEFAULT; - - - /* Use span's trunk_mode as a reference for the default libpri mode */ - if (ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) { - isdn_data->mode = PRI_NETWORK; - } else { - isdn_data->mode = PRI_CPE; - } - - switch (ftdm_span_get_trunk_type(span)) { - case FTDM_TRUNK_BRI: - case FTDM_TRUNK_BRI_PTMP: -#ifndef HAVE_LIBPRI_BRI - ftdm_log(FTDM_LOG_ERROR, "Unsupported trunk type: '%s', libpri too old\n", ftdm_span_get_trunk_type_str(span)); - goto error; -#endif - case FTDM_TRUNK_E1: - ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ALAW since this is an E1/BRI/BRI PTMP trunk\n"); - isdn_data->layer1 = PRI_LAYER_1_ALAW; - isdn_data->dialect = PRI_SWITCH_EUROISDN_E1; - break; - case FTDM_TRUNK_T1: - case FTDM_TRUNK_J1: - ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ULAW since this is a T1/J1 trunk\n"); - isdn_data->layer1 = PRI_LAYER_1_ULAW; - isdn_data->dialect = PRI_SWITCH_LUCENT5E; - break; - default: - ftdm_log(FTDM_LOG_ERROR, "Invalid trunk type: '%s'\n", ftdm_span_get_trunk_type_str(span)); - goto error; - } - - /* - * Init MSN filter - */ - if (msn_filter_init(isdn_data) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to init MSN filter\n"); - goto error; - } - - for (i = 0; ftdm_parameters[i].var; i++) { - const char *var = ftdm_parameters[i].var; - const char *val = ftdm_parameters[i].val; - - if (ftdm_strlen_zero(var)) { - ftdm_log(FTDM_LOG_WARNING, "Skipping parameter with no name\n"); - continue; - } - - if (ftdm_strlen_zero(val)) { - ftdm_log(FTDM_LOG_ERROR, "Parameter '%s' has no value\n", var); - goto error; - } - - if (!strcasecmp(var, "node") || !strcasecmp(var, "mode")) { - if ((isdn_data->mode = parse_mode(val)) == -1) { - ftdm_log(FTDM_LOG_ERROR, "Unknown node type '%s'\n", val); - goto error; - } - } - else if (!strcasecmp(var, "switch") || !strcasecmp(var, "dialect")) { - isdn_data->dialect = parse_dialect(val); - } - else if (!strcasecmp(var, "opts")) { - isdn_data->opts = parse_opts(val); - } - else if (!strcasecmp(var, "dp") || !strcasecmp(var, "ton")) { - isdn_data->ton = parse_ton(val); - } - else if (!strcasecmp(var, "l1") || !strcasecmp(var, "layer1")) { - isdn_data->layer1 = parse_layer1(val); - } - else if (!strcasecmp(var, "overlapdial")) { - if ((isdn_data->overlap = parse_overlap_dial(val)) == -1) { - ftdm_log(FTDM_LOG_ERROR, "Invalid overlap flag, ignoring parameter\n"); - isdn_data->overlap = FTMOD_LIBPRI_OVERLAP_NONE; - } - } - else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "t302")) { - int tmp = parse_timeout(val); - if (!tmp) { - isdn_data->overlap_timeout_ms = 0; /* disabled */ - } - else if ((isdn_data->overlap_timeout_ms = ftdm_clamp(tmp, OVERLAP_TIMEOUT_MS_MIN, OVERLAP_TIMEOUT_MS_MAX)) != tmp) { - ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ms ('%s') outside of range [%d:%d] ms, using %d ms instead\n", - var, tmp, val, OVERLAP_TIMEOUT_MS_MIN, OVERLAP_TIMEOUT_MS_MAX, - isdn_data->overlap_timeout_ms); - } - } - else if (!strcasecmp(var, "idle_restart_interval")) { - int tmp = parse_timeout(val); - if (!tmp) { - isdn_data->idle_restart_timeout_ms = 0; /* disabled */ - } - else if ((isdn_data->idle_restart_timeout_ms = ftdm_clamp(tmp, IDLE_RESTART_TIMEOUT_MS_MIN, IDLE_RESTART_TIMEOUT_MS_MAX)) != tmp) { - ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ms ('%s') outside of range [%d:%d] ms, using %d ms instead\n", - var, tmp, val, IDLE_RESTART_TIMEOUT_MS_MIN, IDLE_RESTART_TIMEOUT_MS_MAX, - isdn_data->idle_restart_timeout_ms); - } - } - else if (!strcasecmp(var, "restart_timeout") || !strcasecmp(var, "t316")) { - int tmp = parse_timeout(val); - if (tmp <= 0) { - ftdm_log(FTDM_LOG_ERROR, "'%s' value '%s' is invalid\n", var, val); - goto error; - } - else if ((isdn_data->t316_timeout_ms = ftdm_clamp(tmp, T316_TIMEOUT_MS_MIN, T316_TIMEOUT_MS_MAX)) != tmp) { - ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ms ('%s') outside of range [%d:%d] ms, using %d ms instead\n", - var, tmp, val, T316_TIMEOUT_MS_MIN, T316_TIMEOUT_MS_MAX, - isdn_data->t316_timeout_ms); - } - } - else if (!strcasecmp(var, "restart_attempts") || !strcasecmp(var, "t316_limit")) { - int tmp = atoi(val); - if (tmp <= 0) { - ftdm_log(FTDM_LOG_ERROR, "'%s' value '%s' is invalid\n", var, val); - goto error; - } - else if ((isdn_data->t316_max_attempts = ftdm_clamp(tmp, T316_ATTEMPT_LIMIT_MIN, T316_ATTEMPT_LIMIT_MAX)) != tmp) { - ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ('%s') outside of range [%d:%d], using %d instead\n", - var, tmp, val, T316_ATTEMPT_LIMIT_MIN, T316_ATTEMPT_LIMIT_MAX, - isdn_data->t316_max_attempts); - } - } - else if (!strcasecmp(var, "debug")) { - if (parse_debug(val, &isdn_data->debug_mask) == -1) { - ftdm_log(FTDM_LOG_ERROR, "Invalid debug flag, ignoring parameter\n"); - isdn_data->debug_mask = 0; - } - } - else if (!strcasecmp(var, "service_message_support")) { - if (ftdm_true(val)) { - isdn_data->service_message_support = 1; - } - } - else if (!strcasecmp(var, "local-number") || !strcasecmp(var, "msn")) { - if (msn_filter_add(isdn_data, val) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Invalid MSN/DDI(s) '%s' specified\n", val); - goto error; - } - } - else { - ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s', aborting configuration\n", var); - goto error; - } - } - - /* Check if modes match and log a message if they do not. Just to be on the safe side. */ - if (isdn_data->mode == PRI_CPE && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) { - ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for TE/CPE/USER mode, while port is running in NT/NET mode. You may want to check your 'trunk_mode' settings.\n", - ftdm_span_get_name(span)); - } - else if (isdn_data->mode == PRI_NETWORK && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_CPE) { - ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for NT/NET mode, while port is running in TE/CPE/USER mode. You may want to check your 'trunk_mode' settings.\n", - ftdm_span_get_name(span)); - } - - span->start = ftdm_libpri_start; - span->stop = ftdm_libpri_stop; - span->signal_cb = sig_cb; - - span->signal_data = isdn_data; - span->signal_type = FTDM_SIGTYPE_ISDN; - span->outgoing_call = isdn_outgoing_call; - - span->state_map = &isdn_state_map; - span->state_processor = state_advance; - - span->get_channel_sig_status = isdn_get_channel_sig_status; - span->get_span_sig_status = isdn_get_span_sig_status; - - /* move calls to PROCEED state when they hit dialplan (ROUTING state in FreeSWITCH) */ - ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE); - - if ((isdn_data->opts & FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL)) { - span->channel_request = isdn_channel_request; - ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID); - } - - /* Allocate per-channel private data */ - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - - if (!chan) - continue; - - if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { - ftdm_libpri_b_chan_t *priv = NULL; - - priv = calloc(1, sizeof(*priv)); - if (!priv) { - ftdm_log_chan_msg(chan, FTDM_LOG_CRIT, "Failed to allocate per-channel private data\n"); - goto error; - } - priv->channel = chan; - chan->call_data = priv; - } - } - return FTDM_SUCCESS; -error: - /* TODO: free per-channel private data */ - msn_filter_destroy(isdn_data); - ftdm_safe_free(isdn_data); - return FTDM_FAIL; -} - -/** - * \brief FreeTDM libpri signaling and IO module definition - */ -ftdm_module_t ftdm_module = { - "libpri", - ftdm_libpri_io_init, - ftdm_libpri_unload, - ftdm_libpri_init, - NULL, - NULL, - ftdm_libpri_configure_span -}; - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h deleted file mode 100644 index 8ace29693b..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2009-2012, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef FTMOD_LIBPRI_H -#define FTMOD_LIBPRI_H -#include "freetdm.h" -#include "lpwrap_pri.h" - -/* T302 Overlap receiving inter-digit timeout */ -#define OVERLAP_TIMEOUT_MS_DEFAULT 5000 /* 5 sec */ -#define OVERLAP_TIMEOUT_MS_MIN 3000 /* 3 sec */ -#define OVERLAP_TIMEOUT_MS_MAX 30000 /* 30 sec */ - -/* NT-mode idle b-channel restart timer */ -#define IDLE_RESTART_TIMEOUT_MS_DEFAULT 0 /* disabled */ -#define IDLE_RESTART_TIMEOUT_MS_MIN 10000 /* 10 sec */ -#define IDLE_RESTART_TIMEOUT_MS_MAX 86400000 /* 1 day */ - -/* T316 RESTART ACK wait timer */ -#define T316_TIMEOUT_MS_DEFAULT 30000 /* 30 sec */ -#define T316_TIMEOUT_MS_MIN 10000 /* 10 sec */ -#define T316_TIMEOUT_MS_MAX 300000 /* 5 min */ - -/* T316 restart attempts until channel is suspended */ -#define T316_ATTEMPT_LIMIT_DEFAULT 3 -#define T316_ATTEMPT_LIMIT_MIN 1 -#define T316_ATTEMPT_LIMIT_MAX 10 - - -typedef enum { - SERVICE_CHANGE_STATUS_INSERVICE = 0, - SERVICE_CHANGE_STATUS_MAINTENANCE, - SERVICE_CHANGE_STATUS_OUTOFSERVICE -} service_change_status_t; - -typedef enum { - FTMOD_LIBPRI_OPT_NONE = 0, - FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL = (1 << 0), - FTMOD_LIBPRI_OPT_OMIT_DISPLAY_IE = (1 << 1), - FTMOD_LIBPRI_OPT_OMIT_REDIRECTING_NUMBER_IE = (1 << 2), - FTMOD_LIBPRI_OPT_FACILITY_AOC = (1 << 3), - - FTMOD_LIBPRI_OPT_MAX = (1 << 4) -} ftdm_isdn_opts_t; - -typedef enum { - FTMOD_LIBPRI_RUNNING = (1 << 0) -} ftdm_isdn_flag_t; - -typedef enum { - FTMOD_LIBPRI_OVERLAP_NONE = 0, - FTMOD_LIBPRI_OVERLAP_RECEIVE = (1 << 0), - FTMOD_LIBPRI_OVERLAP_SEND = (1 << 1) -#define FTMOD_LIBPRI_OVERLAP_BOTH (FTMOD_LIBPRI_OVERLAP_RECEIVE | FTMOD_LIBPRI_OVERLAP_SEND) -} ftdm_isdn_overlap_t; - -struct ftdm_libpri_data { - ftdm_channel_t *dchan; - ftdm_isdn_opts_t opts; - uint32_t flags; - uint32_t debug_mask; - - int mode; - int dialect; - int overlap; /*!< Overlap dial flags */ - int overlap_timeout_ms; /*!< Overlap dial timeout */ - int idle_restart_timeout_ms; /*!< NT-mode idle b-channel restart */ - int t316_timeout_ms; /*!< T316 RESTART ACK timeout */ - int t316_max_attempts; /*!< T316 timeout limit */ - unsigned int layer1; - unsigned int ton; - unsigned int service_message_support; - - lpwrap_pri_t spri; - - /* MSN filter */ - ftdm_hash_t *msn_hash; - ftdm_mutex_t *msn_mutex; - - /* NT-mode idle restart timer */ - struct lpwrap_timer t3xx; -}; - -typedef struct ftdm_libpri_data ftdm_libpri_data_t; - - -/* - * b-channel flags - */ -enum { - FTDM_LIBPRI_B_NONE = 0, - FTDM_LIBPRI_B_REMOTE_RESTART = (1 << 0), /*!< Remote triggered channel restart */ -}; - -/** - * Per-b-channel private data - */ -struct ftdm_libpri_b_chan { - struct lpwrap_timer t302; /*!< T302 overlap receive timer */ - struct lpwrap_timer t316; /*!< T316 restart ack timer */ - ftdm_channel_t *channel; /*!< back-pointer to b-channel */ - q931_call *call; /*!< libpri opaque call handle */ - uint32_t flags; /*!< channel flags */ - uint32_t t316_timeout_cnt; /*!< T316 timeout counter */ - int peerhangup; /*!< hangup requested from libpri (RELEASE/RELEASE_ACK/DL_RELEASE/TIMERS EXPIRY) */ -}; - -typedef struct ftdm_libpri_b_chan ftdm_libpri_b_chan_t; - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c deleted file mode 100644 index a59baccbe5..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright (c) 2009-2012, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//#define IODEBUG - -#include "private/ftdm_core.h" -#include "lpwrap_pri.h" - -static struct lpwrap_pri_event_list LPWRAP_PRI_EVENT_LIST[LPWRAP_PRI_EVENT_MAX] = { - {0, LPWRAP_PRI_EVENT_ANY, "ANY"}, - {1, LPWRAP_PRI_EVENT_DCHAN_UP, "DCHAN_UP"}, - {2, LPWRAP_PRI_EVENT_DCHAN_DOWN, "DCHAN_DOWN"}, - {3, LPWRAP_PRI_EVENT_RESTART, "RESTART"}, - {4, LPWRAP_PRI_EVENT_CONFIG_ERR, "CONFIG_ERR"}, - {5, LPWRAP_PRI_EVENT_RING, "RING"}, - {6, LPWRAP_PRI_EVENT_HANGUP, "HANGUP"}, - {7, LPWRAP_PRI_EVENT_RINGING, "RINGING"}, - {8, LPWRAP_PRI_EVENT_ANSWER, "ANSWER"}, - {9, LPWRAP_PRI_EVENT_HANGUP_ACK, "HANGUP_ACK"}, - {10, LPWRAP_PRI_EVENT_RESTART_ACK, "RESTART_ACK"}, - {11, LPWRAP_PRI_EVENT_FACILITY, "FACILITY"}, - {12, LPWRAP_PRI_EVENT_INFO_RECEIVED, "INFO_RECEIVED"}, - {13, LPWRAP_PRI_EVENT_PROCEEDING, "PROCEEDING"}, - {14, LPWRAP_PRI_EVENT_SETUP_ACK, "SETUP_ACK"}, - {15, LPWRAP_PRI_EVENT_HANGUP_REQ, "HANGUP_REQ"}, - {16, LPWRAP_PRI_EVENT_NOTIFY, "NOTIFY"}, - {17, LPWRAP_PRI_EVENT_PROGRESS, "PROGRESS"}, - {18, LPWRAP_PRI_EVENT_KEYPAD_DIGIT, "KEYPAD_DIGIT"}, - {19, LPWRAP_PRI_EVENT_IO_FAIL, "IO_FAIL"}, -}; - -const char *lpwrap_pri_event_str(lpwrap_pri_event_t event_id) -{ - if (event_id >= LPWRAP_PRI_EVENT_MAX) - return ""; - - return LPWRAP_PRI_EVENT_LIST[event_id].name; -} - -static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen) -{ - struct lpwrap_pri *spri = (struct lpwrap_pri *) pri_get_userdata(pri); - ftdm_size_t len = buflen; - ftdm_status_t zst; - int res; - - if ((zst = ftdm_channel_read(spri->dchan, buf, &len)) != FTDM_SUCCESS) { - if (zst == FTDM_FAIL) { - ftdm_log(FTDM_LOG_CRIT, "span %d D-READ FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error); - spri->errs++; - } else { - ftdm_log(FTDM_LOG_CRIT, "span %d D-READ TIMEOUT\n", spri->span->span_id); - } - /* we cannot return -1, libpri seems to expect values >= 0 */ - return 0; - } - spri->errs = 0; - res = (int)len; - - if (res > 0) { - memset(&((unsigned char*)buf)[res], 0, 2); - res += 2; -#ifdef IODEBUG - { - char bb[2048] = { 0 }; - - print_hex_bytes(buf, res - 2, bb, sizeof(bb)); - ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2); - } -#endif - } - return res; -} - -static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen) -{ - struct lpwrap_pri *spri = (struct lpwrap_pri *) pri_get_userdata(pri); - ftdm_size_t len = buflen - 2; - - if (ftdm_channel_write(spri->dchan, buf, buflen, &len) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "span %d D-WRITE FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error); - /* we cannot return -1, libpri seems to expect values >= 0 */ - return 0; - } - -#ifdef IODEBUG - { - char bb[2048] = { 0 }; - - print_hex_bytes(buf, buflen - 2, bb, sizeof(bb)); - ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n", (int)buflen - 2); - } -#endif - return (int)buflen; -} - - -/* - * Unified init function for BRI + PRI libpri spans - */ -int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int debug) -{ - int ret = -1; - - memset(spri, 0, sizeof(struct lpwrap_pri)); - spri->dchan = dchan; - spri->span = span; - - if (!spri->dchan) { - ftdm_log(FTDM_LOG_ERROR, "No D-Channel available, unable to create BRI/PRI\n"); - return ret; - } - - if (ftdm_mutex_create(&spri->timer_mutex) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to create timer list mutex\n"); - return ret; - } - - switch (ftdm_span_get_trunk_type(span)) { - case FTDM_TRUNK_E1: - case FTDM_TRUNK_J1: - case FTDM_TRUNK_T1: - spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri); - break; -#ifdef HAVE_LIBPRI_BRI - case FTDM_TRUNK_BRI: - spri->pri = pri_new_bri_cb(spri->dchan->sockfd, 1, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri); - break; - case FTDM_TRUNK_BRI_PTMP: - spri->pri = pri_new_bri_cb(spri->dchan->sockfd, 0, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri); - break; -#endif - default: - ftdm_log(FTDM_LOG_CRIT, "Invalid/unsupported trunk type '%s'\n", - ftdm_span_get_trunk_type_str(span)); - ftdm_mutex_destroy(&spri->timer_mutex); - return ret; - } - - if (spri->pri) { - pri_set_debug(spri->pri, debug); -#ifdef HAVE_LIBPRI_BRI - /* "follow Q.931 Section 5.3.2 call hangup better" */ - pri_hangup_fix_enable(spri->pri, 1); -#endif -#ifdef HAVE_LIBPRI_AOC - pri_aoc_events_enable(spri->pri, 1); -#endif - ret = 0; - } else { - ftdm_log(FTDM_LOG_CRIT, "Unable to create BRI/PRI\n"); - ftdm_mutex_destroy(&spri->timer_mutex); - } - return ret; -} - - -#define timeval_to_ms(x) \ - (ftdm_time_t)(((x)->tv_sec * 1000) + ((x)->tv_usec / 1000)) - -int lpwrap_start_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer, const uint32_t timeout_ms, timeout_handler callback) -{ - struct lpwrap_timer **prev, *cur; - - if (!spri || !timer || timer->timeout) - return -1; - - ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "-- Starting timer %p with timeout %u ms\n", - timer, timeout_ms); - - timer->timeout = ftdm_current_time_in_ms() + timeout_ms; - timer->callback = callback; - timer->next = NULL; - - ftdm_mutex_lock(spri->timer_mutex); - - for (prev = &spri->timer_list, cur = spri->timer_list; cur; prev = &(*prev)->next, cur = cur->next) { - if (cur->timeout > timer->timeout) { - *prev = timer; - timer->next = cur; - break; - } - } - if (!cur) { - *prev = timer; - } - - ftdm_mutex_unlock(spri->timer_mutex); - return 0; -} - -int lpwrap_stop_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer) -{ - struct lpwrap_timer **prev, *cur; - - if (!spri || !timer) - return -1; - - if (!timer->timeout) - return 0; - - ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "-- Stopping timer %p\n", timer); - - ftdm_mutex_lock(spri->timer_mutex); - - for (prev = &spri->timer_list, cur = spri->timer_list; cur; prev = &(*prev)->next, cur = cur->next) { - if (cur == timer) { - *prev = cur->next; - break; - } - } - - ftdm_mutex_unlock(spri->timer_mutex); - - if (!cur) { - ftdm_log_chan(spri->dchan, FTDM_LOG_WARNING, "-- Timer %p not found in list\n", timer); - } - - timer->next = NULL; - timer->timeout = 0; - timer->callback = NULL; - return 0; -} - -static struct lpwrap_timer *lpwrap_timer_next(struct lpwrap_pri *spri) -{ - return spri ? spri->timer_list : NULL; -} - -static int lpwrap_run_expired(struct lpwrap_pri *spri, ftdm_time_t now_ms) -{ - struct lpwrap_timer *expired_list = NULL; - struct lpwrap_timer **prev, *cur; - - if (!spri || !spri->timer_list) - return 0; - - ftdm_mutex_lock(spri->timer_mutex); - - /* Move all timers to expired list */ - expired_list = spri->timer_list; - - for (prev = &expired_list, cur = expired_list; cur; prev = &(*prev)->next, cur = cur->next) { - if (cur->timeout > now_ms) { - *prev = NULL; - break; - } - } - /* Move non-expired timer to front of timer_list (or clear list if there are none) */ - spri->timer_list = cur; - - ftdm_mutex_unlock(spri->timer_mutex); - - /* fire callbacks */ - while ((cur = expired_list)) { - timeout_handler handler = cur->callback; - expired_list = cur->next; - - /* Stop timer */ - cur->next = NULL; - cur->timeout = 0; - cur->callback = NULL; - - if (handler) - handler(spri, cur); - } - return 0; -} - - -#define LPWRAP_MAX_TIMEOUT_MS 100 -#define LPWRAP_MAX_ERRORS 2 - -int lpwrap_run_pri_once(struct lpwrap_pri *spri) -{ - struct timeval *next = NULL; - struct lpwrap_timer *timer = NULL; - pri_event *event = NULL; - ftdm_wait_flag_t flags; - ftdm_time_t now_ms, next_ms, timeout_ms, tmp_ms; - int ret; - - if (spri->on_loop) { - if ((ret = spri->on_loop(spri)) < 0) - return FTDM_FAIL; - } - - /* Default timeout when no scheduled events are pending */ - timeout_ms = LPWRAP_MAX_TIMEOUT_MS; - next_ms = 0; - now_ms = ftdm_current_time_in_ms(); - - /* - * Get the next scheduled timer from libpri to set the maximum timeout, - * but limit it to MAX_TIMEOUT_MS (100ms). - */ - if ((next = pri_schedule_next(spri->pri))) { - next_ms = timeval_to_ms(next); - if (now_ms >= next_ms) { - /* Already late, handle timeout */ - timeout_ms = 0; - } else { - /* Calculate new timeout and limit it to MAX_TIMEOUT_MS miliseconds */ - tmp_ms = ftdm_min(next_ms - now_ms, LPWRAP_MAX_TIMEOUT_MS); - timeout_ms = ftdm_min(timeout_ms, tmp_ms); - } - } - - /* - * Next lpwrap_timer timeout - */ - if ((timer = lpwrap_timer_next(spri))) { - if (now_ms >= timer->timeout) { - /* Already late, handle timeout */ - timeout_ms = 0; - } else { - /* Calculate new timeout and limit it to MAX_TIMEOUT_MS miliseconds */ - tmp_ms = ftdm_min(timer->timeout - now_ms, LPWRAP_MAX_TIMEOUT_MS); - timeout_ms = ftdm_min(timeout_ms, tmp_ms); - } - } - - /* */ - if (timeout_ms > 0) { - flags = FTDM_READ | FTDM_EVENTS; - ret = ftdm_channel_wait(spri->dchan, &flags, timeout_ms); - - if (spri->flags & LPWRAP_PRI_ABORT) - return FTDM_SUCCESS; - - if (ret == FTDM_TIMEOUT) { - now_ms = ftdm_current_time_in_ms(); - - if (next) { - if (next_ms < now_ms) { - ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "pri timer %d ms late\n", - (int)(now_ms - next_ms)); - } - event = pri_schedule_run(spri->pri); - } - if (timer) { - if (timer->timeout < now_ms) { - ftdm_log_chan(spri->dchan, FTDM_LOG_DEBUG, "lpwrap timer %d ms late\n", - (int)(now_ms - timer->timeout)); - } - lpwrap_run_expired(spri, now_ms); - } - } else if (flags & (FTDM_READ | FTDM_EVENTS)) { - event = pri_check_event(spri->pri); - } - } else { - /* - * Scheduled event has already expired, handle it immediately - */ - if (next) { - event = pri_schedule_run(spri->pri); - } - if (timer) { - lpwrap_run_expired(spri, now_ms); - } - } - - if (spri->flags & LPWRAP_PRI_ABORT) - return FTDM_SUCCESS; - - if (event) { - event_handler handler; - - /* 0 is catchall event handler */ - if (event->e < 0 || event->e >= LPWRAP_PRI_EVENT_MAX) { - handler = spri->eventmap[0]; - } else if (spri->eventmap[event->e]) { - handler = spri->eventmap[event->e]; - } else { - handler = spri->eventmap[0]; - } - - if (handler) { - handler(spri, event->e, event); - } else { - ftdm_log(FTDM_LOG_CRIT, "No event handler found for event %d.\n", event->e); - } - } - - return FTDM_SUCCESS; -} - -int lpwrap_run_pri(struct lpwrap_pri *spri) -{ - int ret = 0; - - while (!(spri->flags & LPWRAP_PRI_ABORT)) { - ret = lpwrap_run_pri_once(spri); - if (ret) { - ftdm_log(FTDM_LOG_ERROR, "Error = %d, [%s]\n", - ret, strerror(errno)); - spri->errs++; - } else { - spri->errs = 0; - } - if (!ftdm_running()) - break; - if (spri->errs >= LPWRAP_MAX_ERRORS) { - ftdm_log(FTDM_LOG_CRIT, "Too many errors on span, restarting\n"); - spri->errs = 0; - break; - } - } - return ret; -} - -int lpwrap_stop_pri(struct lpwrap_pri *spri) -{ - spri->flags |= LPWRAP_PRI_ABORT; - return FTDM_SUCCESS; -} - -int lpwrap_destroy_pri(struct lpwrap_pri *spri) -{ - if (spri->timer_mutex) - ftdm_mutex_destroy(&spri->timer_mutex); - return FTDM_SUCCESS; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.h b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.h deleted file mode 100644 index 89708da270..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2009-2012, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _LPWRAP_PRI_H -#define _LPWRAP_PRI_H -#include -#include - - -#define LPWRAP_MAX_CHAN_PER_SPAN 32 - -typedef enum { - LPWRAP_PRI_EVENT_ANY = 0, - LPWRAP_PRI_EVENT_DCHAN_UP = PRI_EVENT_DCHAN_UP, - LPWRAP_PRI_EVENT_DCHAN_DOWN = PRI_EVENT_DCHAN_DOWN, - LPWRAP_PRI_EVENT_RESTART = PRI_EVENT_RESTART, - LPWRAP_PRI_EVENT_CONFIG_ERR = PRI_EVENT_CONFIG_ERR, - LPWRAP_PRI_EVENT_RING = PRI_EVENT_RING, - LPWRAP_PRI_EVENT_HANGUP = PRI_EVENT_HANGUP, - LPWRAP_PRI_EVENT_RINGING = PRI_EVENT_RINGING, - LPWRAP_PRI_EVENT_ANSWER = PRI_EVENT_ANSWER, - LPWRAP_PRI_EVENT_HANGUP_ACK = PRI_EVENT_HANGUP_ACK, - LPWRAP_PRI_EVENT_RESTART_ACK = PRI_EVENT_RESTART_ACK, -#ifdef PRI_EVENT_FACILITY - LPWRAP_PRI_EVENT_FACILITY = PRI_EVENT_FACILITY, -#else - LPWRAP_PRI_EVENT_FACILITY = PRI_EVENT_FACNAME, -#endif - LPWRAP_PRI_EVENT_INFO_RECEIVED = PRI_EVENT_INFO_RECEIVED, - LPWRAP_PRI_EVENT_PROCEEDING = PRI_EVENT_PROCEEDING, - LPWRAP_PRI_EVENT_SETUP_ACK = PRI_EVENT_SETUP_ACK, - LPWRAP_PRI_EVENT_HANGUP_REQ = PRI_EVENT_HANGUP_REQ, - LPWRAP_PRI_EVENT_NOTIFY = PRI_EVENT_NOTIFY, - LPWRAP_PRI_EVENT_PROGRESS = PRI_EVENT_PROGRESS, - LPWRAP_PRI_EVENT_KEYPAD_DIGIT = PRI_EVENT_KEYPAD_DIGIT, - LPWRAP_PRI_EVENT_IO_FAIL = 19, - - /* don't touch */ - LPWRAP_PRI_EVENT_MAX -} lpwrap_pri_event_t; - -typedef enum { - LPWRAP_PRI_NETWORK = PRI_NETWORK, - LPWRAP_PRI_CPE = PRI_CPE -} lpwrap_pri_node_t; - -typedef enum { - LPWRAP_PRI_SWITCH_UNKNOWN = PRI_SWITCH_UNKNOWN, - LPWRAP_PRI_SWITCH_NI2 = PRI_SWITCH_NI2, - LPWRAP_PRI_SWITCH_DMS100 = PRI_SWITCH_DMS100, - LPWRAP_PRI_SWITCH_LUCENT5E = PRI_SWITCH_LUCENT5E, - LPWRAP_PRI_SWITCH_ATT4ESS = PRI_SWITCH_ATT4ESS, - LPWRAP_PRI_SWITCH_EUROISDN_E1 = PRI_SWITCH_EUROISDN_E1, - LPWRAP_PRI_SWITCH_EUROISDN_T1 = PRI_SWITCH_EUROISDN_T1, - LPWRAP_PRI_SWITCH_NI1 = PRI_SWITCH_NI1, - LPWRAP_PRI_SWITCH_GR303_EOC = PRI_SWITCH_GR303_EOC, - LPWRAP_PRI_SWITCH_GR303_TMC = PRI_SWITCH_GR303_TMC, - LPWRAP_PRI_SWITCH_QSIG = PRI_SWITCH_QSIG, - - /* don't touch */ - LPWRAP_PRI_SWITCH_MAX -} lpwrap_pri_switch_t; - -typedef enum { - LPWRAP_PRI_READY = (1 << 0), - LPWRAP_PRI_ABORT = (1 << 1) -} lpwrap_pri_flag_t; - -struct lpwrap_pri; -struct lpwrap_timer; - -typedef int (*timeout_handler)(struct lpwrap_pri *, struct lpwrap_timer *); -typedef int (*event_handler)(struct lpwrap_pri *, lpwrap_pri_event_t, pri_event *); -typedef int (*loop_handler)(struct lpwrap_pri *); - -struct lpwrap_pri { - struct pri *pri; - ftdm_span_t *span; - ftdm_channel_t *dchan; - unsigned int flags; - void *private_info; - event_handler eventmap[LPWRAP_PRI_EVENT_MAX]; - loop_handler on_loop; - int errs; - struct lpwrap_timer *timer_list; - ftdm_mutex_t *timer_mutex; -}; - -typedef struct lpwrap_pri lpwrap_pri_t; - -struct lpwrap_pri_event_list { - int event_id; - int pri_event; - const char *name; -}; - -struct lpwrap_timer { - struct lpwrap_timer *next; - ftdm_time_t timeout; - timeout_handler callback; -}; - -int lpwrap_start_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer, const uint32_t timeout_ms, timeout_handler callback); -int lpwrap_stop_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer); - -#define LPWRAP_MAP_PRI_EVENT(spri, event, func) spri.eventmap[event] = func; -const char *lpwrap_pri_event_str(lpwrap_pri_event_t event_id); - -int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *dchan, int swtype, int node, int debug); -int lpwrap_destroy_pri(struct lpwrap_pri *spri); -int lpwrap_run_pri_once(struct lpwrap_pri *spri); -int lpwrap_run_pri(struct lpwrap_pri *spri); -int lpwrap_stop_pri(struct lpwrap_pri *spri); -#endif diff --git a/libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c b/libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c deleted file mode 100644 index 4909595a0b..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c +++ /dev/null @@ -1,2837 +0,0 @@ -/** - * mISDN HW interface - * - * Copyright (c) 2011, Stefan Knoblich - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * NOTE: This is intended as a Layer 1 interface only, signaling - * is handled by other modules (e.g. ftmod_libpri or ftmod_isdn). - */ -/* - * TODO: - * - Use a fifo and PH_DATA_CNF for b-channel write polling (drop timerfd) - * - * - Disable L1 idle deactivation on BRI PTMP with IMGL1HOLD ioctl(? optional) - * - * - Add hfcsusb specific state + flag defines and try to do something useful with - * it in misdn_handle_mph_information_ind(). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* this is how it should have been... -#ifdef HAVE_FREETDM_FREETDM_H -#include -#else -#include -#endif -*/ -/* ... and this is how it is */ -#include - -#include - -/* - * mISDNcompat.h replaces these with references to an extern int, - * which is exported by libmisdn... unset them and use the official - * AF ID "34" - */ -#undef PF_ISDN -#undef AF_ISDN -#define AF_ISDN 34 -#define PF_ISDN AF_ISDN - -//#define MISDN_DEBUG_EVENTS -//#define MISDN_DEBUG_IO - -#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) - -typedef enum { - MISDN_CAPS_NONE = 0, - - /* D-Channel */ - MISDN_CAPS_PRI = (1 << 0), - MISDN_CAPS_BRI = (1 << 1), - MISDN_CAPS_UP0 = (1 << 2), - MISDN_CAPS_NT = (1 << 3), - MISDN_CAPS_TE = (1 << 4), - - /* B-Channel */ - MISDN_CAPS_RAW = (1 << 10), - MISDN_CAPS_HDLC = (1 << 11), -} misdn_capability_flags_t; - -#define MISDN_IS_BRI(x) (x & MISDN_CAPS_BRI) -#define MISDN_IS_PRI(x) (x & MISDN_CAPS_PRI) - -#define MISDN_IS_TE(x) (x & MISDN_CAPS_TE) -#define MISDN_IS_NT(x) (x & MISDN_CAPS_NT) - -#define MISDN_IS_RAW(x) (x & MISDN_CAPS_RAW) -#define MISDN_IS_HDLC(x) (x & MISDN_CAPS_HDLC) - -#define MISDN_MSG_DATA(x) ((void *)((unsigned char *)(x) + MISDN_HEADER_LEN)) - -const static struct { - const int id; - const char *name; -} misdn_event_types[] = { -#define MISDN_EVENT_TYPE(x) { x, #x } - MISDN_EVENT_TYPE(PH_DATA_REQ), - MISDN_EVENT_TYPE(PH_DATA_IND), - MISDN_EVENT_TYPE(PH_DATA_CNF), - MISDN_EVENT_TYPE(PH_DATA_E_IND), - MISDN_EVENT_TYPE(PH_CONTROL_REQ), - MISDN_EVENT_TYPE(PH_CONTROL_IND), - MISDN_EVENT_TYPE(PH_CONTROL_CNF), - MISDN_EVENT_TYPE(PH_ACTIVATE_REQ), - MISDN_EVENT_TYPE(PH_ACTIVATE_IND), - MISDN_EVENT_TYPE(PH_ACTIVATE_CNF), - MISDN_EVENT_TYPE(PH_DEACTIVATE_REQ), - MISDN_EVENT_TYPE(PH_DEACTIVATE_IND), - MISDN_EVENT_TYPE(PH_DEACTIVATE_CNF), - MISDN_EVENT_TYPE(MPH_ACTIVATE_REQ), - MISDN_EVENT_TYPE(MPH_ACTIVATE_IND), - MISDN_EVENT_TYPE(MPH_DEACTIVATE_REQ), - MISDN_EVENT_TYPE(MPH_DEACTIVATE_IND), - MISDN_EVENT_TYPE(MPH_INFORMATION_REQ), - MISDN_EVENT_TYPE(MPH_INFORMATION_IND), -#undef MISDN_EVENT_TYPE -}; - -static const char *misdn_event2str(const int event) -{ - int x; - - for (x = 0; x < ftdm_array_len(misdn_event_types); x++) { - if (event == misdn_event_types[x].id) - return misdn_event_types[x].name; - } - return "unknown"; -} - - -const static struct { - const int id; - const char *name; -} misdn_control_types[] = { -#define MISDN_CONTROL_TYPE(x) { x, #x } - MISDN_CONTROL_TYPE(DTMF_HFC_COEF), - MISDN_CONTROL_TYPE(DSP_CONF_JOIN), - MISDN_CONTROL_TYPE(DSP_CONF_SPLIT), - MISDN_CONTROL_TYPE(DSP_RECEIVE_OFF), - MISDN_CONTROL_TYPE(DSP_RECEIVE_ON), - MISDN_CONTROL_TYPE(DSP_ECHO_ON), - MISDN_CONTROL_TYPE(DSP_ECHO_OFF), - MISDN_CONTROL_TYPE(DSP_MIX_ON), - MISDN_CONTROL_TYPE(DSP_MIX_OFF), - MISDN_CONTROL_TYPE(DSP_DELAY), - MISDN_CONTROL_TYPE(DSP_JITTER), - MISDN_CONTROL_TYPE(DSP_TXDATA_ON), - MISDN_CONTROL_TYPE(DSP_TXDATA_OFF), - MISDN_CONTROL_TYPE(DSP_TX_DEJITTER), - MISDN_CONTROL_TYPE(DSP_TX_DEJ_OFF), - MISDN_CONTROL_TYPE(DSP_TONE_PATT_ON), - MISDN_CONTROL_TYPE(DSP_TONE_PATT_OFF), - MISDN_CONTROL_TYPE(DSP_VOL_CHANGE_TX), - MISDN_CONTROL_TYPE(DSP_VOL_CHANGE_RX), - MISDN_CONTROL_TYPE(DSP_BF_ENABLE_KEY), - MISDN_CONTROL_TYPE(DSP_BF_DISABLE), - MISDN_CONTROL_TYPE(DSP_BF_ACCEPT), - MISDN_CONTROL_TYPE(DSP_BF_REJECT), - MISDN_CONTROL_TYPE(DSP_PIPELINE_CFG), - MISDN_CONTROL_TYPE(HFC_VOL_CHANGE_TX), - MISDN_CONTROL_TYPE(HFC_VOL_CHANGE_RX), - MISDN_CONTROL_TYPE(HFC_SPL_LOOP_ON), - MISDN_CONTROL_TYPE(HFC_SPL_LOOP_OFF), -#undef MISDN_CONTROL_TYPE -}; - -static const char *misdn_control2str(const int ctrl) -{ - int x; - - for (x = 0; x < ftdm_array_len(misdn_control_types); x++) { - if (ctrl == misdn_control_types[x].id) - return misdn_control_types[x].name; - } - return "unknown"; -} - - -/*********************************************************************************** - * mISDN <-> FreeTDM audio conversion - ***********************************************************************************/ - -/* - * Code used to generate table values taken from - * Linux Call Router (LCR) http://www.linux-call-router.de/ - * - * chan_lcr.c:3488 ff., load_module() - */ -static const unsigned char conv_audio_tbl[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, -}; - -/* Convert ISDN_P_B_RAW audio data to/from a-/u-law */ -static inline void misdn_convert_audio_bits(char *buf, int buflen) -{ - int i; - - for (i = 0; i < buflen; i++) { - buf[i] = conv_audio_tbl[(unsigned char)buf[i]]; - } -} - - -/*********************************************************************************** - * mISDN <-> FreeTDM data structures - ***********************************************************************************/ - -typedef enum { - MISDN_CMD_NONE = 0, - MISDN_CMD_STOP, /*!< Stop the I/O thread */ -} misdn_cmd_t; - -struct misdn_command { - misdn_cmd_t type; -/* union { } cmd; */ /*!< Command-specific parameters */ -}; - -enum { - MISDN_SPAN_NONE = 0, - MISDN_SPAN_RUNNING = (1 << 0), - MISDN_SPAN_STOPPED = (1 << 1) -}; - -struct misdn_span_private { - int flags; - int running; - - int event_pipe_in; - int event_pipe_out; - - /* event conditional */ - pthread_mutex_t event_cond_mutex; - pthread_cond_t event_cond; - - /* start / stop feedback */ - pthread_mutex_t ctrl_cond_mutex; - pthread_cond_t ctrl_cond; -}; - -struct misdn_event_queue; - -struct misdn_chan_private { - /* */ - int debugfd; - int active; - - /* hw addr of channel */ - struct sockaddr_mISDN addr; - - /* audio tx pipe (= socketpair ends) */ - int tx_audio_pipe_in; - int tx_audio_pipe_out; - int rx_audio_pipe_in; - int rx_audio_pipe_out; - - /* counters */ - unsigned long tx_cnt; - unsigned long tx_ack_cnt; - unsigned long rx_cnt; - unsigned long slip_rx_cnt; - unsigned long slip_tx_cnt; - - unsigned long tx_pipe_wr_bytes; /*!< Number of bytes written into tx audio pipe */ - unsigned long tx_pipe_rd_bytes; /*!< Number of bytes read from tx audio pipe */ - unsigned long tx_miss_bytes; /*!< Number of bytes missing in short reads from tx audio pipe */ - unsigned long tx_lost_bytes; /*!< Number of bytes lost in short writes to the mISDN B-Channel */ - unsigned long tx_sent_bytes; /*!< Number of bytes successfully sent to the mISDN B-Channel */ - unsigned long tx_pipe_under_cnt; /*!< Number of tx audio pipe underflows */ - unsigned long tx_pipe_over_cnt; /*!< Number of tx audio pipe overflows */ - - struct misdn_event_queue *events; -}; - -#define ftdm_chan_io_private(x) ((x)->io_data) -#define ftdm_span_io_private(x) ((x)->io_data) - -static ftdm_status_t misdn_handle_incoming(ftdm_channel_t *ftdmchan, const char *rbuf, const int size); -static int misdn_handle_mph_information_ind(ftdm_channel_t *chan, const struct mISDNhead *hh, const void *data, const int data_len); - -static const char *ftdm_channel_get_type_str(const ftdm_channel_t *chan) -{ - return ftdm_chan_type2str(ftdm_channel_get_type(chan)); -} - -/*********************************************************************************** - * mISDN interface functions - ***********************************************************************************/ - -/* - * Event Queue - */ -#define MISDN_EVENTS_MAX 8 - -struct misdn_event { - int id; -}; - -struct misdn_event_queue { - int read_pos; - int write_pos; - pthread_mutex_t mutex; - - struct misdn_event events[MISDN_EVENTS_MAX]; -}; - -/** - * Initialize event queue - */ -static ftdm_status_t misdn_event_queue_create(struct misdn_event_queue **queue) -{ - struct misdn_event_queue *tmp = NULL; - - if (!queue) - return FTDM_FAIL; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return FTDM_FAIL; - - pthread_mutex_init(&tmp->mutex, NULL); - - *queue = tmp; - return FTDM_SUCCESS; -} - -/** - * Destroy event queue - */ -static ftdm_status_t misdn_event_queue_destroy(struct misdn_event_queue **queue) -{ - if (!queue || !*queue) - return FTDM_FAIL; - - pthread_mutex_destroy(&(*queue)->mutex); - ftdm_safe_free(*queue); - *queue = NULL; - - return FTDM_SUCCESS; -} - -static ftdm_status_t misdn_event_queue_reset(struct misdn_event_queue *queue) -{ - if (!queue) - return FTDM_FAIL; - pthread_mutex_lock(&queue->mutex); - - memset(queue->events, 0, sizeof(queue->events)); - queue->read_pos = queue->write_pos = 0; - - pthread_mutex_unlock(&queue->mutex); - return FTDM_SUCCESS; -} - -static ftdm_bool_t misdn_event_queue_has_data(const struct misdn_event_queue *queue) -{ - if (!queue) - return FTDM_FALSE; - - return (queue->read_pos == queue->write_pos) ? FTDM_FALSE : FTDM_TRUE; -} - -static struct misdn_event *misdn_event_queue_pop(struct misdn_event_queue *queue) -{ - struct misdn_event *evt = NULL; - int next_idx = 0; - - if (!queue) - return NULL; - - pthread_mutex_lock(&queue->mutex); - - next_idx = (queue->read_pos + 1) % MISDN_EVENTS_MAX; - - if (queue->read_pos == queue->write_pos) { -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN queue %p: empty\n", queue); -#endif - pthread_mutex_unlock(&queue->mutex); - return NULL; - } - -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN queue %p: read event (read_pos: %d, write_pos: %d, next_write_pos: %d)\n", - queue, queue->read_pos, queue->write_pos, next_idx); -#endif - /* update read pos */ - evt = &queue->events[queue->read_pos]; - queue->read_pos = next_idx; - - pthread_mutex_unlock(&queue->mutex); - return evt; -} - -static ftdm_status_t misdn_event_queue_push(struct misdn_event_queue *queue, struct misdn_event *evt) -{ - int next_idx = 0; - - if (!queue || !evt) - return FTDM_FAIL; - - pthread_mutex_lock(&queue->mutex); - - next_idx = (queue->write_pos + 1) % MISDN_EVENTS_MAX; - - if (next_idx == queue->read_pos) { -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN queue %p: full\n", queue); -#endif - pthread_mutex_unlock(&queue->mutex); - return FTDM_FAIL; - } - -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN queue %p: wrote event (read_pos: %d, write_pos: %d, next_write_pos: %d)\n", - queue, queue->read_pos, queue->write_pos, next_idx); -#endif - memcpy(&queue->events[queue->write_pos], evt, sizeof(*evt)); - queue->write_pos = next_idx; - - pthread_mutex_unlock(&queue->mutex); - return FTDM_SUCCESS; -} - -#if 0 /* unused for now */ -static void misdn_event_queue_print_info(const struct misdn_event_queue *queue) -{ - ftdm_log(FTDM_LOG_DEBUG, "Queue %p\n\tread idx: %d\n\twrite idx: %d\n", queue, - queue->read_pos, queue->write_pos); -} -#endif - -/*********************************************************************************** - * mISDN helper functions - ***********************************************************************************/ - -#define MISDN_PH_ACTIVATE_TIMEOUT_MS 10000 -#define MISDN_MPH_INFORMATION_TIMEOUT_MS 3000 - -static inline void ts_add_msec(struct timespec *a, int msec) -{ - a->tv_sec += (msec / 1000); - a->tv_nsec += (msec % 1000) * 1000000; - if (a->tv_nsec >= 1000000000) { - a->tv_sec++; - a->tv_nsec -= 1000000000; - } -} - -static inline int ts_sub_msec(struct timespec *a, struct timespec *b) -{ - int msec = 0; - msec += (a->tv_sec - b->tv_sec) * 1000; - msec += (a->tv_nsec - b->tv_nsec) / 1000000; - return msec; -} - -static inline int ts_after(struct timespec *a, struct timespec *b) -{ - if (a->tv_sec > b->tv_sec) return 1; - if (a->tv_sec == b->tv_sec && a->tv_nsec > b->tv_nsec) return 1; - return 0; -} - -static inline int ts_before(struct timespec *a, struct timespec *b) -{ - if (a->tv_sec < b->tv_sec) return 1; - if (a->tv_sec == b->tv_sec && a->tv_nsec < b->tv_nsec) return 1; - return 0; -} - -/* - * Asynchronous channel (de-)activation - */ -static ftdm_status_t _misdn_toggle_channel_nowait(ftdm_channel_t *chan, int activate) -{ - struct misdn_chan_private *priv = ftdm_chan_io_private(chan); - char buf[MAX_DATA_MEM] = { 0 }; - struct mISDNhead *hh = (struct mISDNhead *) buf; - int retval; - - /* NOTE: sending PH_DEACTIVATE_REQ to closed b-channels kills the d-channel (hfcsusb)... */ - if ((activate && priv->active) || (!activate && !priv->active)) - return FTDM_SUCCESS; - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN sending %s request\n", - (activate) ? "activation" : "deactivation"); - - /* prepare + send request primitive */ - hh->prim = (activate) ? PH_ACTIVATE_REQ : PH_DEACTIVATE_REQ; - hh->id = MISDN_ID_ANY; - - if ((retval = sendto(chan->sockfd, hh, sizeof(*hh), 0, NULL, 0)) < sizeof(*hh)) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to send activation request: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - -static ftdm_status_t misdn_activate_channel_nowait(ftdm_channel_t *chan) -{ - return _misdn_toggle_channel_nowait(chan, 1); -} - -static ftdm_status_t misdn_deactivate_channel_nowait(ftdm_channel_t *chan) -{ - return _misdn_toggle_channel_nowait(chan, 0); -} - -/* - * Synchronous channel (de-)activation - */ -static ftdm_status_t _misdn_toggle_channel(ftdm_channel_t *chan, int activate) -{ - struct misdn_chan_private *priv = ftdm_chan_io_private(chan); - char buf[MAX_DATA_MEM] = { 0 }; - struct mISDNhead *hh = (struct mISDNhead *) buf; - struct timespec abstimeout; - int req = 0, resp = 0, ms_left = MISDN_PH_ACTIVATE_TIMEOUT_MS; - int retval; - - /* NOTE: sending PH_DEACTIVATE_REQ to closed b-channels kills the d-channel (hfcsusb)... */ - if ((activate && priv->active) || (!activate && !priv->active)) - return FTDM_SUCCESS; - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN sending %s request\n", - (activate) ? "activation" : "deactivation"); - - /* prepare + send request primitive */ - req = (activate) ? PH_ACTIVATE_REQ : PH_DEACTIVATE_REQ; - hh->prim = req; - hh->id = MISDN_ID_ANY; - - if ((retval = sendto(chan->sockfd, hh, sizeof(*hh), 0, NULL, 0)) < sizeof(*hh)) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to send activation request: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - - clock_gettime(CLOCK_MONOTONIC, &abstimeout); - ts_add_msec(&abstimeout, ms_left); - - /* wait for answer */ - while (1) { - struct timespec now; - struct pollfd pfd; - - pfd.fd = chan->sockfd; - pfd.events = POLLIN | POLLPRI; - pfd.revents = 0; - - switch ((retval = poll(&pfd, 1, ms_left))) { - case 0: /* timeout */ - goto out; - case -1: /* error */ - if (!(retval == EAGAIN || retval == EINTR)) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN polling for activation confirmation failed: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - break; - default: /* read data */ - break; - } - - if (pfd.revents & (POLLIN | POLLPRI)) { - /* handle incoming message */ - if ((retval = recvfrom(chan->sockfd, buf, sizeof(buf), 0, NULL, NULL)) <= 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to receive possible answer for %s request: %s\n", - (activate) ? "activation" : "deactivation", strerror(errno)); - return FTDM_FAIL; - } -#ifdef MISDN_DEBUG_EVENTS - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN got event '%s (%#x)', id %#x, while waiting for %s confirmation on %c-channel\n", - misdn_event2str(hh->prim), hh->prim, hh->id, (activate) ? "activation" : "deactivation", - ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B ? 'B' : 'D'); -#endif - switch (hh->prim) { - case PH_ACTIVATE_IND: - case PH_ACTIVATE_CNF: - resp = hh->prim; - priv->active = 1; - if (activate) goto out; - break; - case PH_DEACTIVATE_CNF: - case PH_DEACTIVATE_IND: - resp = hh->prim; - priv->active = 0; - if (!activate) goto out; - break; - case PH_ACTIVATE_REQ: /* REQ echo, ignore */ - case PH_DEACTIVATE_REQ: - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN got '%s' echo while waiting for %s confirmation (id: %#x)\n", - misdn_event2str(hh->prim), (activate) ? "activation" : "deactivation", hh->id); - break; - case MPH_INFORMATION_IND: - misdn_handle_mph_information_ind(chan, hh, MISDN_MSG_DATA(buf), retval - MISDN_HEADER_LEN); - break; - case PH_DATA_IND: /* ignore */ - case PH_DATA_CNF: /* ignore */ - break; - default: /* other messages, ignore */ - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN ignoring event '%s (%#x)', id %#x, while waiting for %s confirmation\n", - misdn_event2str(hh->prim), hh->prim, hh->id, (activate) ? "activation" : "deactivation"); - break; - } - } - - /* check timeout */ - clock_gettime(CLOCK_MONOTONIC, &now); - - if (ts_after(&now, &abstimeout) || (ms_left = ts_sub_msec(&abstimeout, &now)) <= 0) - goto out; - } -out: - if (resp == 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN timeout waiting for %s confirmation\n", - (activate) ? "activation" : "deactivation"); - return FTDM_TIMEOUT; - } - if ((req == PH_ACTIVATE_REQ && !(resp == PH_ACTIVATE_CNF || resp == PH_ACTIVATE_IND)) || - (req == PH_DEACTIVATE_REQ && !(resp == PH_DEACTIVATE_CNF || resp == PH_DEACTIVATE_IND))) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN received '%s' while waiting for %s\n", - misdn_event2str(resp), (activate) ? "activation" : "deactivation"); - return FTDM_FAIL; - } - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN received %s confirmation\n", - (activate) ? "activation" : "deactivation"); - return FTDM_SUCCESS; -} - -static ftdm_status_t misdn_activate_channel(ftdm_channel_t *chan) -{ - return _misdn_toggle_channel(chan, 1); -} - -static ftdm_status_t misdn_deactivate_channel(ftdm_channel_t *chan) -{ - return _misdn_toggle_channel(chan, 0); -} - - -#if 0 /* unused for now */ -static ftdm_status_t misdn_get_ph_info(ftdm_channel_t *chan, struct ph_info *info) -{ - char buf[MAX_DATA_MEM] = { 0 }; - struct mISDNhead *hh; - struct timespec abstimeout; - int req = 0, resp = 0, ms_left = MISDN_MPH_INFORMATION_TIMEOUT_MS; - int retval; - - /* prepare + send request primitive */ - req = MPH_INFORMATION_REQ; - hh = (struct mISDNhead *)buf; - hh->prim = req; - hh->id = MISDN_ID_ANY; - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN sending %s request\n", - misdn_event2str(req)); - - if ((retval = sendto(chan->sockfd, &hh, sizeof(hh), 0, NULL, 0)) < sizeof(hh)) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to send %s request: %s\n", - misdn_event2str(req), strerror(errno)); - return FTDM_FAIL; - } - - clock_gettime(CLOCK_MONOTONIC, &abstimeout); - ts_add_msec(&abstimeout, ms_left); - - /* wait for answer */ - while (1) { - struct timespec now; - struct pollfd pfd; - - pfd.fd = chan->sockfd; - pfd.events = POLLIN /* | POLLPRI */; - pfd.revents = 0; - - switch ((retval = poll(&pfd, 1, ms_left))) { - case 0: /* timeout */ - goto out; - case -1: /* error */ - if (!(retval == EAGAIN || retval == EINTR)) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN polling for %s answer failed: %s\n", - misdn_event2str(req), strerror(errno)); - return FTDM_FAIL; - } - break; - default: /* read data */ - break; - } - - if (pfd.revents & (POLLIN | POLLPRI)) { - /* handle incoming message */ - if ((retval = recvfrom(chan->sockfd, buf, sizeof(buf), 0, NULL, NULL)) <= 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to receive possible answer for %s request: %s\n", - misdn_event2str(req), strerror(errno)); - return FTDM_FAIL; - } -#ifdef MISDN_DEBUG_EVENTS - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN got event '%s' while waiting for %s answer\n", - misdn_event2str(hh->prim), misdn_event2str(req)); -#endif - switch (hh->prim) { - case MPH_INFORMATION_IND: /* success */ - if (retval < MISDN_HEADER_LEN + sizeof(*info)) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN answer for %s is too short\n", - misdn_event2str(req)); - return FTDM_FAIL; - } - resp = hh->prim; - /* TODO */ - goto out; - case MPH_INFORMATION_REQ: /* REQ echo, ignore */ - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN got '%s' echo while waiting for %s answer\n", - misdn_event2str(hh->prim), misdn_event2str(req)); - break; - default: /* other messages, ignore */ - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN ignoring event '%s' while waiting for %s answer\n", - misdn_event2str(hh->prim), misdn_event2str(req)); - break; - } - } - - /* check timeout */ - clock_gettime(CLOCK_MONOTONIC, &now); - - if (ts_after(&now, &abstimeout) || (ms_left = ts_sub_msec(&abstimeout, &now)) <= 0) - goto out; - } -out: - if (resp == 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN timeout waiting for %s answer\n", - misdn_event2str(req)); - return FTDM_TIMEOUT; - } - - return FTDM_SUCCESS; -} -#endif - -static int misdn_handle_ph_control_ind(ftdm_channel_t *chan, const struct mISDNhead *hh, const void *data, const int data_len) -{ - ftdm_unused_arg(data); - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, - "PH_CONTROL_IND:\n" - "\tMessage:\t%s (%#x)\n" - "\tPayload:\t%d\n", - misdn_control2str(hh->id), hh->id, data_len); - - switch (hh->id) { - case DTMF_HFC_COEF: - break; - default: - break; - } - - return FTDM_SUCCESS; -} - -/* - * TE/NT state names - * taken from linux-3.2.1/drivers/isdn/hardware/mISDN/hfcsusb.h - */ -static const char *misdn_layer1_te_states[] = { - "TE F0 - Reset", - "TE F1 - Reset", - "TE F2 - Sensing", - "TE F3 - Deactivated", - "TE F4 - Awaiting signal", - "TE F5 - Identifying input", - "TE F6 - Synchronized", - "TE F7 - Activated", - "TE F8 - Lost framing", -}; - -static const char *misdn_layer1_nt_states[] = { - "NT G0 - Reset", - "NT G1 - Deactive", - "NT G2 - Pending activation", - "NT G3 - Active", - "NT G4 - Pending deactivation", -}; - -static const char *misdn_hw_state_name(const int proto, const int id) -{ - if (IS_ISDN_P_TE(proto)) { - if (id < 0 || id >= ftdm_array_len(misdn_layer1_te_states)) - return NULL; - return misdn_layer1_te_states[id]; - } - else if (IS_ISDN_P_NT(proto)) { - if (id < 0 || id >= ftdm_array_len(misdn_layer1_nt_states)) - return NULL; - return misdn_layer1_nt_states[id]; - } - return NULL; -} - - -static const struct misdn_hw_flag { - const unsigned int flag; - const char *name; -} misdn_hw_flags[] = { -#define MISDN_HW_FLAG(v,n) { v, #n } - MISDN_HW_FLAG(0, FLG_TX_BUSY), - MISDN_HW_FLAG(1, FLG_TX_NEXT), - MISDN_HW_FLAG(2, FLG_L1_BUSY), - MISDN_HW_FLAG(3, FLG_L2_ACTIVATED), - MISDN_HW_FLAG(5, FLG_OPEN), - MISDN_HW_FLAG(6, FLG_ACTIVE), - MISDN_HW_FLAG(7, FLG_BUSY_TIMER), - MISDN_HW_FLAG(8, FLG_DCHANNEL), - MISDN_HW_FLAG(9, FLG_BCHANNEL), - MISDN_HW_FLAG(10, FLG_ECHANNEL), - MISDN_HW_FLAG(12, FLG_TRANSPARENT), - MISDN_HW_FLAG(13, FLG_HDLC), - MISDN_HW_FLAG(14, FLG_L2DATA), - MISDN_HW_FLAG(15, FLG_ORIGIN), - MISDN_HW_FLAG(16, FLG_FILLEMPTY), - MISDN_HW_FLAG(17, FLG_ARCOFI_TIMER), - MISDN_HW_FLAG(18, FLG_ARCOFI_ERROR), - MISDN_HW_FLAG(17, FLG_INITIALIZED), - MISDN_HW_FLAG(18, FLG_DLEETX), - MISDN_HW_FLAG(19, FLG_LASTDLE), - MISDN_HW_FLAG(20, FLG_FIRST), - MISDN_HW_FLAG(21, FLG_LASTDATA), - MISDN_HW_FLAG(22, FLG_NMD_DATA), - MISDN_HW_FLAG(23, FLG_FTI_RUN), - MISDN_HW_FLAG(24, FLG_LL_OK), - MISDN_HW_FLAG(25, FLG_LL_CONN), - MISDN_HW_FLAG(26, FLG_DTMFSEND), - MISDN_HW_FLAG(30, FLG_RECVQUEUE), - MISDN_HW_FLAG(31, FLG_PHCHANGE), -#undef MISDN_HW_FLAG -}; - -static const char *misdn_hw_print_flags(unsigned int flags, char *buf, int buflen) -{ - int i; - - buf[0] = '\0'; - for (i = 0; i < ftdm_array_len(misdn_hw_flags); i++) { - if ((1 << misdn_hw_flags[i].flag) & flags) { - strncat(buf, misdn_hw_flags[i].name, buflen); - flags &= ~(1 << misdn_hw_flags[i].flag); - if (!flags) break; - strncat(buf, ",", buflen); - } - } - return buf; -} - -static int misdn_handle_mph_information_ind(ftdm_channel_t *chan, const struct mISDNhead *hh, const void *data, const int data_len) -{ - struct misdn_chan_private *priv = ftdm_chan_io_private(chan); - - ftdm_unused_arg(hh); - - /* - * mISDN has some inconsistency issues here. - * - * There are only two drivers that emit MPH_INFORMATION_IND messages, - * hfcsusb and hfcmulti. The former sends a set of ph_info and ph_info_ch structures, - * while the latter just sends an int containing the current L1_SIGNAL_* event id. - * - * The flags and state information in the ph_info and ph_info_ch structures - * are defined in kernel internal hw-specific headers (mISDNhw.h). - * - * Use the payload size to guess the type of message. - */ - if (data_len >= sizeof(struct ph_info)) { - /* complete port status, hfcsusb sends this */ - struct ph_info *info = (struct ph_info *)data; - struct ph_info_ch *bch_info = NULL; - char tmp[1024] = { 0 }; - - if (data_len < (sizeof(*info) + info->dch.num_bch * sizeof(*bch_info))) { - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "mISDN MPH_INFORMATION_IND message is too short\n"); - return FTDM_FAIL; - } - bch_info = &info->bch[0]; - - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN port state:\n\tD-Chan proto:\t%hu\n\tD-Chan state:\t%s (%hu)\n\tD-Chan flags:\t%#"FTDM_XINT64_FMT"\n\t\t\t%-70s\n", - info->dch.ch.protocol, - misdn_hw_state_name(info->dch.ch.protocol, info->dch.state), info->dch.state, - (uint64_t)info->dch.ch.Flags, - misdn_hw_print_flags(info->dch.ch.Flags, tmp, sizeof(tmp) - 1)); - - /* TODO: try to translate this to a usable set of alarm flags */ - - } else if (data_len == sizeof(int)) { - /* alarm info, sent by hfcmulti */ - int value = *(int *)data; - int alarm_flags = chan->alarm_flags; - - if (data_len < sizeof(value)) { - ftdm_log_chan_msg(chan, FTDM_LOG_ERROR, "mISDN MPH_INFORMATION_IND message is too short\n"); - return FTDM_FAIL; - } - - switch (value) { - case L1_SIGNAL_LOS_ON: - alarm_flags |= FTDM_ALARM_RED; - break; - case L1_SIGNAL_LOS_OFF: - alarm_flags &= ~FTDM_ALARM_RED; - break; - case L1_SIGNAL_AIS_ON: - alarm_flags |= FTDM_ALARM_AIS; - break; - case L1_SIGNAL_AIS_OFF: - alarm_flags &= ~FTDM_ALARM_AIS; - break; - case L1_SIGNAL_RDI_ON: - alarm_flags |= FTDM_ALARM_YELLOW; - break; - case L1_SIGNAL_RDI_OFF: - alarm_flags &= ~FTDM_ALARM_YELLOW; - break; - case L1_SIGNAL_SLIP_RX: - priv->slip_rx_cnt++; - break; - case L1_SIGNAL_SLIP_TX: - priv->slip_tx_cnt++; - break; - default: - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN unknown MPH_INFORMATION_IND signal: %#04x\n", - value); - return FTDM_FAIL; - } - - /* check whether alarm status has changed, update channel flags if it has */ - if ((value = (alarm_flags ^ chan->alarm_flags))) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN alarm flags have changed %#x -> %#x\n", - chan->alarm_flags, alarm_flags); - chan->alarm_flags ^= value; - } - } else { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN sent MPH_INFORMATION_IND message with unknown size %d\n", - data_len); - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - -/*********************************************************************************** - * mISDN <-> FreeTDM interface functions - ***********************************************************************************/ - -static struct misdn_globals { - int sockfd; -} globals; - -/** - * \brief Open channel - * \param ftdmchan FreeTDM channel to open - */ -static FIO_OPEN_FUNCTION(misdn_open) -{ - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(ftdmchan); - ftdm_span_t *span = ftdm_channel_get_span(ftdmchan); - struct misdn_span_private *span_priv = ftdm_span_io_private(span); - ftdm_status_t ret = 0; - - assert(chan_priv); - assert(span_priv); - - if (chan_priv->active) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "mISDN channel is already open, skipping activation\n"); - return FTDM_SUCCESS; - } - - /* flush all events */ - misdn_event_queue_reset(chan_priv->events); - - /* - * Send activation request - */ - ret = misdn_activate_channel(ftdmchan); - if (ret != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to activate channel (socket: %d)\n", - ftdmchan->sockfd); - /* - * Ignore error, ftdm_channel_open() does not correctly handle return FTDM_FAIL cases. - * We will try to activate the channel later. - */ - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "mISDN channel activation request sent\n"); - - switch (ftdmchan->type) { - case FTDM_CHAN_TYPE_B: - case FTDM_CHAN_TYPE_DQ921: - chan_priv->active = 1; - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "mISDN invalid channel type '%s'\n", - ftdm_channel_get_type_str(ftdmchan)); - break; - } - } - return FTDM_SUCCESS; -} - -/** - * \brief Close channel - * \param ftdmchan FreeTDM channel to close - */ -static FIO_CLOSE_FUNCTION(misdn_close) -{ - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(ftdmchan); - ftdm_status_t ret = 0; - - assert(chan_priv); - - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "mISDN trying to close %c-channel\n", - ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D'); - - if (chan_priv->active) { - - if (ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B) { - ret = misdn_deactivate_channel(ftdmchan); - } else { - /* Don't wait for D-Channel deactivation */ - ret = misdn_deactivate_channel_nowait(ftdmchan); - } - - if (ret != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to deactivate %c-channel\n", - ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D'); - /* Ignore error, channel might be closed already */ - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "mISDN %c-channel deactivated\n", - ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D'); - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "mISDN tx stats: wr: %lu, rd: %lu, tx: %lu, tx-lost: %lu, tx-miss: %lu, tx-under#: %lu, tx-over#: %lu\n", - chan_priv->tx_pipe_wr_bytes, chan_priv->tx_pipe_rd_bytes, - chan_priv->tx_sent_bytes, chan_priv->tx_lost_bytes, chan_priv->tx_miss_bytes, - chan_priv->tx_pipe_over_cnt, chan_priv->tx_pipe_under_cnt); - - chan_priv->active = 0; - } - - return FTDM_SUCCESS; -} - -/** - * \brief Execute command - * \param ftdmchan FreeTDM channel - * \param command Command to execute - * \param obj Additional command data - */ -static FIO_COMMAND_FUNCTION(misdn_command) -{ - switch (command) { - case FTDM_COMMAND_NOOP: - break; - case FTDM_COMMAND_SET_INTERVAL: -// case FTDM_COMMAND_GET_INTERVAL: - case FTDM_COMMAND_SET_CODEC: - case FTDM_COMMAND_GET_CODEC: - case FTDM_COMMAND_SET_NATIVE_CODEC: - case FTDM_COMMAND_GET_NATIVE_CODEC: - case FTDM_COMMAND_ENABLE_DTMF_DETECT: - case FTDM_COMMAND_DISABLE_DTMF_DETECT: - case FTDM_COMMAND_SEND_DTMF: - case FTDM_COMMAND_SET_DTMF_ON_PERIOD: - case FTDM_COMMAND_GET_DTMF_ON_PERIOD: - case FTDM_COMMAND_SET_DTMF_OFF_PERIOD: - case FTDM_COMMAND_GET_DTMF_OFF_PERIOD: - case FTDM_COMMAND_SET_RX_GAIN: /* DSP_VOL_CHANGE_RX / HFC_VOL_CHANGE_RX */ - case FTDM_COMMAND_GET_RX_GAIN: - case FTDM_COMMAND_SET_TX_GAIN: /* DSP_VOL_CHANGE_TX / HFC_VOL_CHANGE_TX */ - case FTDM_COMMAND_GET_TX_GAIN: - case FTDM_COMMAND_FLUSH_TX_BUFFERS: - case FTDM_COMMAND_FLUSH_RX_BUFFERS: - case FTDM_COMMAND_FLUSH_BUFFERS: - case FTDM_COMMAND_FLUSH_IOSTATS: - case FTDM_COMMAND_SET_PRE_BUFFER_SIZE: - case FTDM_COMMAND_SET_LINK_STATUS: - case FTDM_COMMAND_GET_LINK_STATUS: - case FTDM_COMMAND_SET_RX_QUEUE_SIZE: - case FTDM_COMMAND_SET_TX_QUEUE_SIZE: - case FTDM_COMMAND_START_MF_PLAYBACK: - case FTDM_COMMAND_STOP_MF_PLAYBACK: - case FTDM_COMMAND_GET_IOSTATS: - case FTDM_COMMAND_SWITCH_IOSTATS: - /* Supported by mISDN */ - case FTDM_COMMAND_ENABLE_ECHOCANCEL: /* DSP_ECHO_ON */ - case FTDM_COMMAND_DISABLE_ECHOCANCEL: /* DSP_ECHO_OFF */ - case FTDM_COMMAND_ENABLE_LOOP: - case FTDM_COMMAND_DISABLE_LOOP: - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Received unimplemented command: %d\n", - command); - break; - - case FTDM_COMMAND_GET_INTERVAL: - FTDM_COMMAND_OBJ_INT = ftdm_channel_get_io_interval(ftdmchan); - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Interval %d ms\n", - ftdm_channel_get_io_interval(ftdmchan)); - break; - - default: - ftdm_log(FTDM_LOG_ERROR, "Unknown command %d\n", command); - } - return FTDM_SUCCESS; -} - - -/** - * \brief Wait for new data - * \param ftdmchan FreeTDM channel to wait on - * \param flags Wait flags - * \param to Timeout - */ -static FIO_WAIT_FUNCTION(misdn_wait) -{ - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(ftdmchan); - struct pollfd pfds[2]; - int nr_fds = 0; - int retval; - - memset(pfds, 0, sizeof(pfds)); - - switch (ftdm_channel_get_type(ftdmchan)) { - case FTDM_CHAN_TYPE_B: - if (*flags & FTDM_WRITE) { - pfds[nr_fds].fd = chan_priv->tx_audio_pipe_in; - pfds[nr_fds].events = POLLOUT; - nr_fds++; - } - if (*flags & FTDM_READ) { - pfds[nr_fds].fd = chan_priv->rx_audio_pipe_out; - pfds[nr_fds].events = POLLIN; - nr_fds++; - } -/* if (*flags & (FTDM_READ | FTDM_EVENTS)) { - pfds[nr_fds].fd = ftdmchan->sockfd; - pfds[nr_fds].events |= (*flags & FTDM_READ) ? POLLIN : 0; - pfds[nr_fds].events |= (*flags & FTDM_EVENTS) ? POLLPRI : 0; - nr_fds++; - } -*/ - break; - default: - if (*flags & FTDM_READ) - pfds[0].events |= POLLIN; - if (*flags & FTDM_WRITE) - pfds[0].events |= POLLOUT; - if (*flags & FTDM_EVENTS) - pfds[0].events |= POLLPRI; - pfds[0].fd = ftdmchan->sockfd; - nr_fds++; - break; - } - - *flags = FTDM_NO_FLAGS; - - if (!(pfds[0].events || pfds[1].events)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "mISDN poll(): no flags set!\n"); - return FTDM_SUCCESS; - } - - if ((retval = poll(pfds, nr_fds, to)) < 0) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN poll() failed: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - if (retval == 0) - return FTDM_TIMEOUT; - - switch (ftdm_channel_get_type(ftdmchan)) { - case FTDM_CHAN_TYPE_B: - if ((pfds[0].revents & POLLOUT) || (pfds[1].revents & POLLOUT)) - *flags |= FTDM_WRITE; - if ((pfds[0].revents & POLLIN) || (pfds[1].revents & POLLIN)) - *flags |= FTDM_READ; - if ((pfds[0].revents & POLLPRI) || (pfds[1].revents & POLLPRI)) - *flags |= FTDM_EVENTS; - break; - default: - if (pfds[0].revents & POLLIN) - *flags |= FTDM_READ; - if (pfds[0].revents & POLLOUT) - *flags |= FTDM_WRITE; - if (pfds[0].revents & POLLPRI) - *flags |= FTDM_EVENTS; - break; - } - return FTDM_SUCCESS; -} - - -/** - * Handle incoming mISDN message on d-channel - * \param[in] ftdmchan - * \param[in] msg_buf - * \param[in] msg_len - * \internal - */ -static ftdm_status_t misdn_handle_incoming(ftdm_channel_t *ftdmchan, const char *msg_buf, const int msg_len) -{ - struct misdn_chan_private *priv = ftdm_chan_io_private(ftdmchan); - struct mISDNhead *hh = (struct mISDNhead *)msg_buf; - const char *data = msg_buf + sizeof(*hh); - int data_len = msg_len - sizeof(*hh); - - assert(msg_buf); - assert(priv); - - if (msg_len < sizeof(*hh)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN message to small (%d < %"FTDM_SIZE_FMT" bytes)\n", - msg_len, sizeof(*hh)); - return FTDM_FAIL; - } - -#ifdef MISDN_DEBUG_EVENTS - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "mISDN %c-channel received '%s' message (id: 0x%x, additional data: %d bytes)\n", - ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D', misdn_event2str(hh->prim), hh->id, data_len); -#endif - - switch (hh->prim) { - /* data events */ - case PH_DATA_CNF: /* TX: ack */ - priv->tx_ack_cnt++; - break; - case PH_DATA_REQ: /* TX: request echo (ignore) */ - break; - case PH_DATA_E_IND: /* RX: e-channel data received (monitoring?) */ - break; - - /* control requests */ - case PH_CONTROL_IND: - return misdn_handle_ph_control_ind(ftdmchan, hh, data, data_len); - case PH_CONTROL_REQ: - case PH_CONTROL_CNF: - break; - - /* information */ - case MPH_INFORMATION_IND: - return misdn_handle_mph_information_ind(ftdmchan, hh, data, data_len); - - /* channel de-/activation */ - case PH_ACTIVATE_REQ: /* Echoed requests, ignore */ - case PH_DEACTIVATE_REQ: - break; - case PH_ACTIVATE_IND: - case PH_DEACTIVATE_IND: { - /* other events, enqueue and let misdn_event_next handle it */ - struct misdn_span_private *span_priv = ftdm_span_io_private(ftdmchan->span); - struct misdn_event evt = { 0 }; - evt.id = hh->prim; - - misdn_event_queue_push(priv->events, &evt); - - /* wake possible readers */ - pthread_cond_signal(&span_priv->event_cond); - break; - } - default: /* error? */ - ftdm_log(FTDM_LOG_DEBUG, "mISDN channel %d:%d received unknown event %d\n", - ftdm_channel_get_span_id(ftdmchan), ftdm_channel_get_id(ftdmchan), hh->prim); - break; - } - return FTDM_SUCCESS; -} - -/** - * \brief Read data - * \param ftdmchan FreeTDM channel - * \param data Buffer for data - * \param datalen Number of bytes to read (contains bytes read after return) - */ -static FIO_READ_FUNCTION(misdn_read) -{ - struct misdn_chan_private *priv = ftdm_chan_io_private(ftdmchan); - char rbuf[MAX_DATA_MEM] = { 0 }; - struct mISDNhead *hh = (struct mISDNhead *)rbuf; - int bytes = *datalen; - int retval; - int maxretry = 10; - - /* nothing read yet */ - *datalen = 0; - - /* - * try to read all messages, as long as we haven't received a PH_DATA_IND one - * we'll get a lot of "mISDN_send: error -12" message in dmesg otherwise - * (= b-channel receive queue overflowing) - */ - switch (ftdm_channel_get_type(ftdmchan)) { - case FTDM_CHAN_TYPE_DQ921: { - while (maxretry--) { - struct sockaddr_mISDN addr; - socklen_t addrlen = sizeof(addr); - - if ((retval = recvfrom(ftdmchan->sockfd, rbuf, sizeof(rbuf), 0, (struct sockaddr *)&addr, &addrlen)) < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) break; - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN failed to receive incoming message: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - - if (retval < MISDN_HEADER_LEN) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "mISDN received message too small\n"); - return FTDM_FAIL; - } - - if (hh->prim == PH_DATA_IND) { - *datalen = ftdm_clamp(retval - MISDN_HEADER_LEN, 0, bytes); - - if (*datalen <= 0) - continue; - - /* - * Copy data into ouput buffer (excluding the mISDN message header) - * NOTE: audio data needs to be converted to a-law / u-law! - */ - memcpy(data, rbuf + MISDN_HEADER_LEN, *datalen); - return FTDM_SUCCESS; - } else { - *datalen = 0; - /* event */ - misdn_handle_incoming(ftdmchan, rbuf, retval); - } - } - break; - } - case FTDM_CHAN_TYPE_B: { - if (!priv->active) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "mISDN ignoring read on closed b-channel\n"); - return FTDM_SUCCESS; - } - - if ((retval = read(priv->rx_audio_pipe_out, data, bytes)) < 0) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN failed to read audio data from rx pipe: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - *datalen = retval; - break; - } - default: - break; - } - return FTDM_SUCCESS; -} - -/** - * \brief Write data - * \param ftdmchan FreeTDM channel - * \param data Buffer for data - * \param datalen Number of bytes to write (contains bytes written after return) - */ -static FIO_WRITE_FUNCTION(misdn_write) -{ - struct misdn_chan_private *priv = ftdm_chan_io_private(ftdmchan); - char wbuf[MAX_DATA_MEM]; - struct mISDNhead *hh = (struct mISDNhead *)wbuf; - int size = *datalen; - int retval = 0; - ftdm_wait_flag_t wflags; - - assert(priv); - - /* ignore empty writes */ - if (*datalen <= 0) - return FTDM_SUCCESS; - -#ifdef MISDN_DEBUG_IO - { - char hbuf[MAX_DATA_MEM] = { 0 }; - print_hex_bytes(data, *datalen, hbuf, sizeof(hbuf)); - ftdm_log(FTDM_LOG_DEBUG, "mISDN write data: %s\n", hbuf); - } -#endif - *datalen = 0; - - switch (ftdm_channel_get_type(ftdmchan)) { - case FTDM_CHAN_TYPE_B: - /* - * Check state, send activation request (async) if channel is not open - */ - if (!priv->active) { - misdn_activate_channel_nowait(ftdmchan); - return FTDM_SUCCESS; /* eat data */ - } - /* - * Write to audio pipe, misdn_read() will pull - * from there as needed and send it to the b-channel - * - * NOTE: can't use blocking I/O here since both parts are serviced - * from the same thread - */ - if ((retval = write(priv->tx_audio_pipe_in, data, size)) < 0) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN channel audio pipe write error [wr: %lu, rd: %lu: tx: %lu, tx-under#: %lu, tx-over#: %lu]: %s\n", - priv->tx_pipe_wr_bytes, priv->tx_pipe_rd_bytes, priv->tx_sent_bytes, - priv->tx_pipe_under_cnt, priv->tx_pipe_over_cnt, strerror(errno)); - return FTDM_FAIL; - } else if (retval < size) { - priv->tx_pipe_over_cnt++; - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "mISDN channel audio pipe short write [wr: %lu, rd: %lu: tx: %lu, tx-under#: %lu, tx-over#: %lu], expected: %d, written: %d\n", - priv->tx_pipe_wr_bytes, priv->tx_pipe_rd_bytes, priv->tx_sent_bytes, - priv->tx_pipe_under_cnt, priv->tx_pipe_over_cnt, size, retval); - } - ACCESS_ONCE(priv->tx_pipe_wr_bytes) += retval; - *datalen = retval; - break; - default: - hh->prim = PH_DATA_REQ; - hh->id = MISDN_ID_ANY; - - /* Avoid buffer overflow */ - size = ftdm_min(size, MAX_DATA_MEM - MISDN_HEADER_LEN); - - memcpy(wbuf + MISDN_HEADER_LEN, data, size); - size += MISDN_HEADER_LEN; - - /* - * Check state, send activation request (sync) if channel is not open - */ - if (!priv->active) { - retval = misdn_activate_channel(ftdmchan); - if (retval) { - *datalen = 0; - return FTDM_FAIL; - } - } - - /* wait for channel to get ready */ - wflags = FTDM_WRITE; - retval = misdn_wait(ftdmchan, &wflags, 20); - if (retval) { - /* timeout, io error */ - *datalen = 0; - return FTDM_FAIL; - } - -#ifdef MISDN_DEBUG_IO - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "mISDN writing %d bytes to channel socket %d [dev.ch: %d.%d]\n", - size, ftdmchan->sockfd, priv->addr.dev, priv->addr.channel); -#endif - - if ((retval = sendto(ftdmchan->sockfd, wbuf, size, 0, NULL, 0)) < size) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "mISDN channel socket write error: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - *datalen = retval; - break; - } - - priv->tx_cnt++; - return FTDM_SUCCESS; -} - -/** - * Carefully choosen size for socket send/recv buffers - * larger values will add more latency, while lower values will cause deadlocks - * (see misdn_span_run() comments below for an explanation) - */ -#define SOCKETPAIR_BUFFER_SIZE 3072 - -static ftdm_status_t misdn_open_range(ftdm_span_t *span, ftdm_chan_type_t type, struct mISDN_devinfo *devinfo, int start, int end) -{ - int num_configured = 0; - int d_protocol, d_channel; - int x; - - ftdm_log(FTDM_LOG_DEBUG, "mISDN configuring card:range %d:%d->%d\n", - devinfo->id, start, end); - - switch (ftdm_span_get_trunk_type(span)) { - case FTDM_TRUNK_E1: - d_protocol = ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET ? ISDN_P_NT_E1 : ISDN_P_TE_E1; - d_channel = 16; - break; - case FTDM_TRUNK_BRI: - case FTDM_TRUNK_BRI_PTMP: - d_protocol = ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET ? ISDN_P_NT_S0 : ISDN_P_TE_S0; - d_channel = 0; - break; - default: - ftdm_log(FTDM_LOG_ERROR, "Unsupported span type %s\n", - ftdm_span_get_trunk_type_str(span)); - return FTDM_FAIL; - } - - for (x = start; x <= end; x++) { - struct misdn_chan_private *priv; - struct sockaddr_mISDN addr; - ftdm_channel_t *ftdmchan = NULL; - ftdm_socket_t sockfd = -1; - - ftdm_log(FTDM_LOG_DEBUG, "mISDN configuring card:channel => %d:%d\n", - devinfo->id, x); - - memset(&addr, 0, sizeof(addr)); - addr.family = AF_ISDN; - addr.dev = devinfo->id; - - switch (type) { - case FTDM_CHAN_TYPE_DQ931: /* unsupported */ - ftdm_log(FTDM_LOG_ERROR, "Unsupported channel type '%s'\n", - ftdm_chan_type2str(type)); - return FTDM_FAIL; - - case FTDM_CHAN_TYPE_DQ921: - /* No NT-mode support, since we have no idea which mode we should run in at this point */ - sockfd = socket(PF_ISDN, SOCK_DGRAM, d_protocol); - addr.channel = d_channel; /* 0 for S0 and 16 for E1 */ - break; - - case FTDM_CHAN_TYPE_B: - if (!test_channelmap(x, devinfo->channelmap)) { - ftdm_log(FTDM_LOG_ERROR, "Invalid B-Channel specified: %d\n", x); - return FTDM_FAIL; - } - sockfd = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW); - addr.channel = x; - break; - - default: - ftdm_log(FTDM_LOG_ERROR, "Invalid/unsupported channel type '%s' (%d)\n", - ftdm_chan_type2str(type), type); - return FTDM_FAIL; - } - - if (sockfd < 0) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open socket: %s\n", strerror(errno)); - return FTDM_FAIL; - } - - ftdm_log(FTDM_LOG_DEBUG, "mISDN opened socket (on chan:dev => %d:%d): %d\n", - addr.dev, addr.channel, sockfd); - - /* Set mISDN channel socket non-blocking */ - if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN Failed to set socket fd to non-blocking: %s\n", - strerror(errno)); - close(sockfd); - return FTDM_FAIL; - } - - /* - * Bind socket to card:channel - */ - if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Failed to bind mISDN socket [%d:%d]: %s\n", - addr.dev, x, strerror(errno)); - close(sockfd); - return FTDM_FAIL; - } - - /* - * Add channel to span - */ - if (ftdm_span_add_channel(span, sockfd, type, &ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to add mISDN ftdmchan to span\n"); - close(sockfd); - return FTDM_FAIL; - } - - priv = calloc(1, sizeof(*priv)); - if (!priv) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to allocate channel private data\n"); - close(sockfd); - return FTDM_FAIL; - } - ftdm_chan_io_private(ftdmchan) = priv; - - priv->addr = addr; - priv->debugfd = -1; - - /* - * Create event queue - */ - misdn_event_queue_create(&priv->events); - - ftdmchan->rate = 8000; - ftdmchan->physical_span_id = devinfo->id; - ftdmchan->physical_chan_id = x; - - if (ftdmchan->type == FTDM_CHAN_TYPE_B) { - int pipefd[2] = { -1, -1 }; - - ftdmchan->packet_len = 30 /* ms */ * (ftdmchan->rate / 1000); - ftdmchan->effective_interval = ftdmchan->native_interval = ftdmchan->packet_len / 8; - ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_ALAW; - -// ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL); - -#ifdef USE_PIPE - /* - * Create audio tx pipe, use non-blocking I/O to avoid deadlock since both ends - * are used from the same thread - */ - if (pipe2(pipefd, 0 | O_NONBLOCK) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Failed to create mISDN audio tx pipe [%d:%d]: %s\n", - addr.dev, x, strerror(errno)); - close(sockfd); - return FTDM_FAIL; - } - priv->tx_audio_pipe_in = pipefd[1]; - priv->tx_audio_pipe_out = pipefd[0]; - -#if 1 || defined(HAVE_F_SETPIPE_SZ) - if (fcntl(priv->tx_audio_pipe_in, F_SETPIPE_SZ, 4096) < 0) { - ftdm_log(FTDM_LOG_WARNING, "Failed to set mISDN audio tx pipe size [%d:%d]: %s\n", - addr.dev, x, strerror(errno)); - } -#endif - /* - * Create audio rx pipe, use non-blocking I/O to avoid deadlock since both ends - * are used from the same thread - */ - if (pipe2(pipefd, 0 | O_NONBLOCK) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Failed to create mISDN audio rx pipe [%d:%d]: %s\n", - addr.dev, x, strerror(errno)); - close(sockfd); - return FTDM_FAIL; - } - priv->rx_audio_pipe_in = pipefd[1]; - priv->rx_audio_pipe_out = pipefd[0]; - -#if 1 || defined(HAVE_F_SETPIPE_SZ) - if (fcntl(priv->rx_audio_pipe_in, F_SETPIPE_SZ, 4096) < 0) { - ftdm_log(FTDM_LOG_WARNING, "Failed to set mISDN audio rx pipe size [%d:%d]: %s\n", - addr.dev, x, strerror(errno)); - } -#endif -#else /* !USE_PIPE */ - /* - * Use a socket pair for audio rx/tx, allows for more fine-grained control - * of latency (= amounts of data in buffers) - */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Failed to create mISDN audio socket pair [%d:%d]: %s\n", - addr.dev, x, strerror(errno)); - close(sockfd); - return FTDM_FAIL; - } else { - int opt = SOCKETPAIR_BUFFER_SIZE; - socklen_t optlen = sizeof(opt); - - if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN Failed to set socket pair fd[0] to non-blocking: %s\n", - strerror(errno)); - close(sockfd); - close(pipefd[0]); - close(pipefd[1]); - return FTDM_FAIL; - } - if (fcntl(pipefd[1], F_SETFL, O_NONBLOCK) < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN Failed to set socket pair fd[1] to non-blocking: %s\n", - strerror(errno)); - close(sockfd); - close(pipefd[0]); - close(pipefd[1]); - return FTDM_FAIL; - } - - /* - * Set RX/TX buffer sizes on each end of the socket pair - */ - if (setsockopt(pipefd[0], SOL_SOCKET, SO_RCVBUF, &opt, optlen) < 0) { - ftdm_log(FTDM_LOG_WARNING, "mISDN Failed to set socket pair fd[0] RCVBUF: %s\n", - strerror(errno)); - } - if (setsockopt(pipefd[0], SOL_SOCKET, SO_SNDBUF, &opt, optlen) < 0) { - ftdm_log(FTDM_LOG_WARNING, "mISDN Failed to set socket pair fd[0] SNDBUF: %s\n", - strerror(errno)); - } - if (setsockopt(pipefd[1], SOL_SOCKET, SO_RCVBUF, &opt, optlen) < 0) { - ftdm_log(FTDM_LOG_WARNING, "mISDN Failed to set socket pair fd[1] RCVBUF: %s\n", - strerror(errno)); - } - if (setsockopt(pipefd[1], SOL_SOCKET, SO_SNDBUF, &opt, optlen) < 0) { - ftdm_log(FTDM_LOG_WARNING, "mISDN Failed to set socket pair fd[1] SNDBUF: %s\n", - strerror(errno)); - } - - priv->rx_audio_pipe_in = pipefd[1]; - priv->rx_audio_pipe_out = pipefd[0]; - - priv->tx_audio_pipe_in = pipefd[0]; - priv->tx_audio_pipe_out = pipefd[1]; - } -#endif - } else { - /* early activate D-Channel */ - misdn_activate_channel(ftdmchan); - ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE; - } - num_configured++; - } - - return num_configured; -} - -static int misdn_find_device(const char *name, int nr_devices, struct mISDN_devinfo *info) -{ - struct mISDN_devinfo devinfo; - char *endp = NULL; - int port_id = -1; - int i; - - port_id = strtoul(name, &endp, 10); - if (endp == name || errno == EINVAL) - port_id = -1; - if (port_id < 0 || port_id >= nr_devices) - port_id = -1; - - for (i = 0; i < nr_devices; i++) { - memset(&devinfo, 0, sizeof(devinfo)); - devinfo.id = i; - - if (ioctl(globals.sockfd, IMGETDEVINFO, &devinfo) < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN unable to get device %d info: %s\n", - devinfo.id, strerror(errno)); - return FTDM_FAIL; - } - if (devinfo.id == port_id) - break; - if (strlen(devinfo.name) <= 0) - continue; - if (!strcasecmp(devinfo.name, name)) - break; - } - if (i == nr_devices) - return FTDM_FAIL; - - if (info) *info = devinfo; - return FTDM_SUCCESS; -} - -#define MISDN_PH_TE_PROTOCOLS(x) \ - ((x) & ((1 << ISDN_P_TE_S0) | (1 << ISDN_P_TE_E1) | (1 << ISDN_P_TE_UP0))) -#define MISDN_PH_NT_PROTOCOLS(x) \ - ((x) & ((1 << ISDN_P_NT_S0) | (1 << ISDN_P_NT_E1) | (1 << ISDN_P_NT_UP0))) - -/** - * \brief Configure/open span ftmod_misdn settings - */ -static FIO_CONFIGURE_SPAN_FUNCTION(misdn_configure_span) -{ - struct misdn_span_private *span_priv = ftdm_span_io_private(span); - struct mISDN_devinfo devinfo; - int range_start = 0, range_end = 0; - int nr_ports = 0, nr_items = 0; - int res = 0, i; - char *chan_str, *ptr; - char *data = strdup(str); - char *item_list[10]; - - ftdm_unused_arg(name); - ftdm_unused_arg(number); - - /* only these are supported */ - switch (ftdm_span_get_trunk_type(span)) { - case FTDM_TRUNK_E1: - case FTDM_TRUNK_BRI: - case FTDM_TRUNK_BRI_PTMP: - break; - default: - ftdm_log(FTDM_LOG_ERROR, "Unsupported span type %s\n", - ftdm_span_get_trunk_type_str(span)); - return FTDM_FAIL; - } - - /* get port count */ - if (ioctl(globals.sockfd, IMGETCOUNT, &nr_ports) < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN unable to get port count: %s\n", - strerror(errno)); - goto error; - } - if (nr_ports <= 0) { - ftdm_log(FTDM_LOG_ERROR, "No mISDN devices found\n"); - goto error; - } - - /* split configuration string into port ID and channel list */ - if (!(chan_str = strchr(data, ':'))) { - ftdm_log(FTDM_LOG_ERROR, "Invalid configuration string: %s\nExpected format :[-]\n", str); - goto error; - } - *chan_str++ = '\0'; - - /* lookup port id, by number first, then by name */ - if (misdn_find_device(data, nr_ports, &devinfo) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "No such mISDN device/port: %s\n", - data); - goto error; - } - if (devinfo.nrbchan == 0 || devinfo.channelmap == 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN device '%s' has no b-channels\n", - data); - goto error; - } - if (!MISDN_PH_TE_PROTOCOLS(devinfo.Dprotocols)) { - ftdm_log(FTDM_LOG_ERROR, "mISDN device '%s' does not support any ISDN TE modes\n", - data); - goto error; - } - - /* allocate span private */ - if (!span_priv) { - int pipe[2] = { -1, -1 }; - - /* - * Not perfect, there should be something like span_create too - */ - span_priv = calloc(1, sizeof(*span_priv)); - if (!span_priv) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to allocate span private data\n"); - return FTDM_FAIL; - } - ftdm_span_io_private(span) = span_priv; - - /* init event condition */ - pthread_cond_init(&span_priv->event_cond, NULL); - pthread_mutex_init(&span_priv->event_cond_mutex, NULL); - - /* init control condition */ - pthread_cond_init(&span_priv->ctrl_cond, NULL); - pthread_mutex_init(&span_priv->ctrl_cond_mutex, NULL); - - /* create event pipe */ - if (pipe2(pipe, O_CLOEXEC) < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to create event pipe: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - span_priv->event_pipe_in = pipe[0]; - span_priv->event_pipe_out = pipe[1]; - } - - /* split channel list by ',' */ - nr_items = ftdm_separate_string(chan_str, ',', item_list, ftdm_array_len(item_list)); - - for (i = 0; i < nr_items; i++) { - /* */ - if (!(ptr = strchr(item_list[i], '-'))) { - /* single channel */ - range_start = atoi(item_list[i]); - range_end = range_start; - } else { - *ptr++ = '\0'; - /* channel range */ - range_start = atoi(item_list[i]); - range_end = atoi(ptr); - } - - /* check if channel range/id is valid */ - if (range_start <= 0 || range_end <= 0 || range_end < range_start) { - ftdm_log(FTDM_LOG_ERROR, "Invalid configuration string: %s\n", - item_list[i]); - goto error; - } - - /* add range to span */ - res = misdn_open_range(span, type, &devinfo, range_start, range_end); - if (res <= 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to configure channel(s)\n"); - goto error; - } - } - - ftdm_safe_free(data); - return res; -error: - ftdm_span_io_private(span) = NULL; - ftdm_safe_free(span_priv); - ftdm_safe_free(data); - return res; -} - -/** - * \brief Configure global ftmod_misdn settings - */ -static FIO_CONFIGURE_FUNCTION(misdn_configure) -{ - ftdm_unused_arg(category); - ftdm_unused_arg(var); - ftdm_unused_arg(val); - ftdm_unused_arg(lineno); - return FTDM_SUCCESS; -} - -/** - * \brief Retrieve alarm event information (if any) - * \param ftdmchan FreeTDM channel - */ -static FIO_GET_ALARMS_FUNCTION(misdn_get_alarms) -{ - ftdm_unused_arg(ftdmchan); -#if 0 -/* - Nope, this won't work... - - There's no way to create a separate "control" socket for a device - that can be used to send / receive MPH_INFORMATION_REQ/_IND without - having to care about PH_* messages in between... - - ... well, unless we use our own event loop (= thread) and - add event queues and data fifos, so we can sift all the - messages we get to forward them to the right receiver -*/ - char buf[MAX_DATA_MEM] = { 0 }; - struct sockaddr_mISDN addr; - struct mISDNhead *hh; - struct ph_info *phi = NULL; - struct pollfd pfd; - socklen_t addrlen = sizeof(addr); - int retval; - - /* use the global socket to query alarms */ - ftdm_log(FTDM_LOG_DEBUG, "mISDN getting alarms for channel %d:%d [%d:%d]\n", - ftdm_channel_get_span_id(ftdmchan), ftdm_channel_get_id(ftdmchan), - ftdm_channel_get_ph_span_id(ftdmchan), ftdm_channel_get_ph_id(ftdmchan)); - - memset(&addr, 0, sizeof(addr)); - addr.family = AF_ISDN; - addr.dev = ftdm_channel_get_ph_span_id(ftdmchan) - 1; - addr.channel = ftdm_channel_get_ph_id(ftdmchan) - 1; - - hh = (struct mISDNhead *)buf; - hh->prim = MPH_INFORMATION_REQ; - hh->id = MISDN_ID_ANY; - - /* */ - if ((retval = sendto(span_priv->ctrlsock, hh, sizeof(*hh), 0, (struct sockaddr *)&addr, addrlen)) <= 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to send '%s' to channel %d:%d: %s\n", - misdn_event2str(hh->prim), ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), strerror(errno)); - return FTDM_FAIL; - } - - pfd.fd = span_priv->ctrlsock; - pfd.events = POLLIN /*| POLLPRI*/; - pfd.revents = 0; - - if ((retval = poll(&pfd, 1, -1)) <= 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to poll for '%s' answer on channel %d:%d: %s\n", - misdn_event2str(hh->prim), ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), strerror(errno)); - return FTDM_FAIL; - } - - if (!(pfd.revents & (POLLIN | POLLPRI))) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to poll for '%s' answer on channel %d:%d: %s\n", - misdn_event2str(hh->prim), ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), "No read/pri flag"); - return FTDM_FAIL; - } - - if ((retval = recvfrom(span_priv->ctrlsock, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addrlen)) < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to receive answer for '%s' on channel %d:%d: %s\n", - misdn_event2str(hh->prim), ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), strerror(errno)); - return FTDM_FAIL; - } - if (retval < MISDN_HEADER_LEN) { - ftdm_log(FTDM_LOG_ERROR, "mISDN short read on channel %d:%d\n", - ftdm_channel_get_span_id(ftdmchan), ftdm_channel_get_id(ftdmchan)); - return FTDM_FAIL; - } - - switch (hh->prim) { - case MPH_INFORMATION_IND: - ftdm_log(FTDM_LOG_DEBUG, "mISDN received '%s' on channel %d:%d, size %d bytes\n", - misdn_event2str(hh->prim), ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), retval); - break; - default: - ftdm_log(FTDM_LOG_ERROR, "mISDN received unexpected answer '%s' on channel %d:%d: %s\n", - misdn_event2str(hh->prim), ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan), strerror(errno)); - return FTDM_FAIL; - } -#endif - return FTDM_SUCCESS; -} - - -/** - * \brief Poll for new events - * \param span FreeTDM span - * \param ms Timeout (in ms) - */ -static FIO_SPAN_POLL_EVENT_FUNCTION(misdn_poll_event) -{ - struct misdn_span_private *span_priv = ftdm_span_io_private(span); - struct timespec ts; - int retval = 0, nr_events = 0; - int i; - - ftdm_unused_arg(poll_events); - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(chan); - - /* Skip channels that have event processing pending (Avoids event storms) */ - if (ftdm_test_io_flag(chan, FTDM_CHANNEL_IO_EVENT)) - continue; - - if (misdn_event_queue_has_data(chan_priv->events)) { -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN channel %d:%d has event(s)\n", - ftdm_channel_get_span_id(chan), ftdm_channel_get_id(chan)); -#endif - ftdm_set_io_flag(chan, FTDM_CHANNEL_IO_EVENT); - chan->last_event_time = ftdm_current_time_in_ms(); - nr_events++; - } - } - if (nr_events) { -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN span %d has %d new events pending (pre poll)\n", - ftdm_span_get_id(span), nr_events); -#endif - return FTDM_SUCCESS; - } - - -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN span %d has no events pending, polling for new events with %d ms timeout\n", - ftdm_span_get_id(span), ms); -#endif - /* Wait at least 1 ms, max 1 s */ - ms = ftdm_clamp(ms, 1, 1000); - - clock_gettime(CLOCK_REALTIME, &ts); - ts_add_msec(&ts, ms); - - if ((retval = pthread_cond_timedwait(&span_priv->event_cond, &span_priv->event_cond_mutex, &ts))) { - switch (retval) { - case ETIMEDOUT: -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN span %d: No events within %d ms\n", - ftdm_span_get_id(span), ms); -#endif - return FTDM_TIMEOUT; - default: - ftdm_log(FTDM_LOG_DEBUG, "mISDN failed to poll for events on span %d: %s\n", - ftdm_span_get_id(span), strerror(retval)); - return FTDM_FAIL; - } - } - -#ifdef MISDN_DEBUG_EVENTS - ftdm_log(FTDM_LOG_DEBUG, "mISDN span %d received new event notification, checking channel event queues\n", - ftdm_span_get_id(span)); -#endif - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(chan); - - /* Skip channels that have event processing pending (Avoids event storms) */ - if (ftdm_test_io_flag(chan, FTDM_CHANNEL_IO_EVENT)) - continue; - - if (misdn_event_queue_has_data(chan_priv->events)) { - ftdm_set_io_flag(chan, FTDM_CHANNEL_IO_EVENT); - chan->last_event_time = ftdm_current_time_in_ms(); - nr_events++; - } - } - return (nr_events) ? FTDM_SUCCESS : FTDM_TIMEOUT; /* no events? => timeout */ -} - -/** - * Retrieve event from channel - * \param ftdmchan Channel to retrieve event from - * \param event FreeTDM event to return - * \return Success or failure - */ -static FIO_CHANNEL_NEXT_EVENT_FUNCTION(misdn_channel_next_event) -{ - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(ftdmchan); - struct misdn_event *evt = NULL; - ftdm_span_t *span = ftdm_channel_get_span(ftdmchan); - uint32_t event_id = FTDM_OOB_INVALID; - - ftdm_assert(span, "span == NULL"); - - ftdm_clear_io_flag(ftdmchan, FTDM_CHANNEL_IO_EVENT); - - if (!(evt = misdn_event_queue_pop(chan_priv->events))) { -#ifdef MISDN_DEBUG_EVENTS - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "mISDN channel event queue has no events\n"); -#endif - return FTDM_FAIL; - } - -#ifdef MISDN_DEBUG_EVENTS - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got event '%s' from channel event queue\n", - misdn_event2str(evt->id)); -#endif - /* Convert from misdn event to ftdm */ - switch (evt->id) { - case PH_DEACTIVATE_IND: - event_id = FTDM_OOB_ALARM_TRAP; - ftdmchan->alarm_flags |= FTDM_ALARM_RED; - break; - case PH_ACTIVATE_IND: - event_id = FTDM_OOB_ALARM_CLEAR; - ftdmchan->alarm_flags &= ~FTDM_ALARM_RED; - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled event id %d (0x%x) %s\n", - evt->id, evt->id, misdn_event2str(evt->id)); - } - - ftdmchan->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = ftdmchan; - *event = &span->event_header; - return FTDM_SUCCESS; -} - -/** - * \brief Retrieve event - * \param span FreeTDM span - * \param event FreeTDM event - */ -static FIO_SPAN_NEXT_EVENT_FUNCTION(misdn_next_event) -{ - int32_t event_id = FTDM_OOB_INVALID; - int i; - - ftdm_log(FTDM_LOG_DEBUG, "Reading next event from span %d\n", - ftdm_span_get_id(span)); - - for (i = 1; i <= ftdm_span_get_chan_count(span); i++) { - ftdm_channel_t *chan = ftdm_span_get_channel(span, i); - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(chan); - struct misdn_event *evt = NULL; - - ftdm_clear_io_flag(chan, FTDM_CHANNEL_IO_EVENT); - - if (!(evt = misdn_event_queue_pop(chan_priv->events))) { -#ifdef MISDN_DEBUG_EVENTS - ftdm_log_chan_msg(chan, FTDM_LOG_DEBUG, "mISDN channel event queue has no events\n"); -#endif - continue; - } - -#ifdef MISDN_DEBUG_EVENTS - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Got event '%s' from channel event queue\n", - misdn_event2str(evt->id)); -#endif - switch (evt->id) { - case PH_DEACTIVATE_IND: - event_id = FTDM_OOB_ALARM_TRAP; - chan->alarm_flags |= FTDM_ALARM_RED; - break; - case PH_ACTIVATE_IND: - event_id = FTDM_OOB_ALARM_CLEAR; - chan->alarm_flags &= ~FTDM_ALARM_RED; - break; - default: - ftdm_log(FTDM_LOG_ERROR, "Unhandled event id %d (0x%x) %s\n", - evt->id, evt->id, misdn_event2str(evt->id)); - continue; - } - - chan->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = chan; - *event = &span->event_header; - return FTDM_SUCCESS; - } - return FTDM_FAIL; -} - -/** - * \brief Shutdown ftmod_misdn channel - * \param ftdmchan FreeTDM channel - */ -static FIO_CHANNEL_DESTROY_FUNCTION(misdn_channel_destroy) -{ - struct misdn_chan_private *chan_priv = ftdm_chan_io_private(ftdmchan); - assert(chan_priv); - - ftdm_log(FTDM_LOG_DEBUG, "Destroying channel %d:%d\n", - ftdm_channel_get_span_id(ftdmchan), - ftdm_channel_get_id(ftdmchan)); - - if (ftdmchan->sockfd >= 0) { - close(ftdmchan->sockfd); - ftdmchan->sockfd = -1; - } - - /* - * Destroy fifo + event queue - */ - if (chan_priv->events) - misdn_event_queue_destroy(&chan_priv->events); - - ftdm_chan_io_private(ftdmchan) = NULL; - ftdm_safe_free(chan_priv); - - ftdm_log(FTDM_LOG_DEBUG, "mISDN channel %d:%d destroyed\n", - ftdm_channel_get_span_id(ftdmchan), ftdm_channel_get_id(ftdmchan)); - return FTDM_SUCCESS; -} - -/** - * \brief Shutdown ftmod_misdn span - * \param span FreeTDM span - */ -static FIO_SPAN_DESTROY_FUNCTION(misdn_span_destroy) -{ - struct misdn_span_private *span_priv = ftdm_span_io_private(span); - - /* free resources */ - ftdm_span_io_private(span) = NULL; - ftdm_safe_free(span_priv); - - ftdm_log(FTDM_LOG_DEBUG, "mISDN span %d (%s) destroyed\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - return FTDM_SUCCESS; -} - - -/** - * Called by misdn_span_run() to handle incoming b-channel events - * \param[in] chan FreeTDM channel object - * \return FTDM_SUCCESS on success, FTDM_* on error - */ -static ftdm_status_t handle_b_channel_event(ftdm_channel_t *chan) -{ - struct misdn_chan_private *priv = ftdm_chan_io_private(chan); - char buf[MAX_DATA_MEM] = { 0 }; - struct mISDNhead *mh = (void *)buf; - int retval, retries = 5; - - do { - /* - * Retry reading multiple times if recvfrom() returns EAGAIN - */ - retval = recvfrom(chan->sockfd, buf, sizeof(buf), 0, NULL, NULL); - if (retval < 0 && errno != EAGAIN) - break; - - } while (retval < 0 && retries-- > 0); - - if (retval < 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to receive message: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - if (retval < MISDN_HEADER_LEN) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN message too short, min.: %d, read: %d\n", - (int)MISDN_HEADER_LEN, retval); - return FTDM_FAIL; - } - - switch (mh->prim) { - case PH_DATA_IND: { - int datalen = retval - MISDN_HEADER_LEN; - char *data = buf + MISDN_HEADER_LEN; - - /* Discard incoming audio if not active */ - if (priv->active) { - /* Convert audio data */ - misdn_convert_audio_bits(data, datalen); - - /* Write audio into receive pipe */ - if ((retval = write(priv->rx_audio_pipe_in, data, datalen)) < 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to write audio data into rx pipe: %s\n", - strerror(errno)); - return FTDM_FAIL; - } else if (retval < datalen) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN short write into rx pipe, written: %d, expected: %d\n", - retval, datalen); - return FTDM_FAIL; - } - } - - /* Get receive buffer usage */ - if (ioctl(priv->tx_audio_pipe_out, FIONREAD, &retval) < 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to get tx audio buffer usage: %s\n", - strerror(errno)); - return FTDM_FAIL; - } else if (retval < datalen) { -// ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN has not enough bytes in tx audio pipe, available: %d, requested: %d\n", -// retval, datalen); - priv->tx_pipe_under_cnt++; - return FTDM_SUCCESS; - } - -#ifdef MISDN_DEBUG_IO - ftdm_log_chan(chan, FTDM_LOG_INFO, "mISDN tx audio buffer usage: %d\n", - retval); -#endif - - /* Get audio from tx pipe */ - if ((retval = read(priv->tx_audio_pipe_out, data, datalen)) < 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to read audio data from tx pipe: %s\n", - strerror(errno)); - return FTDM_FAIL; - } else if (retval == 0) { - ftdm_log_chan_msg(chan, FTDM_LOG_NOTICE, "mISDN tx pipe is empty\n"); - priv->tx_pipe_under_cnt++; - return FTDM_SUCCESS; - } else if (retval < datalen) { - ftdm_log_chan(chan, FTDM_LOG_NOTICE, "mISDN short read from tx pipe, read: %d, expected: %d\n", - retval, datalen); - priv->tx_pipe_under_cnt++; - priv->tx_miss_bytes += ftdm_max(0, datalen - retval); - datalen = retval; - } - priv->tx_pipe_rd_bytes += retval; - - if (!priv->active) { - /* discard */ - return FTDM_SUCCESS; - } - - /* Convert audio data */ - misdn_convert_audio_bits(data, datalen); - - /* Write to channel */ - mh->prim = PH_DATA_REQ; - mh->id = 0; - datalen += MISDN_HEADER_LEN; - - if ((retval = write(chan->sockfd, buf, datalen)) < 0) { - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to write audio data into b-channel: %s\n", - strerror(errno)); - return FTDM_FAIL; - } else if (retval < datalen) { - ftdm_log_chan(chan, FTDM_LOG_WARNING, "mISDN short write into b-channel, written: %d, expected: %d\n", - retval, datalen); - priv->tx_lost_bytes += ftdm_max(0, datalen - retval - MISDN_HEADER_LEN); - } - priv->tx_sent_bytes += ftdm_max(0, retval - MISDN_HEADER_LEN); - break; - } - case PH_DATA_CNF: - priv->tx_ack_cnt++; - break; - case PH_DEACTIVATE_IND: - priv->active = 0; - break; - case PH_ACTIVATE_IND: - priv->active = 1; - break; - case PH_CONTROL_IND: { - int datalen = retval - MISDN_HEADER_LEN; - char *data = buf + MISDN_HEADER_LEN; - - misdn_handle_ph_control_ind(chan, mh, data, datalen); - break; - } - default: - ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN received unknown/unhandled event primitive: (%d) %s\n", - mh->prim, misdn_event2str(mh->prim)); - break; - } - return FTDM_SUCCESS; -} - - -/** - * Timeout (miliseconds) for epoll_wait() - */ -#define MISDN_EPOLL_WAIT_MAX_MSEC 1000 - -/** - * mISDN I/O thread - * This thread handles all of the B-Channel I/O, this avoids all of the hazzles with - * intermixed data + control frames on mISDN sockets and the missing write poll support on B-Channels. - * - * Each channel uses a unix stream socketpair as a two-way, pipe replacement for incoming and outgoing - * data. Socketpairs allow a more fine grained tuning of the buffer sizes (pipe are restricted to multiples of - * the native page size (with the smallest possible size (4k) being already 500ms worth of audio). - * - * The socketpair buffer sizes and the send algorithm have been carefully tuned to: - * - * - Minimize the risk of sending too much data and making the mISDN drivers unhappy, by - * sending PH_DATA_REQ only when there is as much data available as we have received in - * the PH_DATA_IND. - * - * - Avoid deadlocks between ftdm_write() trying to fill an almust full socket buffer and - * the I/O thread not having enough data to send a PH_DATA_REQ message. - * (The write() call will return EAGAIN since there is not ehough space free to send all audio data.) - * - * \param thread FreeTDM thread handle - * \param data Private data pointer passed to ftdm_thread_create_detached() (the span object) - * \return Always returns NULL (unused) - * - * \note - * ftdm_span_start/_stop() locks the span mutex, - * use direct access to span members to avoid deadlocking - * - * \todo - * Move D-Channel handling into the I/O thread too. - * Use custom ring buffer structures instead of socketpairs - * (for even more fine grained size control). - */ -static void *misdn_span_run(ftdm_thread_t *thread, void *data) -{ - ftdm_span_t *span = data; - struct misdn_span_private *priv = ftdm_span_io_private(span); - struct epoll_event evh; - int epfd = -1; - int ret; - int i; - - ftdm_unused_arg(thread); - ftdm_log(FTDM_LOG_NOTICE, "mISDN[%d:%s] span thread initializing\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - /* Use epoll for event handling */ - epfd = epoll_create(1); - if (epfd < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] failed to create epoll context: %s\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), strerror(errno)); - goto error; - } - - ftdm_log(FTDM_LOG_DEBUG, "mISDN[%d:%s] adding event pipe to epoll context\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - /* Add event pipe */ - evh.events = EPOLLIN | EPOLLPRI | EPOLLERR; - evh.data.fd = priv->event_pipe_out; - - ret = epoll_ctl(epfd, EPOLL_CTL_ADD, priv->event_pipe_out, &evh); - if (ret < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] failed to add event pipe to epoll context: %s\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), strerror(errno)); - goto error; - } - - ftdm_log(FTDM_LOG_DEBUG, "mISDN[%d:%s] adding b-channels to epoll context\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - /* Add b-channels */ - for (i = 1; i <= span->chan_count; i++) { - ftdm_channel_t *chan = span->channels[i]; - ftdm_assert(chan, "channel == NULL"); - - if (ftdm_channel_get_type(chan) != FTDM_CHAN_TYPE_B) - continue; - - ftdm_log(FTDM_LOG_DEBUG, "mISDN[%d:%s] adding b-channel [%d:%d] to epoll context\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), - ftdm_channel_get_id(chan), ftdm_channel_get_ph_id(chan)); - - evh.events = EPOLLIN | EPOLLPRI | EPOLLERR; - evh.data.ptr = chan; - - ret = epoll_ctl(epfd, EPOLL_CTL_ADD, chan->sockfd, &evh); - if (ret < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] failed to add b-channel [%d] socket to epoll context: %s\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), ftdm_channel_get_id(chan), strerror(errno)); - goto error; - } - } - - ftdm_log(FTDM_LOG_NOTICE, "mISDN[%d:%s] span thread started\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - /* Notify world we're running */ - priv->running = 1; - pthread_cond_signal(&priv->ctrl_cond); - - while (priv->running > 0) { - struct epoll_event ev[10]; - int timeout_ms = MISDN_EPOLL_WAIT_MAX_MSEC; - - ret = epoll_wait(epfd, ev, ftdm_array_len(ev), timeout_ms); - if (ret < 0) { - switch (errno) { - case EAGAIN: - case EINTR: - continue; - default: - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] epoll_wait() failed: %s\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), strerror(errno)); - goto error; - } - } - /* Check events */ - for (i = 0; i < ret; i++) { - /* */ - if (ev[i].data.fd == priv->event_pipe_out) { - struct misdn_command cmd; - /* event pipe */ - ftdm_log(FTDM_LOG_DEBUG, "mISDN[%d:%s] event pipe notification\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - ret = read(priv->event_pipe_out, &cmd, sizeof(cmd)); - if (ret < sizeof(cmd)) { - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] failed to read span thread command\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - continue; - } - - switch (cmd.type) { - case MISDN_CMD_STOP: - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] got STOP command\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - priv->running = -1; - break; - default: - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] got unknown command: %d\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), cmd.type); - } - - } else { - ftdm_channel_t *chan = ev[i].data.ptr; - handle_b_channel_event(chan); - } - } - } -error: - ftdm_log(FTDM_LOG_NOTICE, "mISDN[%d:%s] span thread stopped\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - /* Remove epoll event sources */ - for (i = 1; i <= span->chan_count; i++) { - ftdm_channel_t *chan = span->channels[i]; - ftdm_assert(chan, "channel == NULL"); - - if (ftdm_channel_get_type(chan) != FTDM_CHAN_TYPE_B) - continue; - - ret = epoll_ctl(epfd, EPOLL_CTL_DEL, chan->sockfd, NULL); - if (ret < 0) { - ftdm_log(FTDM_LOG_ERROR, "mISDN[%d:%s] failed to remove b-channel [%d] socket from epoll context: %s\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), ftdm_channel_get_id(chan), strerror(errno)); - } - } - - /* Close epoll context */ - if (epfd >= 0) close(epfd); - - /* Notify world we stopped running */ - priv->running = 0; - pthread_cond_signal(&priv->ctrl_cond); - return NULL; -} - -/** - * Timeout (miliseconds) for span start/stop completion - */ -#define SPAN_DEFAULT_TIMEOUT_MSEC 10000 - -static FIO_SPAN_START_FUNCTION(misdn_span_start) -{ - struct misdn_span_private *span_priv = ftdm_span_io_private(span); - struct timespec timeout; - int retval; - - ftdm_log(FTDM_LOG_NOTICE, "mISDN starting span %d (%s)\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - span_priv->running = 0; - - if (ftdm_thread_create_detached(misdn_span_run, span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to start span %d (%s)\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - return FTDM_FAIL; - } - - /* - * Wait SPAN_DEFAULT_TIMEOUT_MSEC miliseconds for I/O thread to start up - */ - clock_gettime(CLOCK_REALTIME, &timeout); - ts_add_msec(&timeout, SPAN_DEFAULT_TIMEOUT_MSEC); - - pthread_mutex_lock(&span_priv->ctrl_cond_mutex); - - retval = pthread_cond_timedwait(&span_priv->ctrl_cond, &span_priv->ctrl_cond_mutex, &timeout); - if (retval == ETIMEDOUT) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to start span %d (%s) in 10 seconds\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - return FTDM_FAIL; - } else if (retval) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to start span %d (%s): %s\n", - ftdm_span_get_id(span), ftdm_span_get_name(span), strerror(errno)); - return FTDM_FAIL; - } - - pthread_mutex_unlock(&span_priv->ctrl_cond_mutex); - return FTDM_SUCCESS; -} - -static FIO_SPAN_STOP_FUNCTION(misdn_span_stop) -{ - struct misdn_span_private *span_priv = ftdm_span_io_private(span); - struct timespec timeout; - struct misdn_command cmd; - int retval; - - ftdm_log(FTDM_LOG_NOTICE, "mISDN stopping span %d (%s)\n", - ftdm_span_get_id(span), ftdm_span_get_name(span)); - - span_priv->running = -1; - - /* Wake up thread */ - cmd.type = MISDN_CMD_STOP; - retval = write(span_priv->event_pipe_in, &cmd, sizeof(cmd)); - if (retval < sizeof(cmd)) { - ftdm_log(FTDM_LOG_WARNING, "mISDN failed to send STOP command to span thread\n"); - } - - /* - * Wait SPAN_DEFAULT_TIMEOUT_MSEC miliseconds for I/O thread to shut down - */ - clock_gettime(CLOCK_REALTIME, &timeout); - ts_add_msec(&timeout, SPAN_DEFAULT_TIMEOUT_MSEC); - - pthread_mutex_lock(&span_priv->ctrl_cond_mutex); - - retval = pthread_cond_timedwait(&span_priv->ctrl_cond, &span_priv->ctrl_cond_mutex, &timeout); - if (retval == ETIMEDOUT) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to stop thread in 10 seconds\n"); - return FTDM_FAIL; - } else if (retval) { - ftdm_log(FTDM_LOG_ERROR, "mISDN failed to stop thread: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - - pthread_mutex_unlock(&span_priv->ctrl_cond_mutex); - return FTDM_SUCCESS; -} - - -/** - * \brief ftmod_misdn interface - */ -static const ftdm_io_interface_t misdn_interface = { - .name = "misdn", - - .open = misdn_open, - .close = misdn_close, - .wait = misdn_wait, - .read = misdn_read, - .write = misdn_write, - - .poll_event = misdn_poll_event, - .next_event = misdn_next_event, - - .command = misdn_command, - .get_alarms = misdn_get_alarms, - .configure = misdn_configure, /* configure global parameters */ - .configure_span = misdn_configure_span, /* assign channels to span */ - .channel_next_event = misdn_channel_next_event, - .channel_destroy = misdn_channel_destroy, /* clean up channel */ - .span_destroy = misdn_span_destroy, /* clean up span */ - - .span_start = misdn_span_start, - .span_stop = misdn_span_stop, -}; - - -/** - * \brief ftmod_misdn module init function - */ -static FIO_IO_LOAD_FUNCTION(misdn_load) -{ - struct mISDNversion ver; - struct mISDN_devinfo devinfo; - int devcnt, usecnt; - int i; - - /* */ - globals.sockfd = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE); - if (globals.sockfd < 0) { - ftdm_log(FTDM_LOG_CRIT, "Unable to create mISDN base socket (are you sure this kernel has mISDN support?)\n"); - return FTDM_FAIL; - } - - if (ioctl(globals.sockfd, IMGETVERSION, &ver) < 0) { - ftdm_log(FTDM_LOG_CRIT, "Unable to retrieve mISDN version\n"); - goto error; - } - - ftdm_log(FTDM_LOG_INFO, "mISDN Interface version %hhd.%hhd.%hd\n", ver.major, ver.minor, ver.release); - - devcnt = 0; - if (ioctl(globals.sockfd, IMGETCOUNT, &devcnt) < 0) { - ftdm_log(FTDM_LOG_CRIT, "Unable to retrieve number of mISDN devices\n"); - goto error; - - } - - if (!devcnt) { - ftdm_log(FTDM_LOG_CRIT, "No mISDN devices found\n"); - goto error; - } - usecnt = devcnt; - - ftdm_log(FTDM_LOG_INFO, "Found %d mISDN devices:\n", devcnt); - - /* Output most important device information */ - for (i = 0; i < devcnt; i++) { - int caps = MISDN_CAPS_NONE; - - devinfo.id = i; - if (ioctl(globals.sockfd, IMGETDEVINFO, &devinfo) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve information for device %d\n", i); - continue; - } - - /* print */ - ftdm_log(FTDM_LOG_INFO, "<%d> Name: %s, B-Channels: %d\n", - devinfo.id, - ftdm_strlen_zero_buf(devinfo.name) ? "Unknown" : devinfo.name, - devinfo.nrbchan); - - /* D-Channels capabilities */ - if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) - caps |= MISDN_CAPS_TE | MISDN_CAPS_PRI; - if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) - caps |= MISDN_CAPS_NT | MISDN_CAPS_PRI; - if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) - caps |= MISDN_CAPS_TE | MISDN_CAPS_BRI; - if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) - caps |= MISDN_CAPS_NT | MISDN_CAPS_BRI; -#ifdef ISDN_P_TE_UP0 - if (devinfo.Dprotocols & (1 << ISDN_P_TE_UP0)) - caps |= MISDN_CAPS_TE | MISDN_CAPS_UP0 | MISDN_CAPS_BRI; -#endif -#ifdef ISDN_P_NT_UP0 - if (devinfo.Dprotocols & (1 << ISDN_P_NT_UP0)) - caps |= MISDN_CAPS_NT | MISDN_CAPS_UP0 | MISDN_CAPS_BRI; -#endif - /* B-Channel capabilities */ - if (devinfo.Bprotocols & (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK))) - caps |= MISDN_CAPS_RAW; - if (devinfo.Bprotocols & (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK))) - caps |= MISDN_CAPS_HDLC; - - ftdm_log(FTDM_LOG_INFO, " Type: %s, Modes: %s %s\n", - MISDN_IS_PRI(caps) ? "PRI" : "BRI", - MISDN_IS_NT(caps) ? "NT" : "", - MISDN_IS_TE(caps) ? "TE" : ""); - - ftdm_log(FTDM_LOG_INFO, " B-Channel modes: %s %s\n", - MISDN_IS_RAW(caps) ? "RAW" : "", - MISDN_IS_HDLC(caps) ? "HDLC" : ""); - - if (!(MISDN_IS_NT(caps) || MISDN_IS_TE(caps)) && !MISDN_IS_RAW(caps)) { - ftdm_log(FTDM_LOG_ERROR, " This device is unusable!\n"); - usecnt--; - } - } - if (!usecnt) { - ftdm_log(FTDM_LOG_CRIT, "No useable devices found!\n"); - goto error; - } - - ftdm_log(FTDM_LOG_INFO, "Found %d useable mISDN devices\n", usecnt); - - /* assign interface struct */ - *fio = (ftdm_io_interface_t *)&misdn_interface; - return FTDM_SUCCESS; -error: - if (globals.sockfd >= 0) - close(globals.sockfd); - return FTDM_FAIL; -} - -/** - * \brief ftmod_misdn module shutdown - */ -static FIO_IO_UNLOAD_FUNCTION(misdn_unload) -{ - if (globals.sockfd >= 0) - close(globals.sockfd); - return FTDM_SUCCESS; -} - -/** - * \brief ftmod_misdn module - */ -ftdm_module_t ftdm_module = { - .name = "misdn", - .io_load = misdn_load, - .io_unload = misdn_unload -}; diff --git a/libs/freetdm/src/ftmod/ftmod_pika/ftdm_pika.h b/libs/freetdm/src/ftmod/ftmod_pika/ftdm_pika.h deleted file mode 100644 index 54c550e8e7..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_pika/ftdm_pika.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FTDM_PIKA_H -#define FTDM_PIKA_H -#include "freetdm.h" -#include "pikahmpapi.h" - - - -#define PIKA_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) _TYPE _FUNC1 (const char *name); const char * _FUNC2 (_TYPE type); -#define PIKA_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \ - _TYPE _FUNC1 (const char *name) \ - { \ - int i; \ - _TYPE t = _MAX ; \ - \ - for (i = 0; i < _MAX ; i++) { \ - if (!strcasecmp(name, _STRINGS[i])) { \ - t = (_TYPE) i; \ - break; \ - } \ - } \ - \ - return t; \ - } \ - const char * _FUNC2 (_TYPE type) \ - { \ - if (type > _MAX) { \ - type = _MAX; \ - } \ - return _STRINGS[(int)type]; \ - } - - -typedef enum { - PIKA_SPAN_FRAMING_T1_D4, - PIKA_SPAN_FRAMING_T1_ESF, - PIKA_SPAN_FRAMING_E1_BASIC, - PIKA_SPAN_FRAMING_E1_CRC4, - PIKA_SPAN_INVALID -} PIKA_TSpanFraming; -#define PIKA_SPAN_STRINGS "T1_D4", "T1_ESF", "E1_BASIC", "E1_CRC4" -PIKA_STR2ENUM_P(pika_str2span, pika_span2str, PIKA_TSpanFraming) - -typedef enum { - PIKA_SPAN_ENCODING_T1_AMI_ZS_NONE, - PIKA_SPAN_ENCODING_T1_AMI_ZS_GTE, - PIKA_SPAN_ENCODING_T1_AMI_ZS_BELL, - PIKA_SPAN_ENCODING_T1_AMI_ZS_JAM8, - PIKA_SPAN_ENCODING_T1_B8ZS, - PIKA_SPAN_ENCODING_E1_AMI, - PIKA_SPAN_ENCODING_E1_HDB3, - PIKA_SPAN_ENCODING_INVALID -} PIKA_TSpanEncoding; -#define PIKA_SPAN_ENCODING_STRINGS "T1_AMI_ZS_NONE", "T1_AMI_ZS_GTE", "T1_AMI_ZS_BELL", "T1_AMI_ZS_JAM8", "T1_B8ZS", "E1_AMI", "E1_HDB3" -PIKA_STR2ENUM_P(pika_str2span_encoding, pika_span_encoding2str, PIKA_TSpanEncoding) - -typedef enum { - PIKA_SPAN_LOOP_LENGTH_SHORT_HAUL, - PIKA_SPAN_LOOP_LENGTH_LONG_HAUL, - PIKA_SPAN_LOOP_INVALID -} PIKA_TSpanLoopLength; -#define PIKA_LL_STRINGS "SHORT_HAUL", "LONG_HAUL" -PIKA_STR2ENUM_P(pika_str2loop_length, pika_loop_length2str, PIKA_TSpanLoopLength) - -typedef enum { - PIKA_SPAN_LBO_T1_LONG_0_DB, - PIKA_SPAN_LBO_T1_LONG_7_DB, - PIKA_SPAN_LBO_T1_LONG_15_DB, - PIKA_SPAN_LBO_T1_LONG_22_DB, - PIKA_SPAN_LBO_T1_SHORT_133_FT, - PIKA_SPAN_LBO_T1_SHORT_266_FT, - PIKA_SPAN_LBO_T1_SHORT_399_FT, - PIKA_SPAN_LBO_T1_SHORT_533_FT, - PIKA_SPAN_LBO_T1_SHORT_655_FT, - PIKA_SPAN_LBO_E1_WAVEFORM_120_OHM, - PIKA_SPAN_LBO_INVALID -} PIKA_TSpanBuildOut; -#define PIKA_LBO_STRINGS "T1_LONG_0_DB", "T1_LONG_7_DB", "T1_LONG_15_DB", "T1_LONG_22_DB", "T1_SHORT_133_FT", "T1_SHORT_266_FT", "T1_SHORT_399_FT", "T1_SHORT_533_FT", "T1_SHORT_655_FT", "E1_WAVEFORM_120_OHM" -PIKA_STR2ENUM_P(pika_str2lbo, pika_lbo2str, PIKA_TSpanBuildOut) - -typedef enum { - PIKA_SPAN_COMPAND_MODE_MU_LAW = 1, - PIKA_SPAN_COMPAND_MODE_A_LAW, - PIKA_SPAN_COMPAND_MODE_INVALID -} PIKA_TSpanCompandMode; -#define PIKA_SPAN_COMPAND_MODE_STRINGS "MU_LAW", "A_LAW" -PIKA_STR2ENUM_P(pika_str2compand_mode, pika_compand_mode2str, PIKA_TSpanCompandMode) - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2008.vcproj deleted file mode 100644 index 7ad535ea3f..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2008.vcproj +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2010.vcxproj.filters deleted file mode 100644 index 4d4cec4668..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2010.vcxproj.filters +++ /dev/null @@ -1,23 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.c b/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.c deleted file mode 100644 index fcd5149814..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.c +++ /dev/null @@ -1,1469 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "freetdm.h" -#include "ftdm_pika.h" - - -#define MAX_NUMBER_OF_TRUNKS 64 -#define PIKA_BLOCK_SIZE 160 -#define PIKA_BLOCK_LEN 20 -#define PIKA_NUM_BUFFERS 8 -#define TRY_OR_DIE(__code, __status, __label) if ((status = __code ) != __status) goto __label -#define pk_atof(__a) (PK_FLOAT) atof(__a) - -PK_VOID PK_CALLBACK media_out_callback(PKH_TPikaEvent *event); - -FTDM_ENUM_NAMES(PIKA_SPAN_NAMES, PIKA_SPAN_STRINGS) -PIKA_STR2ENUM(pika_str2span, pika_span2str, PIKA_TSpanFraming, PIKA_SPAN_NAMES, PIKA_SPAN_INVALID) - -FTDM_ENUM_NAMES(PIKA_SPAN_ENCODING_NAMES, PIKA_SPAN_ENCODING_STRINGS) -PIKA_STR2ENUM(pika_str2span_encoding, pika_span_encoding2str, PIKA_TSpanEncoding, PIKA_SPAN_ENCODING_NAMES, PIKA_SPAN_ENCODING_INVALID) - -FTDM_ENUM_NAMES(PIKA_LL_NAMES, PIKA_LL_STRINGS) -PIKA_STR2ENUM(pika_str2loop_length, pika_loop_length2str, PIKA_TSpanLoopLength, PIKA_LL_NAMES, PIKA_SPAN_LOOP_INVALID) - -FTDM_ENUM_NAMES(PIKA_LBO_NAMES, PIKA_LBO_STRINGS) -PIKA_STR2ENUM(pika_str2lbo, pika_lbo2str, PIKA_TSpanBuildOut, PIKA_LBO_NAMES, PIKA_SPAN_LBO_INVALID) - -FTDM_ENUM_NAMES(PIKA_SPAN_COMPAND_MODE_NAMES, PIKA_SPAN_COMPAND_MODE_STRINGS) -PIKA_STR2ENUM(pika_str2compand_mode, pika_compand_mode2str, PIKA_TSpanCompandMode, PIKA_SPAN_COMPAND_MODE_NAMES, PIKA_SPAN_COMPAND_MODE_INVALID) - - -typedef enum { - PK_FLAG_READY = (1 << 0), - PK_FLAG_LOCKED = (1 << 1) -} pk_flag_t; - -struct general_config { - uint32_t region; -}; -typedef struct general_config general_config_t; - -struct pika_channel_profile { - char name[80]; - PKH_TRecordConfig record_config; - PKH_TPlayConfig play_config; - int ec_enabled; - PKH_TECConfig ec_config; - PKH_TSpanConfig span_config; - general_config_t general_config; - int cust_span; -}; -typedef struct pika_channel_profile pika_channel_profile_t; - -static struct { - PKH_TSystemDeviceList board_list; - TPikaHandle open_boards[MAX_NUMBER_OF_TRUNKS]; - TPikaHandle system_handle; - PKH_TSystemConfig system_config; - PKH_TRecordConfig record_config; - PKH_TPlayConfig play_config; - PKH_TECConfig ec_config; - PKH_TSpanConfig t1_span_config; - PKH_TSpanConfig e1_span_config; - ftdm_hash_t *profile_hash; - general_config_t general_config; -} globals; - - -struct pika_span_data { - TPikaHandle event_queue; - PKH_TPikaEvent last_oob_event; - uint32_t boardno; - PKH_TSpanConfig span_config; - TPikaHandle handle; - uint32_t flags; -}; -typedef struct pika_span_data pika_span_data_t; - -struct pika_chan_data { - TPikaHandle handle; - TPikaHandle media_in; - TPikaHandle media_out; - TPikaHandle media_in_queue; - TPikaHandle media_out_queue; - PKH_TPikaEvent last_media_event; - PKH_TPikaEvent last_oob_event; - PKH_TRecordConfig record_config; - PKH_TPlayConfig play_config; - int ec_enabled; - PKH_TECConfig ec_config; - PKH_THDLCConfig hdlc_config; - ftdm_buffer_t *digit_buffer; - ftdm_mutex_t *digit_mutex; - ftdm_size_t dtmf_len; - uint32_t flags; - uint32_t hdlc_bytes; -}; -typedef struct pika_chan_data pika_chan_data_t; - -static const char *pika_board_type_string(PK_UINT type) -{ - if (type == PKH_BOARD_TYPE_DIGITAL_GATEWAY) { - return "digital_gateway"; - } - - if (type == PKH_BOARD_TYPE_ANALOG_GATEWAY) { - return "analog_gateway"; - } - - return "unknown"; -} - -/** - * \brief Process configuration variable for a pika profile - * \param category Pika profile name - * \param var Variable name - * \param val Variable value - * \param lineno Line number from configuration file (unused) - * \return Success - */ -static FIO_CONFIGURE_FUNCTION(pika_configure) -{ - pika_channel_profile_t *profile = NULL; - int ok = 1; - - if (!(profile = (pika_channel_profile_t *) hashtable_search(globals.profile_hash, (char *)category))) { - profile = ftdm_malloc(sizeof(*profile)); - memset(profile, 0, sizeof(*profile)); - ftdm_set_string(profile->name, category); - profile->ec_config = globals.ec_config; - profile->record_config = globals.record_config; - profile->play_config = globals.play_config; - hashtable_insert(globals.profile_hash, (void *)profile->name, profile, HASHTABLE_FLAG_NONE); - ftdm_log(FTDM_LOG_INFO, "creating profile [%s]\n", category); - } - - if (!strcasecmp(var, "rx-gain")) { - profile->record_config.gain = pk_atof(val); - } else if (!strcasecmp(var, "rx-agc-enabled")) { - profile->record_config.AGC.enabled = ftdm_true(val); - } else if (!strcasecmp(var, "rx-agc-targetPower")) { - profile->record_config.AGC.targetPower = pk_atof(val); - } else if (!strcasecmp(var, "rx-agc-minGain")) { - profile->record_config.AGC.minGain = pk_atof(val); - } else if (!strcasecmp(var, "rx-agc-maxGain")) { - profile->record_config.AGC.maxGain = pk_atof(val); - } else if (!strcasecmp(var, "rx-agc-attackRate")) { - profile->record_config.AGC.attackRate = atoi(val); - } else if (!strcasecmp(var, "rx-agc-decayRate")) { - profile->record_config.AGC.decayRate = atoi(val); - } else if (!strcasecmp(var, "rx-agc-speechThreshold")) { - profile->record_config.AGC.speechThreshold = pk_atof(val); - } else if (!strcasecmp(var, "rx-vad-enabled")) { - profile->record_config.VAD.enabled = ftdm_true(val); - } else if (!strcasecmp(var, "rx-vad-activationThreshold")) { - profile->record_config.VAD.activationThreshold = pk_atof(val); - } else if (!strcasecmp(var, "rx-vad-activationDebounceTime")) { - profile->record_config.VAD.activationDebounceTime = atoi(val); - } else if (!strcasecmp(var, "rx-vad-deactivationThreshold")) { - profile->record_config.VAD.deactivationThreshold = pk_atof(val); - } else if (!strcasecmp(var, "rx-vad-deactivationDebounceTime")) { - profile->record_config.VAD.deactivationDebounceTime = atoi(val); - } else if (!strcasecmp(var, "rx-vad-preSpeechBufferSize")) { - profile->record_config.VAD.preSpeechBufferSize = atoi(val); - } else if (!strcasecmp(var, "tx-gain")) { - profile->play_config.gain = pk_atof(val); - } else if (!strcasecmp(var, "tx-agc-enabled")) { - profile->play_config.AGC.enabled = ftdm_true(val); - } else if (!strcasecmp(var, "tx-agc-targetPower")) { - profile->play_config.AGC.targetPower = pk_atof(val); - } else if (!strcasecmp(var, "tx-agc-minGain")) { - profile->play_config.AGC.minGain = pk_atof(val); - } else if (!strcasecmp(var, "tx-agc-maxGain")) { - profile->play_config.AGC.maxGain = pk_atof(val); - } else if (!strcasecmp(var, "tx-agc-attackRate")) { - profile->play_config.AGC.attackRate = atoi(val); - } else if (!strcasecmp(var, "tx-agc-decayRate")) { - profile->play_config.AGC.decayRate = atoi(val); - } else if (!strcasecmp(var, "tx-agc-speechThreshold")) { - profile->play_config.AGC.speechThreshold = pk_atof(val); - } else if (!strcasecmp(var, "ec-enabled")) { - profile->ec_enabled = ftdm_true(val); - } else if (!strcasecmp(var, "ec-doubleTalkerThreshold")) { - profile->ec_config.doubleTalkerThreshold = pk_atof(val); - } else if (!strcasecmp(var, "ec-speechPresentThreshold")) { - profile->ec_config.speechPresentThreshold = pk_atof(val); - } else if (!strcasecmp(var, "ec-echoSuppressionThreshold")) { - profile->ec_config.echoSuppressionThreshold = pk_atof(val); - } else if (!strcasecmp(var, "ec-echoSuppressionEnabled")) { - profile->ec_config.echoSuppressionEnabled = ftdm_true(val); - } else if (!strcasecmp(var, "ec-comfortNoiseEnabled")) { - profile->ec_config.comfortNoiseEnabled = ftdm_true(val); - } else if (!strcasecmp(var, "ec-adaptationModeEnabled")) { - profile->ec_config.adaptationModeEnabled = ftdm_true(val); - } else if (!strcasecmp(var, "framing")) { - profile->span_config.framing = pika_str2span(val); - profile->cust_span++; - } else if (!strcasecmp(var, "encoding")) { - profile->span_config.encoding = pika_str2span_encoding(val); - profile->cust_span++; - } else if (!strcasecmp(var, "loopLength")) { - profile->span_config.loopLength = pika_str2loop_length(val); - profile->cust_span++; - } else if (!strcasecmp(var, "buildOut")) { - profile->span_config.buildOut = pika_str2lbo(val); - profile->cust_span++; - } else if (!strcasecmp(var, "compandMode")) { - profile->span_config.compandMode = pika_str2compand_mode(val); - profile->cust_span++; - } else if (!strcasecmp(var, "region")) { - if (!strcasecmp(val, "eu")) { - profile->general_config.region = PKH_TRUNK_EU; - } else { - profile->general_config.region = PKH_TRUNK_NA; - } - } else { - ok = 0; - } - - if (ok) { - ftdm_log(FTDM_LOG_INFO, "setting param [%s]=[%s] for profile [%s]\n", var, val, category); - } else { - ftdm_log(FTDM_LOG_ERROR, "unknown param [%s]\n", var); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Pika event handler - * \param event Pika event - */ -PK_VOID PK_CALLBACK media_out_callback(PKH_TPikaEvent *event) -{ - PK_STATUS pk_status; - ftdm_channel_t *ftdmchan = event->userData; - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - - //PK_CHAR event_text[PKH_EVENT_MAX_NAME_LENGTH]; - //PKH_EVENT_GetText(event->id, event_text, sizeof(event_text)); - //ftdm_log(FTDM_LOG_DEBUG, "Event: %s\n", event_text); - - switch (event->id) { - case PKH_EVENT_PLAY_IDLE: - { - while (ftdm_buffer_inuse(chan_data->digit_buffer)) { - char dtmf[128] = ""; - ftdm_mutex_lock(chan_data->digit_mutex); - chan_data->dtmf_len = ftdm_buffer_read(chan_data->digit_buffer, dtmf, sizeof(dtmf)); - pk_status = PKH_TG_PlayDTMF(chan_data->media_out, dtmf); - ftdm_mutex_unlock(chan_data->digit_mutex); - } - } - break; - case PKH_EVENT_TG_TONE_PLAYED: - { - - if (!event->p1) { - ftdm_mutex_lock(chan_data->digit_mutex); - PKH_PLAY_Start(chan_data->media_out); - chan_data->dtmf_len = 0; - ftdm_mutex_unlock(chan_data->digit_mutex); - } - - - } - break; - default: - break; - } - -} - -/** - * \brief Initialises a range of pika channels - * \param span FreeTDM span - * \param boardno Pika board number - * \param spanno Pika span number - * \param start Initial pika channel number - * \param end Final pika channel number - * \param type FreeTDM channel type - * \param name FreeTDM span name - * \param number FreeTDM span number - * \param profile Pika channel profile - * \return number of spans configured - */ -static unsigned pika_open_range(ftdm_span_t *span, unsigned boardno, unsigned spanno, unsigned start, unsigned end, - ftdm_chan_type_t type, char *name, char *number, pika_channel_profile_t *profile) -{ - unsigned configured = 0, x; - PK_STATUS status; - PK_CHAR error_text[PKH_ERROR_MAX_NAME_LENGTH]; - pika_span_data_t *span_data; - - if (boardno >= globals.board_list.numberOfBoards) { - ftdm_log(FTDM_LOG_ERROR, "Board %u is not present!\n", boardno); - return 0; - } - - if (!globals.open_boards[boardno]) { - status = PKH_BOARD_Open(globals.board_list.board[boardno].id, - NULL, - &globals.open_boards[boardno]); - if(status != PK_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error: PKH_BOARD_Open %d failed(%s)!\n", boardno, - PKH_ERROR_GetText(status, error_text, sizeof(error_text))); - return 0; - } - - ftdm_log(FTDM_LOG_DEBUG, "Open board %u\n", boardno); - - //PKH_BOARD_SetDebugTrace(globals.open_boards[boardno], 1, 0); - - } - - if (span->io_data) { - span_data = span->io_data; - } else { - span_data = ftdm_malloc(sizeof(*span_data)); - assert(span_data != NULL); - memset(span_data, 0, sizeof(*span_data)); - span_data->boardno = boardno; - - status = PKH_QUEUE_Create(PKH_QUEUE_TYPE_NORMAL, &span_data->event_queue); - - if (status != PK_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error: PKH_QUEUE_Create failed(%s)!\n", - PKH_ERROR_GetText(status, error_text, sizeof(error_text))); - ftdm_safe_free(span_data); - return 0; - } - - //PKH_QUEUE_Attach(span_data->event_queue, globals.open_boards[boardno], NULL); - - span->io_data = span_data; - } - - if (type == FTDM_CHAN_TYPE_FXS || type == FTDM_CHAN_TYPE_FXO) { - start--; - end--; - } - - for(x = start; x < end; x++) { - ftdm_channel_t *chan; - pika_chan_data_t *chan_data = NULL; - - chan_data = ftdm_malloc(sizeof *chan_data); - assert(chan_data); - memset(chan_data, 0, sizeof(*chan_data)); - ftdm_span_add_channel(span, 0, type, &chan); - chan->io_data = chan_data; - - if ((type == FTDM_CHAN_TYPE_B || type == FTDM_CHAN_TYPE_DQ921) && !span_data->handle) { - PKH_TBoardConfig boardConfig; - - TRY_OR_DIE(PKH_BOARD_GetConfig(globals.open_boards[boardno], &boardConfig), PK_SUCCESS, error); - if ((profile && profile->general_config.region == PKH_TRUNK_EU) || ftdm_test_flag(span_data, PK_FLAG_LOCKED)) { - if (span->trunk_type == FTDM_TRUNK_T1) { - ftdm_log(FTDM_LOG_WARNING, "Changing trunk type to E1 based on previous config.\n"); - } - span->trunk_type = FTDM_TRUNK_E1; - } - - if (span->trunk_type == FTDM_TRUNK_T1) { - if (ftdm_test_flag(span_data, PK_FLAG_LOCKED)) { - ftdm_log(FTDM_LOG_WARNING, "Already locked into E1 mode!\n"); - } - } else if (span->trunk_type == FTDM_TRUNK_E1) { - boardConfig.specific.DigitalGateway.interfaceType = PKH_BOARD_INTERFACE_TYPE_E1; - if ((status = PKH_BOARD_SetConfig(globals.open_boards[boardno], &boardConfig)) != PK_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error: [%s]\n", - PKH_ERROR_GetText(status, error_text, sizeof(error_text))); - } - ftdm_set_flag(span_data, PK_FLAG_LOCKED); - } - - TRY_OR_DIE(PKH_SPAN_Open(globals.open_boards[boardno], spanno, NULL, &span_data->handle), PK_SUCCESS, error); - TRY_OR_DIE(PKH_SPAN_GetConfig(span_data->handle, &span_data->span_config), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(span_data->event_queue, span_data->handle, (PK_VOID*) span), PK_SUCCESS, error); - } - - if (type == FTDM_CHAN_TYPE_FXO) { - PKH_TTrunkConfig trunkConfig; - - TRY_OR_DIE(PKH_TRUNK_Open(globals.open_boards[boardno], x, &chan_data->handle), PK_SUCCESS, error); - TRY_OR_DIE(PKH_TRUNK_Seize(chan_data->handle), PK_SUCCESS, error); - - if (profile && profile->general_config.region == PKH_TRUNK_EU) { - TRY_OR_DIE(PKH_TRUNK_GetConfig(chan_data->handle, &trunkConfig), PK_SUCCESS, error); - trunkConfig.internationalControl = PKH_PHONE_INTERNATIONAL_CONTROL_EU; - trunkConfig.audioFormat = PKH_AUDIO_ALAW; - trunkConfig.compandMode = PKH_PHONE_AUDIO_ALAW; - chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW; - TRY_OR_DIE(PKH_TRUNK_SetConfig(chan_data->handle, &trunkConfig), PK_SUCCESS, error); - } else { - chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW; - } - - - TRY_OR_DIE(PKH_QUEUE_Attach(span_data->event_queue, chan_data->handle, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_TRUNK_GetMediaStreams(chan_data->handle, &chan_data->media_in, &chan_data->media_out), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Create(PKH_QUEUE_TYPE_NORMAL, &chan_data->media_in_queue), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(chan_data->media_in_queue, chan_data->media_in, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Create(PKH_QUEUE_TYPE_CALLBACK, &chan_data->media_out_queue), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_SetEventHandler(chan_data->media_out_queue, media_out_callback), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(chan_data->media_out_queue, chan_data->media_out, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_TRUNK_Start(chan_data->handle), PK_SUCCESS, error); - } else if (type == FTDM_CHAN_TYPE_FXS) { - PKH_TPhoneConfig phoneConfig; - - if (profile && profile->general_config.region == PKH_TRUNK_EU) { - TRY_OR_DIE(PKH_PHONE_GetConfig(chan_data->handle, &phoneConfig), PK_SUCCESS, error); - phoneConfig.internationalControl = PKH_PHONE_INTERNATIONAL_CONTROL_EU; - phoneConfig.compandMode = PKH_PHONE_AUDIO_ALAW; - chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW; - TRY_OR_DIE(PKH_PHONE_SetConfig(chan_data->handle, &phoneConfig), PK_SUCCESS, error); - } else { - chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW; - } - - TRY_OR_DIE(PKH_PHONE_Open(globals.open_boards[boardno], x, &chan_data->handle), PK_SUCCESS, error); - TRY_OR_DIE(PKH_PHONE_Seize(chan_data->handle), PK_SUCCESS, error); - TRY_OR_DIE(PKH_PHONE_GetMediaStreams(chan_data->handle, &chan_data->media_in, &chan_data->media_out), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(span_data->event_queue, chan_data->handle, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Create(PKH_QUEUE_TYPE_NORMAL, &chan_data->media_in_queue), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(chan_data->media_in_queue, chan_data->media_in, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Create(PKH_QUEUE_TYPE_CALLBACK, &chan_data->media_out_queue), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_SetEventHandler(chan_data->media_out_queue, media_out_callback), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(chan_data->media_out_queue, chan_data->media_out, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_PHONE_Start(chan_data->handle), PK_SUCCESS, error); - } else if (type == FTDM_CHAN_TYPE_B) { - TRY_OR_DIE(PKH_SPAN_SeizeChannel(span_data->handle, x), PK_SUCCESS, error); - TRY_OR_DIE(PKH_SPAN_GetMediaStreams(span_data->handle, x, &chan_data->media_in, &chan_data->media_out), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Create(PKH_QUEUE_TYPE_NORMAL, &chan_data->media_in_queue), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(chan_data->media_in_queue, chan_data->media_in, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Create(PKH_QUEUE_TYPE_CALLBACK, &chan_data->media_out_queue), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_SetEventHandler(chan_data->media_out_queue, media_out_callback), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(chan_data->media_out_queue, chan_data->media_out, (PK_VOID*) chan), PK_SUCCESS, error); - } else if (type == FTDM_CHAN_TYPE_DQ921) { - TRY_OR_DIE(PKH_SPAN_HDLC_Open(span_data->handle, PKH_SPAN_HDLC_MODE_NORMAL, &chan_data->handle), PK_SUCCESS, error); - TRY_OR_DIE(PKH_SPAN_HDLC_GetConfig(chan_data->handle, &chan_data->hdlc_config), PK_SUCCESS, error); - chan_data->hdlc_config.channelId = x; - TRY_OR_DIE(PKH_SPAN_HDLC_SetConfig(chan_data->handle, &chan_data->hdlc_config), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Create(PKH_QUEUE_TYPE_NORMAL, &chan_data->media_in_queue), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(chan_data->media_in_queue, chan_data->handle, (PK_VOID*) chan), PK_SUCCESS, error); - TRY_OR_DIE(PKH_QUEUE_Attach(span_data->event_queue, chan_data->handle, (PK_VOID*) chan), PK_SUCCESS, error); - - if (profile) { - if (profile->cust_span) { - span_data->span_config.framing = profile->span_config.framing; - span_data->span_config.encoding = profile->span_config.encoding; - span_data->span_config.loopLength = profile->span_config.loopLength; - span_data->span_config.buildOut = profile->span_config.buildOut; - span_data->span_config.compandMode = profile->span_config.compandMode; - } else { - if (profile->general_config.region == PKH_TRUNK_EU) { - span_data->span_config = globals.e1_span_config; - } else { - span_data->span_config = globals.t1_span_config; - } - } - } else { - if (span->trunk_type == FTDM_TRUNK_E1) { - span_data->span_config = globals.e1_span_config; - } else { - span_data->span_config = globals.t1_span_config; - } - } - - PKH_SPAN_SetConfig(span_data->handle, &span_data->span_config); - TRY_OR_DIE(PKH_SPAN_Start(span_data->handle), PK_SUCCESS, error); - } - - goto ok; - - error: - PKH_ERROR_GetText(status, error_text, sizeof(error_text)); - ftdm_log(FTDM_LOG_ERROR, "failure configuring device b%ds%dc%d [%s]\n", boardno, spanno, x, error_text); - continue; - ok: - ftdm_set_flag(chan_data, PK_FLAG_READY); - status = PKH_RECORD_GetConfig(chan_data->media_in, &chan_data->record_config); - chan_data->record_config.encoding = PKH_RECORD_ENCODING_MU_LAW; - chan_data->record_config.samplingRate = PKH_RECORD_SAMPLING_RATE_8KHZ; - chan_data->record_config.bufferSize = PIKA_BLOCK_SIZE; - chan_data->record_config.numberOfBuffers = PIKA_NUM_BUFFERS; - chan_data->record_config.VAD.enabled = PK_FALSE; - //chan_data->record_config.speechSegmentEventsEnabled = PK_FALSE; - //chan_data->record_config.gain = rxgain; - - status = PKH_PLAY_GetConfig(chan_data->media_out, &chan_data->play_config); - chan_data->play_config.encoding = PKH_RECORD_ENCODING_MU_LAW; - chan_data->play_config.samplingRate = PKH_RECORD_SAMPLING_RATE_8KHZ; - chan_data->play_config.AGC.enabled = PK_FALSE; - ftdm_log(FTDM_LOG_INFO, "configuring device b%ds%dc%d as FreeTDM device %d:%d\n", boardno, spanno, x, chan->span_id, chan->chan_id); - - if (profile) { - ftdm_log(FTDM_LOG_INFO, "applying config profile %s to device %d:%d\n", profile->name, chan->span_id, chan->chan_id); - chan_data->record_config.gain = profile->record_config.gain; - chan_data->record_config.AGC = profile->record_config.AGC; - chan_data->record_config.VAD = profile->record_config.VAD; - chan_data->play_config.gain = profile->play_config.gain; - chan_data->play_config.AGC = profile->play_config.AGC; - chan_data->ec_enabled = profile->ec_enabled; - chan_data->ec_config = profile->ec_config; - } - - if (type == FTDM_CHAN_TYPE_B) { - if (span_data->span_config.compandMode == PKH_SPAN_COMPAND_MODE_A_LAW) { - chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW; - } else { - chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW; - } - } - - status = PKH_RECORD_SetConfig(chan_data->media_in, &chan_data->record_config); - status = PKH_PLAY_SetConfig(chan_data->media_out, &chan_data->play_config); - - chan->physical_span_id = spanno; - chan->physical_chan_id = x; - - chan->rate = 8000; - chan->packet_len = (uint32_t)chan_data->record_config.bufferSize; - chan->effective_interval = chan->native_interval = chan->packet_len / 8; - - PKH_RECORD_Start(chan_data->media_in); - PKH_PLAY_Start(chan_data->media_out); - if (chan_data->ec_enabled) { - PKH_EC_SetConfig(chan_data->media_in, &chan_data->ec_config); - PKH_EC_Start(chan_data->media_in, chan_data->media_in, chan_data->media_out); - } - - if (!ftdm_strlen_zero(name)) { - ftdm_copy_string(chan->chan_name, name, sizeof(chan->chan_name)); - } - - if (!ftdm_strlen_zero(number)) { - ftdm_copy_string(chan->chan_number, number, sizeof(chan->chan_number)); - } - - ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE); - ftdm_buffer_create(&chan_data->digit_buffer, 128, 128, 0); - ftdm_mutex_create(&chan_data->digit_mutex); - - configured++; - } - - - return configured; -} - -/** - * \brief Initialises an freetdm pika span from a configuration string - * \param span FreeTDM span - * \param str Configuration string - * \param type FreeTDM span type - * \param name FreeTDM span name - * \param number FreeTDM span number - * \return Success or failure - */ -static FIO_CONFIGURE_SPAN_FUNCTION(pika_configure_span) -{ - int items, i; - char *mydata, *item_list[10]; - char *bd, *sp, *ch = NULL, *mx; - int boardno; - int channo; - int spanno; - int top = 0; - unsigned configured = 0; - char *profile_name = NULL; - pika_channel_profile_t *profile = NULL; - - assert(str != NULL); - - mydata = ftdm_strdup(str); - assert(mydata != NULL); - - if ((profile_name = strchr(mydata, '@'))) { - *profile_name++ = '\0'; - if (!ftdm_strlen_zero(profile_name)) { - profile = (pika_channel_profile_t *) hashtable_search(globals.profile_hash, (char *)profile_name); - } - } - - items = ftdm_separate_string(mydata, ',', item_list, (sizeof(item_list) / sizeof(item_list[0]))); - - for(i = 0; i < items; i++) { - bd = item_list[i]; - if ((sp = strchr(bd, ':'))) { - *sp++ = '\0'; - if ((ch = strchr(sp, ':'))) { - *ch++ = '\0'; - } - } - - if (!(bd && sp && ch)) { - ftdm_log(FTDM_LOG_ERROR, "Invalid input\n"); - continue; - } - - boardno = atoi(bd); - channo = atoi(ch); - spanno = atoi(sp); - - - if (boardno < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid board number %d\n", boardno); - continue; - } - - if (channo < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid channel number %d\n", channo); - continue; - } - - if (spanno < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid span number %d\n", channo); - continue; - } - - if ((mx = strchr(ch, '-'))) { - mx++; - top = atoi(mx) + 1; - } else { - top = channo + 1; - } - - - if (top < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid range number %d\n", top); - continue; - } - - configured += pika_open_range(span, boardno, spanno, channo, top, type, name, number, profile); - - } - - ftdm_safe_free(mydata); - - return configured; -} - -/** - * \brief Opens Pika channel - * \param ftdmchan Channel to open - * \return Success or failure - */ -static FIO_OPEN_FUNCTION(pika_open) -{ - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - - if (!chan_data && !ftdm_test_flag(chan_data, PK_FLAG_READY)) { - return FTDM_FAIL; - } - - if (chan_data->media_in_queue) { - PKH_QUEUE_Flush(chan_data->media_in_queue); - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_FXS || ftdmchan->type == FTDM_CHAN_TYPE_FXO || ftdmchan->type == FTDM_CHAN_TYPE_B) { - PKH_PLAY_Start(chan_data->media_out); - } - return FTDM_SUCCESS; -} - -/** - * \brief Closes Pika channel - * \param ftdmchan Channel to close - * \return Success - */ -static FIO_CLOSE_FUNCTION(pika_close) -{ - return FTDM_SUCCESS; -} - -/** - * \brief Waits for an event on a Pika channel - * \param ftdmchan Channel to open - * \param flags Type of event to wait for - * \param to Time to wait (in ms) - * \return Success, failure or timeout - */ -static FIO_WAIT_FUNCTION(pika_wait) -{ - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - PK_STATUS status; - ftdm_wait_flag_t myflags = *flags; - PK_CHAR event_text[PKH_EVENT_MAX_NAME_LENGTH]; - - *flags = FTDM_NO_FLAGS; - - if (myflags & FTDM_READ) { - if (chan_data->hdlc_bytes) { - *flags |= FTDM_READ; - return FTDM_SUCCESS; - } - status = PKH_QUEUE_WaitOnEvent(chan_data->media_in_queue, to, &chan_data->last_media_event); - - if (status == PK_SUCCESS) { - if (chan_data->last_media_event.id == PKH_EVENT_QUEUE_TIMEOUT || chan_data->last_media_event.id == PKH_EVENT_RECORD_BUFFER_OVERFLOW) { - return FTDM_TIMEOUT; - } - - *flags |= FTDM_READ; - return FTDM_SUCCESS; - } - - PKH_EVENT_GetText(chan_data->last_media_event.id, event_text, sizeof(event_text)); - ftdm_log(FTDM_LOG_DEBUG, "Event: %s\n", event_text); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Reads data from a Pika channel - * \param ftdmchan Channel to read from - * \param data Data buffer - * \param datalen Size of data buffer - * \return Success or failure - */ -static FIO_READ_FUNCTION(pika_read) -{ - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - PK_STATUS status; - PK_CHAR event_text[PKH_EVENT_MAX_NAME_LENGTH]; - uint32_t len; - - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - if ((status = PKH_SPAN_HDLC_GetMessage(chan_data->handle, data, *datalen)) == PK_SUCCESS) { - *datalen = chan_data->hdlc_bytes; - chan_data->hdlc_bytes = 0; - return FTDM_SUCCESS; - } - return FTDM_FAIL; - } - - if (!(len = chan_data->last_media_event.p0)) { - len = ftdmchan->packet_len; - } - - if (len < *datalen) { - *datalen = len; - } - - if ((status = PKH_RECORD_GetData(chan_data->media_in, data, *datalen)) == PK_SUCCESS) { - return FTDM_SUCCESS; - } - - - PKH_ERROR_GetText(status, event_text, sizeof(event_text)); - ftdm_log(FTDM_LOG_DEBUG, "ERR: %s\n", event_text); - return FTDM_FAIL; -} - -/** - * \brief Writes data to a Pika channel - * \param ftdmchan Channel to write to - * \param data Data buffer - * \param datalen Size of data buffer - * \return Success or failure - */ -static FIO_WRITE_FUNCTION(pika_write) -{ - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - PK_STATUS status; - - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - if ((status = PKH_SPAN_HDLC_SendMessage(chan_data->handle, data, *datalen)) == PK_SUCCESS) { - return FTDM_SUCCESS; - } - return FTDM_FAIL; - } - - if (PKH_PLAY_AddData(chan_data->media_out, 0, data, *datalen) == PK_SUCCESS) { - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -/** - * \brief Executes an FreeTDM command on a Pika channel - * \param ftdmchan Channel to execute command on - * \param command FreeTDM command to execute - * \param obj Object (unused) - * \return Success or failure - */ -static FIO_COMMAND_FUNCTION(pika_command) -{ - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - //pika_span_data_t *span_data = (pika_span_data_t *) ftdmchan->span->io_data; - PK_STATUS pk_status; - ftdm_status_t status = FTDM_SUCCESS; - - switch(command) { - case FTDM_COMMAND_OFFHOOK: - { - if ((pk_status = PKH_TRUNK_SetHookSwitch(chan_data->handle, PKH_TRUNK_OFFHOOK)) != PK_SUCCESS) { - PKH_ERROR_GetText(pk_status, ftdmchan->last_error, sizeof(ftdmchan->last_error)); - GOTO_STATUS(done, FTDM_FAIL); - } else { - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); - } - } - break; - case FTDM_COMMAND_ONHOOK: - { - if ((pk_status = PKH_TRUNK_SetHookSwitch(chan_data->handle, PKH_TRUNK_ONHOOK)) != PK_SUCCESS) { - PKH_ERROR_GetText(pk_status, ftdmchan->last_error, sizeof(ftdmchan->last_error)); - GOTO_STATUS(done, FTDM_FAIL); - } else { - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); - } - } - break; - case FTDM_COMMAND_GENERATE_RING_ON: - { - if ((pk_status = PKH_PHONE_RingStart(chan_data->handle, 0, 0)) != PK_SUCCESS) { - PKH_ERROR_GetText(pk_status, ftdmchan->last_error, sizeof(ftdmchan->last_error)); - GOTO_STATUS(done, FTDM_FAIL); - } else { - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING); - } - } - break; - case FTDM_COMMAND_GENERATE_RING_OFF: - { - if ((pk_status = PKH_PHONE_RingStop(chan_data->handle)) != PK_SUCCESS) { - PKH_ERROR_GetText(pk_status, ftdmchan->last_error, sizeof(ftdmchan->last_error)); - GOTO_STATUS(done, FTDM_FAIL); - } else { - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING); - } - } - break; - case FTDM_COMMAND_GET_INTERVAL: - { - - FTDM_COMMAND_OBJ_INT = ftdmchan->native_interval; - - } - break; - case FTDM_COMMAND_SET_INTERVAL: - { - int interval = FTDM_COMMAND_OBJ_INT; - int len = interval * 8; - chan_data->record_config.bufferSize = len; - chan_data->record_config.numberOfBuffers = (PK_UINT)chan_data->record_config.bufferSize; - ftdmchan->packet_len = (uint32_t)chan_data->record_config.bufferSize; - ftdmchan->effective_interval = ftdmchan->native_interval = ftdmchan->packet_len / 8; - PKH_RECORD_SetConfig(chan_data->media_in, &chan_data->record_config); - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - case FTDM_COMMAND_GET_DTMF_ON_PERIOD: - { - - FTDM_COMMAND_OBJ_INT = ftdmchan->dtmf_on; - GOTO_STATUS(done, FTDM_SUCCESS); - - } - break; - case FTDM_COMMAND_GET_DTMF_OFF_PERIOD: - { - FTDM_COMMAND_OBJ_INT = ftdmchan->dtmf_on; - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - case FTDM_COMMAND_SET_DTMF_ON_PERIOD: - { - int val = FTDM_COMMAND_OBJ_INT; - if (val > 10 && val < 1000) { - ftdmchan->dtmf_on = val; - GOTO_STATUS(done, FTDM_SUCCESS); - } else { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "invalid value %d range 10-1000", val); - GOTO_STATUS(done, FTDM_FAIL); - } - } - break; - case FTDM_COMMAND_SET_DTMF_OFF_PERIOD: - { - int val = FTDM_COMMAND_OBJ_INT; - if (val > 10 && val < 1000) { - ftdmchan->dtmf_off = val; - GOTO_STATUS(done, FTDM_SUCCESS); - } else { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "invalid value %d range 10-1000", val); - GOTO_STATUS(done, FTDM_FAIL); - } - } - break; - case FTDM_COMMAND_SEND_DTMF: - { - char *digits = FTDM_COMMAND_OBJ_CHAR_P; - ftdm_log(FTDM_LOG_DEBUG, "Adding DTMF SEQ [%s]\n", digits); - ftdm_mutex_lock(chan_data->digit_mutex); - ftdm_buffer_write(chan_data->digit_buffer, digits, strlen(digits)); - ftdm_mutex_unlock(chan_data->digit_mutex); - pk_status = PKH_PLAY_Stop(chan_data->media_out); - - if (pk_status != PK_SUCCESS) { - PKH_ERROR_GetText(pk_status, ftdmchan->last_error, sizeof(ftdmchan->last_error)); - GOTO_STATUS(done, FTDM_FAIL); - } - GOTO_STATUS(done, FTDM_SUCCESS); - } - break; - default: - break; - }; - - done: - return status; -} - -/** - * \brief Checks for events on a Pika span - * \param span Span to check for events - * \param ms Time to wait for event - * \return Success if event is waiting or failure if not - */ -static FIO_SPAN_POLL_EVENT_FUNCTION(pika_poll_event) -{ - pika_span_data_t *span_data = (pika_span_data_t *) span->io_data; - PK_STATUS status; - PK_CHAR event_text[PKH_EVENT_MAX_NAME_LENGTH]; - - status = PKH_QUEUE_WaitOnEvent(span_data->event_queue, ms, &span_data->last_oob_event); - - if (status == PK_SUCCESS) { - ftdm_channel_t *ftdmchan = NULL; - uint32_t *data = (uint32_t *) span_data->last_oob_event.userData; - ftdm_data_type_t data_type = FTDM_TYPE_NONE; - - if (span_data->last_oob_event.id == PKH_EVENT_QUEUE_TIMEOUT) { - return FTDM_TIMEOUT; - } - - if (data) { - data_type = *data; - } - - if (data_type == FTDM_TYPE_CHANNEL) { - ftdmchan = span_data->last_oob_event.userData; - } else if (data_type == FTDM_TYPE_SPAN) { - ftdm_time_t last_event_time = ftdm_current_time_in_ms(); - uint32_t event_id = 0; - - switch (span_data->last_oob_event.id) { - case PKH_EVENT_SPAN_ALARM_T1_RED: - case PKH_EVENT_SPAN_ALARM_T1_YELLOW: - case PKH_EVENT_SPAN_ALARM_T1_AIS: - case PKH_EVENT_SPAN_ALARM_E1_RED: - case PKH_EVENT_SPAN_ALARM_E1_RAI: - case PKH_EVENT_SPAN_ALARM_E1_AIS: - case PKH_EVENT_SPAN_ALARM_E1_RMAI: - case PKH_EVENT_SPAN_ALARM_E1_TS16AIS: - case PKH_EVENT_SPAN_ALARM_E1_TS16LOS: - case PKH_EVENT_SPAN_OUT_OF_SYNC: - case PKH_EVENT_SPAN_FRAMING_ERROR: - case PKH_EVENT_SPAN_LOSS_OF_SIGNAL: - case PKH_EVENT_SPAN_OUT_OF_CRC_MF_SYNC: - case PKH_EVENT_SPAN_OUT_OF_CAS_MF_SYNC: - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_T1_RED_CLEAR: - case PKH_EVENT_SPAN_ALARM_T1_YELLOW_CLEAR: - case PKH_EVENT_SPAN_ALARM_T1_AIS_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_RED_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_RAI_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_AIS_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_RMAI_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_TS16AIS_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_TS16LOS_CLEAR: - case PKH_EVENT_SPAN_IN_SYNC: - case PKH_EVENT_SPAN_LOSS_OF_SIGNAL_CLEAR: - case PKH_EVENT_SPAN_IN_CRC_MF_SYNC: - case PKH_EVENT_SPAN_IN_CAS_MF_SYNC: - event_id = FTDM_OOB_ALARM_CLEAR; - break; - case PKH_EVENT_SPAN_MESSAGE: - case PKH_EVENT_SPAN_ABCD_SIGNAL_CHANGE: - break; - } - - if (event_id) { - uint32_t x = 0; - ftdm_channel_t *ftdmchan; - pika_chan_data_t *chan_data; - for(x = 1; x <= span->chan_count; x++) { - ftdmchan = span->channels[x]; - assert(ftdmchan != NULL); - chan_data = (pika_chan_data_t *) ftdmchan->io_data; - assert(chan_data != NULL); - - - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_EVENT); - ftdmchan->last_event_time = last_event_time; - chan_data->last_oob_event = span_data->last_oob_event; - } - - } - - } - - PKH_EVENT_GetText(span_data->last_oob_event.id, event_text, sizeof(event_text)); - //ftdm_log(FTDM_LOG_DEBUG, "Event: %s\n", event_text); - - if (ftdmchan) { - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - - assert(chan_data != NULL); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_EVENT); - ftdmchan->last_event_time = ftdm_current_time_in_ms(); - chan_data->last_oob_event = span_data->last_oob_event; - } - - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -/** - * \brief Retrieves an event from a Pika span - * \param span Span to retrieve event from - * \param event FreeTDM event to return - * \return Success or failure - */ -static FIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event) -{ - uint32_t i, event_id = 0; - - for(i = 1; i <= span->chan_count; i++) { - if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_EVENT)) { - pika_chan_data_t *chan_data = (pika_chan_data_t *) span->channels[i]->io_data; - PK_CHAR event_text[PKH_EVENT_MAX_NAME_LENGTH]; - - ftdm_clear_flag(span->channels[i], FTDM_CHANNEL_EVENT); - - PKH_EVENT_GetText(chan_data->last_oob_event.id, event_text, sizeof(event_text)); - - switch(chan_data->last_oob_event.id) { - case PKH_EVENT_HDLC_MESSAGE: - chan_data->hdlc_bytes = chan_data->last_oob_event.p2; - continue; - case PKH_EVENT_TRUNK_HOOKFLASH: - event_id = FTDM_OOB_FLASH; - break; - case PKH_EVENT_TRUNK_RING_OFF: - event_id = FTDM_OOB_RING_STOP; - break; - case PKH_EVENT_TRUNK_RING_ON: - event_id = FTDM_OOB_RING_START; - break; - - case PKH_EVENT_PHONE_OFFHOOK: - ftdm_set_flag_locked(span->channels[i], FTDM_CHANNEL_OFFHOOK); - event_id = FTDM_OOB_OFFHOOK; - break; - - case PKH_EVENT_TRUNK_BELOW_THRESHOLD: - case PKH_EVENT_TRUNK_ABOVE_THRESHOLD: - case PKH_EVENT_PHONE_ONHOOK: - ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_OFFHOOK); - event_id = FTDM_OOB_ONHOOK; - break; - - - - case PKH_EVENT_SPAN_ALARM_T1_RED: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_RED); - snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RED ALARM"); - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_T1_YELLOW: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_YELLOW); - snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "YELLOW ALARM"); - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_T1_AIS: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_AIS); - snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "AIS ALARM"); - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_E1_RED: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_RED); - snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RED ALARM"); - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_E1_RAI: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_RAI); - snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RAI ALARM"); - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_E1_AIS: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_AIS); - snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "AIS ALARM"); - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_E1_RMAI: - case PKH_EVENT_SPAN_ALARM_E1_TS16AIS: - case PKH_EVENT_SPAN_ALARM_E1_TS16LOS: - case PKH_EVENT_SPAN_OUT_OF_SYNC: - case PKH_EVENT_SPAN_FRAMING_ERROR: - case PKH_EVENT_SPAN_LOSS_OF_SIGNAL: - case PKH_EVENT_SPAN_OUT_OF_CRC_MF_SYNC: - case PKH_EVENT_SPAN_OUT_OF_CAS_MF_SYNC: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_GENERAL); - snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "GENERAL ALARM"); - event_id = FTDM_OOB_ALARM_TRAP; - break; - case PKH_EVENT_SPAN_ALARM_T1_RED_CLEAR: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_RED); - case PKH_EVENT_SPAN_ALARM_T1_YELLOW_CLEAR: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_YELLOW); - case PKH_EVENT_SPAN_ALARM_T1_AIS_CLEAR: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_AIS); - case PKH_EVENT_SPAN_ALARM_E1_RED_CLEAR: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_RED); - case PKH_EVENT_SPAN_ALARM_E1_RAI_CLEAR: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_RAI); - case PKH_EVENT_SPAN_ALARM_E1_AIS_CLEAR: - ftdm_set_alarm_flag(span->channels[i], FTDM_ALARM_AIS); - case PKH_EVENT_SPAN_ALARM_E1_RMAI_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_TS16AIS_CLEAR: - case PKH_EVENT_SPAN_ALARM_E1_TS16LOS_CLEAR: - case PKH_EVENT_SPAN_IN_SYNC: - case PKH_EVENT_SPAN_LOSS_OF_SIGNAL_CLEAR: - case PKH_EVENT_SPAN_IN_CRC_MF_SYNC: - case PKH_EVENT_SPAN_IN_CAS_MF_SYNC: - ftdm_clear_alarm_flag(span->channels[i], FTDM_ALARM_GENERAL); - event_id = FTDM_OOB_ALARM_CLEAR; - break; - case PKH_EVENT_SPAN_MESSAGE: - case PKH_EVENT_SPAN_ABCD_SIGNAL_CHANGE: - break; - - - - - case PKH_EVENT_TRUNK_ONHOOK: - case PKH_EVENT_TRUNK_OFFHOOK: - case PKH_EVENT_TRUNK_DIALED : - case PKH_EVENT_TRUNK_REVERSAL: - case PKH_EVENT_TRUNK_LCSO: - case PKH_EVENT_TRUNK_DROPOUT: - case PKH_EVENT_TRUNK_LOF: - case PKH_EVENT_TRUNK_RX_OVERLOAD: - default: - ftdm_log(FTDM_LOG_DEBUG, "Unhandled event %d on channel %d [%s]\n", chan_data->last_oob_event.id, i, event_text); - event_id = FTDM_OOB_INVALID; - break; - } - - span->channels[i]->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = span->channels[i]; - *event = &span->event_header; - return FTDM_SUCCESS; - } - } - - return FTDM_FAIL; -} - -/** - * \brief Destroys a Pika Span - * \param span Span to destroy - * \return Success - */ -static FIO_SPAN_DESTROY_FUNCTION(pika_span_destroy) -{ - pika_span_data_t *span_data = (pika_span_data_t *) span->io_data; - - if (span_data) { - PKH_QUEUE_Destroy(span_data->event_queue); - ftdm_safe_free(span_data); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Destroys a Pika Channel - * \param ftdmchan Channel to destroy - * \return Success or failure - */ -static FIO_CHANNEL_DESTROY_FUNCTION(pika_channel_destroy) -{ - pika_chan_data_t *chan_data = (pika_chan_data_t *) ftdmchan->io_data; - pika_span_data_t *span_data = (pika_span_data_t *) ftdmchan->span->io_data; - - if (!chan_data) { - return FTDM_FAIL; - } - - if (!ftdm_test_flag(chan_data, PK_FLAG_READY)) { - goto end; - } - - PKH_RECORD_Stop(chan_data->media_in); - PKH_PLAY_Stop(chan_data->media_out); - PKH_QUEUE_Destroy(chan_data->media_in_queue); - PKH_QUEUE_Destroy(chan_data->media_out_queue); - - switch(ftdmchan->type) { - case FTDM_CHAN_TYPE_FXS: - PKH_QUEUE_Detach(span_data->event_queue, chan_data->handle); - PKH_PHONE_Close(chan_data->handle); - break; - case FTDM_CHAN_TYPE_FXO: - PKH_QUEUE_Detach(span_data->event_queue, chan_data->handle); - PKH_TRUNK_Close(chan_data->handle); - break; - case FTDM_CHAN_TYPE_DQ921: - PKH_SPAN_Stop(span_data->handle); - break; - default: - break; - } - - - ftdm_mutex_destroy(&chan_data->digit_mutex); - ftdm_buffer_destroy(&chan_data->digit_buffer); - - end: - ftdm_safe_free(chan_data); - - return FTDM_SUCCESS; -} - -/** - * \brief Gets alarms from a Pika Channel (does nothing) - * \param ftdmchan Channel to get alarms from - * \return Failure - */ -static FIO_GET_ALARMS_FUNCTION(pika_get_alarms) -{ - return FTDM_FAIL; -} - -static ftdm_io_interface_t pika_interface; - -/** - * \brief Loads Pika IO module - * \param fio FreeTDM IO interface - * \return Success or failure - */ -static FIO_IO_LOAD_FUNCTION(pika_init) -{ - - PK_STATUS status; - PK_CHAR error_text[PKH_ERROR_MAX_NAME_LENGTH]; - uint32_t i; - int ok = 0; - PKH_TLogMasks m; - TPikaHandle tmpHandle; - - assert(fio != NULL); - memset(&pika_interface, 0, sizeof(pika_interface)); - memset(&globals, 0, sizeof(globals)); - globals.general_config.region = PKH_TRUNK_NA; - - globals.profile_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - - // Open the system object, to enumerate boards configured for this system - if ((status = PKH_SYSTEM_Open(&globals.system_handle)) != PK_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error: PKH_SYSTEM_Open failed(%s)!\n", - PKH_ERROR_GetText(status, error_text, sizeof(error_text))); - return FTDM_FAIL; - } - - // Retrieves a list of all boards in this system, existing, - // or listed in pika.cfg - if ((status = PKH_SYSTEM_Detect(globals.system_handle, &globals.board_list)) != PK_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error: PKH_SYSTEM_Detect failed(%s)!\n", - PKH_ERROR_GetText(status, error_text, sizeof(error_text))); - return FTDM_FAIL; - } - - PKH_SYSTEM_GetConfig(globals.system_handle, &globals.system_config); - globals.system_config.maxAudioProcessBlockSize = PIKA_BLOCK_LEN; - globals.system_config.playBufferSize = PIKA_BLOCK_SIZE; - globals.system_config.recordBufferSize = PIKA_BLOCK_SIZE; - globals.system_config.recordNumberOfBuffers = PIKA_NUM_BUFFERS; - PKH_SYSTEM_SetConfig(globals.system_handle, &globals.system_config); - - status = PKH_MEDIA_STREAM_Create(&tmpHandle); - status = PKH_RECORD_GetConfig(tmpHandle, &globals.record_config); - status = PKH_PLAY_GetConfig(tmpHandle, &globals.play_config); - status = PKH_EC_GetConfig(tmpHandle, &globals.ec_config); - status = PKH_MEDIA_STREAM_Destroy(tmpHandle); - - - - ftdm_log(FTDM_LOG_DEBUG, "Found %u board%s\n", globals.board_list.numberOfBoards, globals.board_list.numberOfBoards == 1 ? "" : "s"); - for(i = 0; i < globals.board_list.numberOfBoards; ++i) { - ftdm_log(FTDM_LOG_INFO, "Found PIKA board type:[%s] id:[%u] serno:[%u]\n", - pika_board_type_string(globals.board_list.board[i].type), globals.board_list.board[i].id, (uint32_t) - globals.board_list.board[i].serialNumber); - - if (globals.board_list.board[i].type == PKH_BOARD_TYPE_DIGITAL_GATEWAY) { - TPikaHandle board_handle, span_handle; - PKH_TBoardConfig boardConfig; - PKH_BOARD_GetConfig(board_handle, &boardConfig); - PKH_BOARD_Open(globals.board_list.board[i].id, NULL, &board_handle); - PKH_SPAN_Open(board_handle, 0, NULL, &span_handle); - PKH_SPAN_GetConfig(span_handle, &globals.t1_span_config); - PKH_SPAN_Close(span_handle); - boardConfig.specific.DigitalGateway.interfaceType = PKH_BOARD_INTERFACE_TYPE_E1; - PKH_BOARD_SetConfig(board_handle, &boardConfig); - PKH_SPAN_Open(board_handle, 0, NULL, &span_handle); - PKH_SPAN_GetConfig(span_handle, &globals.e1_span_config); - PKH_SPAN_Close(span_handle); - boardConfig.specific.DigitalGateway.interfaceType = PKH_BOARD_INTERFACE_TYPE_T1; - PKH_BOARD_SetConfig(board_handle, &boardConfig); - PKH_BOARD_Close(board_handle); - } - ok++; - - } - - if (!ok) { - return FTDM_FAIL; - } - - pika_interface.name = "pika"; - pika_interface.configure = pika_configure; - pika_interface.configure_span = pika_configure_span; - pika_interface.open = pika_open; - pika_interface.close = pika_close; - pika_interface.wait = pika_wait; - pika_interface.read = pika_read; - pika_interface.write = pika_write; - pika_interface.command = pika_command; - pika_interface.poll_event = pika_poll_event; - pika_interface.next_event = pika_next_event; - pika_interface.channel_destroy = pika_channel_destroy; - pika_interface.span_destroy = pika_span_destroy; - pika_interface.get_alarms = pika_get_alarms; - *fio = &pika_interface; - - - ftdm_log(FTDM_LOG_INFO, "Dumping Default configs:\n"); - ftdm_log(FTDM_LOG_INFO, "rx-gain => %0.2f\n", (float)globals.record_config.gain); - ftdm_log(FTDM_LOG_INFO, "rx-agc-enabled => %s\n", globals.record_config.AGC.enabled ? "true" : "false"); - ftdm_log(FTDM_LOG_INFO, "rx-agc-targetPower => %0.2f\n", (float)globals.record_config.AGC.targetPower); - ftdm_log(FTDM_LOG_INFO, "rx-agc-minGain => %0.2f\n", (float)globals.record_config.AGC.minGain); - ftdm_log(FTDM_LOG_INFO, "rx-agc-maxGain => %0.2f\n", (float)globals.record_config.AGC.maxGain); - ftdm_log(FTDM_LOG_INFO, "rx-agc-attackRate => %d\n", (int)globals.record_config.AGC.attackRate); - ftdm_log(FTDM_LOG_INFO, "rx-agc-decayRate => %d\n", (int)globals.record_config.AGC.decayRate); - ftdm_log(FTDM_LOG_INFO, "rx-agc-speechThreshold => %0.2f\n", (float)globals.record_config.AGC.speechThreshold); - ftdm_log(FTDM_LOG_INFO, "rx-vad-enabled => %s\n", globals.record_config.VAD.enabled ? "true" : "false"); - ftdm_log(FTDM_LOG_INFO, "rx-vad-activationThreshold => %0.2f\n", (float)globals.record_config.VAD.activationThreshold); - ftdm_log(FTDM_LOG_INFO, "rx-vad-activationDebounceTime => %d\n", (int)globals.record_config.VAD.activationDebounceTime); - ftdm_log(FTDM_LOG_INFO, "rx-vad-deactivationThreshold => %0.2f\n", (float)globals.record_config.VAD.deactivationThreshold); - ftdm_log(FTDM_LOG_INFO, "rx-vad-deactivationDebounceTime => %d\n", (int)globals.record_config.VAD.deactivationDebounceTime); - ftdm_log(FTDM_LOG_INFO, "rx-vad-preSpeechBufferSize => %d\n", (int)globals.record_config.VAD.preSpeechBufferSize); - ftdm_log(FTDM_LOG_INFO, "tx-gain => %0.2f\n", (float)globals.play_config.gain); - ftdm_log(FTDM_LOG_INFO, "tx-agc-enabled => %s\n", globals.play_config.AGC.enabled ? "true" : "false"); - ftdm_log(FTDM_LOG_INFO, "tx-agc-targetPower => %0.2f\n", (float)globals.play_config.AGC.targetPower); - ftdm_log(FTDM_LOG_INFO, "tx-agc-minGain => %0.2f\n", (float)globals.play_config.AGC.minGain); - ftdm_log(FTDM_LOG_INFO, "tx-agc-maxGain => %0.2f\n", (float)globals.play_config.AGC.maxGain); - ftdm_log(FTDM_LOG_INFO, "tx-agc-attackRate => %d\n", (int)globals.play_config.AGC.attackRate); - ftdm_log(FTDM_LOG_INFO, "tx-agc-decayRate => %d\n", (int)globals.play_config.AGC.decayRate); - ftdm_log(FTDM_LOG_INFO, "tx-agc-speechThreshold => %0.2f\n", (float)globals.play_config.AGC.speechThreshold); - ftdm_log(FTDM_LOG_INFO, "ec-doubleTalkerThreshold => %0.2f\n", (float)globals.ec_config.doubleTalkerThreshold); - ftdm_log(FTDM_LOG_INFO, "ec-speechPresentThreshold => %0.2f\n", (float)globals.ec_config.speechPresentThreshold); - ftdm_log(FTDM_LOG_INFO, "ec-echoSuppressionThreshold => %0.2f\n", (float)globals.ec_config.echoSuppressionThreshold); - ftdm_log(FTDM_LOG_INFO, "ec-echoSuppressionEnabled => %s\n", globals.ec_config.echoSuppressionEnabled ? "true" : "false"); - ftdm_log(FTDM_LOG_INFO, "ec-comfortNoiseEnabled => %s\n", globals.ec_config.comfortNoiseEnabled ? "true" : "false"); - ftdm_log(FTDM_LOG_INFO, "ec-adaptationModeEnabled => %s\n", globals.ec_config.adaptationModeEnabled ? "true" : "false"); - - - - memset(&m, 0, sizeof(m)); - //m.apiMask = 0xffffffff; - //PKH_LOG_SetMasks(&m); - - return FTDM_SUCCESS; -} - -/** - * \brief Unloads Pika IO module - * \return Success - */ -static FIO_IO_UNLOAD_FUNCTION(pika_destroy) -{ - uint32_t x; - PK_STATUS status; - PK_CHAR error_text[PKH_ERROR_MAX_NAME_LENGTH]; - - for (x = 0; x < MAX_NUMBER_OF_TRUNKS; x++) { - if (globals.open_boards[x]) { - ftdm_log(FTDM_LOG_INFO, "Closing board %u\n", x); - PKH_BOARD_Close(globals.open_boards[x]); - } - } - - // The system can now be closed. - if ((status = PKH_SYSTEM_Close(globals.system_handle)) != PK_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error: PKH_SYSTEM_Close failed(%s)!\n", - PKH_ERROR_GetText(status, error_text, sizeof(error_text))); - } else { - ftdm_log(FTDM_LOG_INFO, "Closing system handle\n"); - } - - hashtable_destroy(globals.profile_hash); - - return FTDM_SUCCESS; -} - -/** - * \brief Pika IO module definition - */ -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - "pika", - pika_init, - pika_destroy, -}; - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/ftmod/ftmod_pika/ozmod_pika.2005.vcproj b/libs/freetdm/src/ftmod/ftmod_pika/ozmod_pika.2005.vcproj deleted file mode 100644 index 646cc11428..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_pika/ozmod_pika.2005.vcproj +++ /dev/null @@ -1,197 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c deleted file mode 100644 index 38f9c48e84..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * Copyright (c) 2010, Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include "private/ftdm_core.h" - -#define PRI_SPAN(p) (((p) >> 8) & 0xff) -#define PRI_CHANNEL(p) ((p) & 0xff) - -#define PRITAP_NETWORK_ANSWER 0x1 - -typedef enum { - PRITAP_RUNNING = (1 << 0), - PRITAP_MASTER = (1 << 1), -} pritap_flags_t; - -typedef enum { - PRITAP_MIX_BOTH = 0, - PRITAP_MIX_PEER, - PRITAP_MIX_SELF, -} pritap_mix_mode_t; - -typedef struct { - void *callref; - ftdm_number_t callingnum; - ftdm_number_t callingani; - ftdm_number_t callednum; - ftdm_channel_t *fchan; - char callingname[80]; - uint8_t proceeding; - uint8_t inuse; -} passive_call_t; - -typedef enum pritap_iface { - PRITAP_IFACE_UNKNOWN = 0, - PRITAP_IFACE_CPE = 1, - PRITAP_IFACE_NET = 2, -} pritap_iface_t; - -typedef struct pritap { - int32_t flags; - struct pri *pri; - int debug; - pritap_mix_mode_t mixaudio; - ftdm_channel_t *dchan; - ftdm_span_t *span; - ftdm_span_t *peerspan; - ftdm_mutex_t *pcalls_lock; - passive_call_t pcalls[FTDM_MAX_CHANNELS_PHYSICAL_SPAN]; - pritap_iface_t iface; -} pritap_t; - -static FIO_IO_UNLOAD_FUNCTION(ftdm_pritap_unload) -{ - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(pritap_get_channel_sig_status) -{ - *status = FTDM_SIG_STATE_UP; - return FTDM_SUCCESS; -} - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(pritap_get_span_sig_status) -{ - *status = FTDM_SIG_STATE_UP; - return FTDM_SUCCESS; -} - - -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(pritap_outgoing_call) -{ - ftdm_log(FTDM_LOG_ERROR, "Cannot dial on PRI tapping line!\n"); - return FTDM_FAIL; -} - -static void s_pri_error(struct pri *pri, char *s) -{ - pritap_t *pritap = pri_get_userdata(pri); - - if (pritap && pritap->dchan) { - ftdm_log_chan(pritap->dchan, FTDM_LOG_ERROR, "%s", s); - } else { - ftdm_log(FTDM_LOG_ERROR, "%s", s); - } -} - -static void s_pri_message(struct pri *pri, char *s) -{ - pritap_t *pritap = pri_get_userdata(pri); - - if (pritap && pritap->dchan) { - ftdm_log_chan(pritap->dchan, FTDM_LOG_DEBUG, "%s", s); - } else { - ftdm_log(FTDM_LOG_DEBUG, "%s", s); - } -} - -#define PRI_DEBUG_Q921_ALL (PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE) -#define PRI_DEBUG_Q931_ALL (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE | PRI_DEBUG_Q931_ANOMALY) - -static int parse_debug(const char *in) -{ - int flags = 0; - - if (!in) { - return 0; - } - - if (!strcmp(in, "none")) { - return 0; - } - - if (!strcmp(in, "all")) { - return PRI_DEBUG_ALL; - } - - if (strstr(in, "q921_all")) { - flags |= PRI_DEBUG_Q921_ALL; - } - - if (strstr(in, "q921_raw")) { - flags |= PRI_DEBUG_Q921_RAW; - } - - if (strstr(in, "q921_dump")) { - flags |= PRI_DEBUG_Q921_DUMP; - } - - if (strstr(in, "q921_state")) { - flags |= PRI_DEBUG_Q921_STATE; - } - - if (strstr(in, "config")) { - flags |= PRI_DEBUG_CONFIG; - } - - if (strstr(in, "q931_all")) { - flags |= PRI_DEBUG_Q931_ALL; - } - - if (strstr(in, "q931_dump")) { - flags |= PRI_DEBUG_Q931_DUMP; - } - - if (strstr(in, "q931_state")) { - flags |= PRI_DEBUG_Q931_STATE; - } - - if (strstr(in, "q931_anomaly")) { - flags |= PRI_DEBUG_Q931_ANOMALY; - } - - if (strstr(in, "apdu")) { - flags |= PRI_DEBUG_APDU; - } - - if (strstr(in, "aoc")) { - flags |= PRI_DEBUG_AOC; - } - - return flags; -} - -static ftdm_io_interface_t ftdm_pritap_interface; - -static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span); - -static FIO_API_FUNCTION(ftdm_pritap_api) -{ - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argc > 2) { - if (!strcasecmp(argv[0], "debug")) { - ftdm_span_t *span = NULL; - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) { - pritap_t *pritap = span->signal_data; - if (span->start != ftdm_pritap_start) { - stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); - goto done; - } - - pri_set_debug(pritap->pri, parse_debug(argv[2])); - stream->write_function(stream, "%s: +OK debug set.\n", __FILE__); - goto done; - } else { - stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); - goto done; - } - } - - } - - stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__); - - done: - - ftdm_safe_free(mycmd); - - return FTDM_SUCCESS; -} - -static FIO_IO_LOAD_FUNCTION(ftdm_pritap_io_init) -{ - memset(&ftdm_pritap_interface, 0, sizeof(ftdm_pritap_interface)); - - ftdm_pritap_interface.name = "pritap"; - ftdm_pritap_interface.api = ftdm_pritap_api; - - *fio = &ftdm_pritap_interface; - - return FTDM_SUCCESS; -} - -static FIO_SIG_LOAD_FUNCTION(ftdm_pritap_init) -{ - pri_set_error(s_pri_error); - pri_set_message(s_pri_message); - return FTDM_SUCCESS; -} - -static ftdm_state_map_t pritap_state_map = { - { - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - - } -}; - -#define PRITAP_GET_INTERFACE(iface) iface == PRITAP_IFACE_CPE ? "CPE" : \ - iface == PRITAP_IFACE_NET ? "NET" : "UNKNOWN" -static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) -{ - ftdm_status_t status; - ftdm_sigmsg_t sig; - pritap_t *pritap = ftdmchan->span->signal_data; - pritap_t *peer_pritap = pritap->peerspan->signal_data; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "processing state %s\n", ftdm_channel_state2str(ftdmchan->state)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - - ftdm_channel_complete_state(ftdmchan); - - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_DOWN: - { - ftdm_channel_t *fchan = ftdmchan; - - /* Destroy the peer data first */ - if (fchan->call_data) { - ftdm_channel_t *peerchan = fchan->call_data; - ftdm_channel_t *pchan = peerchan; - - ftdm_channel_lock(peerchan); - - pchan->call_data = NULL; - pchan->pflags = 0; - ftdm_channel_close(&pchan); - - ftdm_channel_unlock(peerchan); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "No call data?\n"); - } - - ftdmchan->call_data = NULL; - ftdmchan->pflags = 0; - ftdm_channel_close(&fchan); - } - break; - - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_HANGUP: - break; - - case FTDM_CHANNEL_STATE_UP: - { - if (ftdm_test_pflag(ftdmchan, PRITAP_NETWORK_ANSWER)) { - ftdm_clear_pflag(ftdmchan, PRITAP_NETWORK_ANSWER); - sig.event_id = FTDM_SIGEVENT_UP; - ftdm_span_send_signal(ftdmchan->span, &sig); - } - } - break; - - case FTDM_CHANNEL_STATE_RING: - { - sig.event_id = FTDM_SIGEVENT_START; - /* The ring interface (where the setup was received) is the peer, since we RING the channel - * where PROCEED/PROGRESS is received */ - ftdm_sigmsg_add_var(&sig, "pritap_ring_interface", PRITAP_GET_INTERFACE(peer_pritap->iface)); - if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } - } - break; - - case FTDM_CHANNEL_STATE_TERMINATING: - { - if (ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP) { - sig.event_id = FTDM_SIGEVENT_STOP; - status = ftdm_span_send_signal(ftdmchan->span, &sig); - } - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - - default: - { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ignoring state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(ftdmchan->state)); - } - break; - } - - return FTDM_SUCCESS; -} - -static __inline__ void pritap_check_state(ftdm_span_t *span) -{ - if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) { - uint32_t j; - ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE); - for(j = 1; j <= span->chan_count; j++) { - ftdm_channel_lock(span->channels[j]); - ftdm_channel_advance_states(span->channels[j]); - ftdm_channel_unlock(span->channels[j]); - } - } -} - -static int pri_io_read(struct pri *pri, void *buf, int buflen) -{ - int res; - ftdm_status_t zst; - pritap_t *pritap = pri_get_userdata(pri); - ftdm_size_t len = buflen; - - if ((zst = ftdm_channel_read(pritap->dchan, buf, &len)) != FTDM_SUCCESS) { - if (zst == FTDM_FAIL) { - ftdm_log(FTDM_LOG_CRIT, "span %d D channel read fail! [%s]\n", pritap->span->span_id, pritap->dchan->last_error); - } else { - ftdm_log(FTDM_LOG_CRIT, "span %d D channel read timeout!\n", pritap->span->span_id); - } - return -1; - } - - res = (int)len; - - memset(&((unsigned char*)buf)[res],0,2); - res += 2; - - /* libpri passive q921 raw dump does not work for all frames */ - if (pritap->debug & PRI_DEBUG_Q921_RAW) { - char hbuf[2048] = { 0 }; - - print_hex_bytes(buf, len, hbuf, sizeof(hbuf)); - ftdm_log_chan(pritap->dchan, FTDM_LOG_DEBUG, "READ %"FTDM_SIZE_FMT"\n%s\n", len, hbuf); - } - return res; -} - -static int pri_io_write(struct pri *pri, void *buf, int buflen) -{ - pritap_t *pritap = pri_get_userdata(pri); - ftdm_size_t len = buflen - 2; - - /* libpri passive q921 raw dump does not work for all frames */ - if (pritap->debug & PRI_DEBUG_Q921_RAW) { - char hbuf[2048] = { 0 }; - - print_hex_bytes(buf, len, hbuf, sizeof(hbuf)); - ftdm_log_chan(pritap->dchan, FTDM_LOG_DEBUG, "WRITE %"FTDM_SIZE_FMT"\n%s\n", len, hbuf); - } - - if (ftdm_channel_write(pritap->dchan, buf, buflen, &len) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "span %d D channel write failed! [%s]\n", pritap->span->span_id, pritap->dchan->last_error); - return -1; - } - - return (int)buflen; -} - -static int tap_pri_get_crv(struct pri *ctrl, q931_call *call) -{ - int callmode = 0; - int crv = pri_get_crv(ctrl, call, &callmode); - crv <<= 3; - crv |= (callmode & 0x7); - return crv; -} - -static passive_call_t *tap_pri_get_pcall_bycrv(pritap_t *pritap, int crv) -{ - int i; - int tstcrv; - - ftdm_mutex_lock(pritap->pcalls_lock); - - for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) { - tstcrv = pritap->pcalls[i].callref ? tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref) : 0; - if (pritap->pcalls[i].callref && tstcrv == crv) { - if (pritap->pcalls[i].inuse) { - ftdm_mutex_unlock(pritap->pcalls_lock); - return &pritap->pcalls[i]; - } - /* This just means the crv is being re-used in another call before this one was destroyed */ - ftdm_log(FTDM_LOG_DEBUG, "Found crv %d in slot %d of span %s with call %p but is no longer in use\n", - crv, i, pritap->span->name, pritap->pcalls[i].callref); - } - } - - ftdm_log(FTDM_LOG_DEBUG, "crv %d was not found active in span %s\n", crv, pritap->span->name); - - ftdm_mutex_unlock(pritap->pcalls_lock); - - return NULL; -} - -/* - * This is a tricky function with some side effects, some explanation needed ... - * - * The libpri stack process HDLC frames, then finds Q921 frames and Q931 events, each time - * it finds a new Q931 event, checks if the crv of that event matches a known call in the internal - * list found in the PRI control block (for us, one control block per span), if it does not find - * the call, allocates a new one and then sends the event up to the user (us, ftmod_pritap in this case) - * - * The user is then expected to destroy the call when done with it (on hangup), but things get tricky here - * because in ftmod_pritap we do not destroy the call right away to be sure we only destroy it when no one - * else needs that pointer, therefore we decide to delay the destruction of the call pointer until later - * when a new call comes which triggers the garbage collecting code in this function - * - * Now, what happens if a new call arrives right away with the same crv than the last call? the pri stack - * does *not* allocate a new call pointer because is still a known call and we must therefore re-use the - * same call pointer - * - * This function accepts a pointer to a callref, even a NULL one. When callref is NULL we search for an - * available slot so the caller of this function can use it to store a new callref pointer. In the process - * we also scan for slots that still have a callref pointer but are no longer in use (inuse=0) and we - * destroy that callref and clear the slot (memset). The trick is, we only do this if the callref to - * be garbage collected is NOT the one provided by the parameter callref, of course! otherwise we may - * be freeing a pointer to a callref for a new call that used an old (recycled) callref! - */ -static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref) -{ - int i; - int crv; - - ftdm_mutex_lock(pritap->pcalls_lock); - - for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) { - /* If this slot has a call reference - * and it is different than the *callref provided to us - * and is no longer in use, - * then it is time to garbage collect it ... */ - if (pritap->pcalls[i].callref && callref != pritap->pcalls[i].callref && !pritap->pcalls[i].inuse) { - crv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref); - /* garbage collection */ - ftdm_log(FTDM_LOG_DEBUG, "Garbage collecting callref %d/%p from span %s in slot %d\n", - crv, pritap->pcalls[i].callref, pritap->span->name, i); - pri_passive_destroycall(pritap->pri, pritap->pcalls[i].callref); - memset(&pritap->pcalls[i], 0, sizeof(pritap->pcalls[0])); - } - if (callref == pritap->pcalls[i].callref) { - if (callref == NULL) { - pritap->pcalls[i].inuse = 1; - ftdm_log(FTDM_LOG_DEBUG, "Enabling callref slot %d in span %s\n", i, pritap->span->name); - } else if (!pritap->pcalls[i].inuse) { - crv = tap_pri_get_crv(pritap->pri, callref); - ftdm_log(FTDM_LOG_DEBUG, "Recyclying callref slot %d in span %s for callref %d/%p\n", - i, pritap->span->name, crv, callref); - memset(&pritap->pcalls[i], 0, sizeof(pritap->pcalls[0])); - pritap->pcalls[i].callref = callref; - pritap->pcalls[i].inuse = 1; - } - - ftdm_mutex_unlock(pritap->pcalls_lock); - - return &pritap->pcalls[i]; - } - } - - ftdm_mutex_unlock(pritap->pcalls_lock); - - return NULL; -} - -static void tap_pri_put_pcall(pritap_t *pritap, void *callref) -{ - int i; - int crv; - int tstcrv; - - if (!callref) { - ftdm_log(FTDM_LOG_ERROR, "Cannot put pcall for null callref in span %s\n", pritap->span->name); - return; - } - - ftdm_mutex_lock(pritap->pcalls_lock); - - crv = tap_pri_get_crv(pritap->pri, callref); - for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) { - if (!pritap->pcalls[i].callref) { - continue; - } - tstcrv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref); - if (tstcrv == crv) { - if (pritap->pcalls[i].inuse) { - ftdm_log(FTDM_LOG_DEBUG, "releasing slot %d in span %s used by callref %d/%p\n", i, - pritap->span->name, crv, pritap->pcalls[i].callref); - pritap->pcalls[i].inuse = 0; - } - } - } - - ftdm_mutex_unlock(pritap->pcalls_lock); -} - -static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_call_t *pcall, int channel) -{ - ftdm_channel_t *fchan = NULL; - int err = 0; - int chanpos = PRI_CHANNEL(channel); - if (!chanpos || chanpos > pritap->span->chan_count) { - ftdm_log(FTDM_LOG_CRIT, "Invalid pri tap channel %d requested in span %s\n", channel, pritap->span->name); - return NULL; - } - - fchan = pritap->span->channels[PRI_CHANNEL(channel)]; - - ftdm_channel_lock(fchan); - - if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) { - ftdm_log(FTDM_LOG_ERROR, "Channel %d requested in span %s is already in use!\n", channel, pritap->span->name); - err = 1; - goto done; - } - - if (ftdm_channel_open_chan(fchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Could not open tap channel %d requested in span %s\n", channel, pritap->span->name); - err = 1; - goto done; - } - - memset(&fchan->caller_data, 0, sizeof(fchan->caller_data)); - - ftdm_set_string(fchan->caller_data.cid_num.digits, pcall->callingnum.digits); - if (!ftdm_strlen_zero(pcall->callingname)) { - ftdm_set_string(fchan->caller_data.cid_name, pcall->callingname); - } else { - ftdm_set_string(fchan->caller_data.cid_name, pcall->callingnum.digits); - } - ftdm_set_string(fchan->caller_data.ani.digits, pcall->callingani.digits); - ftdm_set_string(fchan->caller_data.dnis.digits, pcall->callednum.digits); - -done: - if (fchan) { - ftdm_channel_unlock(fchan); - } - - if (err) { - return NULL; - } - - return fchan; -} - -static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) -{ - passive_call_t *pcall = NULL; - passive_call_t *peerpcall = NULL; - ftdm_channel_t *fchan = NULL; - ftdm_channel_t *peerfchan = NULL; - int layer1, transcap = 0; - int crv = 0; - pritap_t *peertap = pritap->peerspan->signal_data; - - switch (e->e) { - - case PRI_EVENT_RING: - /* we cannot use ftdm_channel_t because we still dont know which channel will be used - * (ie, flexible channel was requested), thus, we need our own list of call references */ - crv = tap_pri_get_crv(pritap->pri, e->ring.call); - ftdm_log(FTDM_LOG_DEBUG, "Ring on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), crv); - pcall = tap_pri_get_pcall_bycrv(pritap, crv); - if (pcall) { - ftdm_log(FTDM_LOG_WARNING, "There is a call with callref %d already, ignoring duplicated ring event\n", crv); - break; - } - - /* Try to get a recycled call (ie, e->ring.call is a call that the PRI stack allocated previously and then - * re-used for the next RING event because we did not destroy it fast enough) */ - pcall = tap_pri_get_pcall(pritap, e->ring.call); - if (!pcall) { - /* ok so the call is really not known to us, let's get a new one */ - pcall = tap_pri_get_pcall(pritap, NULL); - if (!pcall) { - ftdm_log(FTDM_LOG_ERROR, "Failed to get a free passive PRI call slot for callref %d, this is a bug!\n", crv); - break; - } - } - pcall->callref = e->ring.call; - ftdm_set_string(pcall->callingnum.digits, e->ring.callingnum); - ftdm_set_string(pcall->callingani.digits, e->ring.callingani); - ftdm_set_string(pcall->callednum.digits, e->ring.callednum); - ftdm_set_string(pcall->callingname, e->ring.callingname); - break; - - case PRI_EVENT_PROGRESS: - crv = tap_pri_get_crv(pritap->pri, e->proceeding.call); - ftdm_log(FTDM_LOG_DEBUG, "Progress on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); - break; - - case PRI_EVENT_PROCEEDING: - crv = tap_pri_get_crv(pritap->pri, e->proceeding.call); - /* at this point we should know the real b chan that will be used and can therefore proceed to notify about the call, but - * only if a couple of call tests are passed first */ - ftdm_log(FTDM_LOG_DEBUG, "Proceeding on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); - - /* check that we already know about this call in the peer PRI (which was the one receiving the PRI_EVENT_RING event) */ - if (!(pcall = tap_pri_get_pcall_bycrv(peertap, crv))) { - ftdm_log(FTDM_LOG_DEBUG, - "ignoring proceeding in channel %s:%d:%d for callref %d since we don't know about it\n", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); - break; - } - if (pcall->proceeding) { - ftdm_log(FTDM_LOG_DEBUG, "Ignoring duplicated proceeding with callref %d\n", crv); - break; - } - pcall->proceeding = 1; - - /* This call should not be known to this PRI yet ... */ - if ((peerpcall = tap_pri_get_pcall_bycrv(pritap, crv))) { - ftdm_log(FTDM_LOG_ERROR, - "ignoring proceeding in channel %s:%d:%d for callref %d, dup???\n", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); - break; - } - - /* Check if the call pointer is being recycled */ - peerpcall = tap_pri_get_pcall(pritap, e->proceeding.call); - if (!peerpcall) { - peerpcall = tap_pri_get_pcall(pritap, NULL); - if (!peerpcall) { - ftdm_log(FTDM_LOG_ERROR, "Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!\n", - crv, pritap->span->name); - break; - } - peerpcall->callref = e->proceeding.call; - } - - /* check that the layer 1 and trans capability are supported */ - layer1 = pri_get_layer1(peertap->pri, pcall->callref); - transcap = pri_get_transcap(peertap->pri, pcall->callref); - - if (PRI_LAYER_1_ULAW != layer1 && PRI_LAYER_1_ALAW != layer1) { - ftdm_log(FTDM_LOG_NOTICE, "Not monitoring callref %d with unsupported layer 1 format %d\n", crv, layer1); - break; - } - - if (transcap != PRI_TRANS_CAP_SPEECH && transcap != PRI_TRANS_CAP_3_1K_AUDIO && transcap != PRI_TRANS_CAP_7K_AUDIO) { - ftdm_log(FTDM_LOG_NOTICE, "Not monitoring callref %d with unsupported capability %d\n", crv, transcap); - break; - } - - fchan = tap_pri_get_fchan(pritap, pcall, e->proceeding.channel); - if (!fchan) { - ftdm_log(FTDM_LOG_ERROR, "Proceeding requested on odd/unavailable channel %s:%d:%d for callref %d\n", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); - break; - } - - peerfchan = tap_pri_get_fchan(peertap, pcall, e->proceeding.channel); - if (!peerfchan) { - ftdm_log(FTDM_LOG_ERROR, "Proceeding requested on odd/unavailable channel %s:%d:%d for callref %d\n", - peertap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); - break; - } - pcall->fchan = fchan; - peerpcall->fchan = fchan; - - ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "Starting new tapped call with callref %d\n", crv); - - ftdm_channel_lock(fchan); - fchan->call_data = peerfchan; - ftdm_set_state(fchan, FTDM_CHANNEL_STATE_RING); - ftdm_channel_unlock(fchan); - - ftdm_channel_lock(peerfchan); - peerfchan->call_data = fchan; - ftdm_channel_unlock(peerfchan); - - break; - - case PRI_EVENT_ANSWER: - crv = tap_pri_get_crv(pritap->pri, e->answer.call); - ftdm_log(FTDM_LOG_DEBUG, "Answer on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv); - if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) { - ftdm_log(FTDM_LOG_DEBUG, - "ignoring answer in channel %s:%d:%d for callref %d since we don't know about it\n", - pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->proceeding.channel), crv); - break; - } - if (!pcall->fchan) { - ftdm_log(FTDM_LOG_ERROR, - "Received answer in channel %s:%d:%d for callref %d but we never got a channel\n", - pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv); - break; - } - ftdm_channel_lock(pcall->fchan); - ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Tapped call was answered in state %s\n", ftdm_channel_state2str(pcall->fchan->state)); - ftdm_set_pflag(pcall->fchan, PRITAP_NETWORK_ANSWER); - ftdm_set_state(pcall->fchan, FTDM_CHANNEL_STATE_UP); - ftdm_channel_unlock(pcall->fchan); - break; - - case PRI_EVENT_HANGUP_REQ: - crv = tap_pri_get_crv(pritap->pri, e->hangup.call); - - ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv); - - if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) { - ftdm_log(FTDM_LOG_DEBUG, - "ignoring hangup in channel %s:%d:%d for callref %d since we don't know about it", - pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv); - break; - } - - if (pcall->fchan) { - fchan = pcall->fchan; - ftdm_channel_lock(fchan); - if (fchan->state < FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_set_state(fchan, FTDM_CHANNEL_STATE_TERMINATING); - } - pcall->fchan = NULL; /* after this event we're not supposed to need to do anything with the channel anymore */ - ftdm_channel_unlock(fchan); - } - - tap_pri_put_pcall(pritap, e->hangup.call); - tap_pri_put_pcall(peertap, e->hangup.call); - break; - - case PRI_EVENT_HANGUP_ACK: - crv = tap_pri_get_crv(pritap->pri, e->hangup.call); - ftdm_log(FTDM_LOG_DEBUG, "Hangup ack on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv); - tap_pri_put_pcall(pritap, e->hangup.call); - tap_pri_put_pcall(peertap, e->hangup.call); - break; - - default: - ftdm_log(FTDM_LOG_DEBUG, "Ignoring passive event %s on span %s\n", pri_event2str(e->gen.e), pritap->span->name); - break; - - } -} - -static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj) -{ - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_span_t *peer = NULL; - pritap_t *pritap = span->signal_data; - pritap_t *p_pritap = NULL; - pri_event *event = NULL; - struct pollfd dpoll[2]; - int rc = 0; - - ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %s\n", span->name); - - pritap->span = span; - - ftdm_set_flag(span, FTDM_SPAN_IN_THREAD); - - if (ftdm_channel_open(span->span_id, pritap->dchan->chan_id, &pritap->dchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open D-channel for span %s\n", span->name); - goto done; - } - - if ((pritap->pri = pri_new_cb(pritap->dchan->sockfd, PRI_NETWORK, PRI_SWITCH_NI2, pri_io_read, pri_io_write, pritap))){ - pri_set_debug(pritap->pri, pritap->debug); - } else { - ftdm_log(FTDM_LOG_CRIT, "Failed to create tapping PRI\n"); - goto done; - } - - /* The last span starting runs the show ... - * This simplifies locking and avoid races by having multiple threads for a single tapped link - * Since both threads really handle a single tapped link there is no benefit on multi-threading, just complications ... */ - peer = pritap->peerspan; - p_pritap = peer->signal_data; - if (!ftdm_test_flag(pritap, PRITAP_MASTER)) { - ftdm_log(FTDM_LOG_DEBUG, "Running dummy thread on span %s\n", span->name); - while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { - poll(NULL, 0, 100); - } - } else { - memset(&dpoll, 0, sizeof(dpoll)); - dpoll[0].fd = pritap->dchan->sockfd; - dpoll[1].fd = p_pritap->dchan->sockfd; - - ftdm_log(FTDM_LOG_DEBUG, "Master tapping thread on span %s (fd1=%d, fd2=%d)\n", span->name, - pritap->dchan->sockfd, p_pritap->dchan->sockfd); - - while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { - - pritap_check_state(span); - pritap_check_state(peer); - - dpoll[0].revents = 0; - dpoll[0].events = POLLIN; - - dpoll[1].revents = 0; - dpoll[1].events = POLLIN; - - rc = poll(&dpoll[0], 2, 10); - - if (rc < 0) { - if (errno == EINTR) { - ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n"); - continue; - } - ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno)); - continue; - } - - pri_schedule_run(pritap->pri); - pri_schedule_run(p_pritap->pri); - - pritap_check_state(span); - pritap_check_state(peer); - - if (rc) { - if (dpoll[0].revents & POLLIN) { - event = pri_read_event(pritap->pri); - if (event) { - handle_pri_passive_event(pritap, event); - pritap_check_state(span); - } - } - - if (dpoll[1].revents & POLLIN) { - event = pri_read_event(p_pritap->pri); - if (event) { - handle_pri_passive_event(p_pritap, event); - pritap_check_state(peer); - } - } - } - - } - } - - -done: - ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %s\n", span->name); - - ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); - ftdm_clear_flag(pritap, PRITAP_RUNNING); - ftdm_clear_flag(pritap, PRITAP_MASTER); - - return NULL; -} - -static ftdm_status_t ftdm_pritap_stop(ftdm_span_t *span) -{ - pritap_t *pritap = span->signal_data; - - if (!ftdm_test_flag(pritap, PRITAP_RUNNING)) { - return FTDM_FAIL; - } - - ftdm_set_flag(span, FTDM_SPAN_STOP_THREAD); - - while (ftdm_test_flag(span, FTDM_SPAN_IN_THREAD)) { - ftdm_sleep(100); - } - - ftdm_mutex_destroy(&pritap->pcalls_lock); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_pritap_sig_read(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size) -{ - ftdm_status_t status; - fio_codec_t codec_func; - ftdm_channel_t *peerchan = ftdmchan->call_data; - pritap_t *pritap = ftdmchan->span->signal_data; - int16_t chanbuf[size]; - int16_t peerbuf[size]; - int16_t mixedbuf[size]; - int i = 0; - ftdm_size_t sizeread = size; - - if (!FTDM_IS_VOICE_CHANNEL(ftdmchan) || !ftdmchan->call_data) { - return FTDM_SUCCESS; - } - - if (pritap->mixaudio == PRITAP_MIX_SELF) { - return FTDM_SUCCESS; - } - - if (pritap->mixaudio == PRITAP_MIX_PEER) { - /* start out by clearing the self audio to make sure we don't return audio we were - * not supposed to in an error condition */ - memset(data, FTDM_SILENCE_VALUE(ftdmchan), size); - } - - if (ftdmchan->native_codec != peerchan->native_codec) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Invalid peer channel with format %d, ours = %d\n", - peerchan->native_codec, ftdmchan->native_codec); - return FTDM_FAIL; - } - - memcpy(chanbuf, data, size); - status = peerchan->fio->read(peerchan, peerbuf, &sizeread); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to read from peer channel!\n"); - return FTDM_FAIL; - } - if (sizeread != size) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "read from peer channel only %"FTDM_SIZE_FMT" bytes!\n", sizeread); - return FTDM_FAIL; - } - - if (pritap->mixaudio == PRITAP_MIX_PEER) { - /* only the peer audio is requested */ - memcpy(data, peerbuf, size); - return FTDM_SUCCESS; - } - - codec_func = peerchan->native_codec == FTDM_CODEC_ULAW ? fio_ulaw2slin : peerchan->native_codec == FTDM_CODEC_ALAW ? fio_alaw2slin : NULL; - if (codec_func) { - sizeread = size; - codec_func(chanbuf, sizeof(chanbuf), &sizeread); - sizeread = size; - codec_func(peerbuf, sizeof(peerbuf), &sizeread); - } - - for (i = 0; i < size; i++) { - mixedbuf[i] = ftdm_saturated_add(chanbuf[i], peerbuf[i]); - } - - codec_func = peerchan->native_codec == FTDM_CODEC_ULAW ? fio_slin2ulaw : peerchan->native_codec == FTDM_CODEC_ALAW ? fio_slin2alaw : NULL; - if (codec_func) { - size = sizeof(mixedbuf); - codec_func(mixedbuf, size, &size); - } - memcpy(data, mixedbuf, size); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span) -{ - ftdm_status_t ret; - pritap_t *pritap = span->signal_data; - pritap_t *p_pritap = pritap->peerspan->signal_data; - - if (ftdm_test_flag(pritap, PRITAP_RUNNING)) { - return FTDM_FAIL; - } - - ftdm_mutex_create(&pritap->pcalls_lock); - - ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD); - ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); - - ftdm_set_flag(pritap, PRITAP_RUNNING); - if (p_pritap && ftdm_test_flag(p_pritap, PRITAP_RUNNING)) { - /* our peer already started, we're the master */ - ftdm_set_flag(pritap, PRITAP_MASTER); - } - ret = ftdm_thread_create_detached(ftdm_pritap_run, span); - - if (ret != FTDM_SUCCESS) { - return ret; - } - - return ret; -} - -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span) -{ - uint32_t i; - const char *var, *val; - const char *debug = NULL; - pritap_mix_mode_t mixaudio = PRITAP_MIX_BOTH; - ftdm_channel_t *dchan = NULL; - pritap_t *pritap = NULL; - ftdm_span_t *peerspan = NULL; - pritap_iface_t iface = PRITAP_IFACE_UNKNOWN; - unsigned paramindex = 0; - - if (span->trunk_type >= FTDM_TRUNK_NONE) { - ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1.\n", ftdm_trunk_type2str(span->trunk_type)); - span->trunk_type = FTDM_TRUNK_T1; - } - - for (i = 1; i <= span->chan_count; i++) { - if (span->channels[i]->type == FTDM_CHAN_TYPE_DQ921) { - dchan = span->channels[i]; - } - } - - if (!dchan) { - ftdm_log(FTDM_LOG_ERROR, "No d-channel specified in freetdm.conf!\n"); - return FTDM_FAIL; - } - - for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { - var = ftdm_parameters[paramindex].var; - val = ftdm_parameters[paramindex].val; - ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI key=value, %s=%s\n", var, val); - - if (!strcasecmp(var, "debug")) { - debug = val; - } else if (!strcasecmp(var, "mixaudio")) { - if (ftdm_true(val) || !strcasecmp(val, "both")) { - ftdm_log(FTDM_LOG_DEBUG, "Setting mix audio mode to 'both' for span %s\n", span->name); - mixaudio = PRITAP_MIX_BOTH; - } else if (!strcasecmp(val, "peer")) { - ftdm_log(FTDM_LOG_DEBUG, "Setting mix audio mode to 'peer' for span %s\n", span->name); - mixaudio = PRITAP_MIX_PEER; - } else { - ftdm_log(FTDM_LOG_DEBUG, "Setting mix audio mode to 'self' for span %s\n", span->name); - mixaudio = PRITAP_MIX_SELF; - } - } else if (!strcasecmp(var, "interface")) { - if (!strcasecmp(val, "cpe")) { - iface = PRITAP_IFACE_CPE; - } else if (!strcasecmp(val, "net")) { - iface = PRITAP_IFACE_NET; - } else { - ftdm_log(FTDM_LOG_WARNING, "Ignoring invalid tapping interface type %s\n", val); - } - } else if (!strcasecmp(var, "peerspan")) { - if (ftdm_span_find_by_name(val, &peerspan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Invalid tapping peer span %s\n", val); - break; - } - } else { - ftdm_log(FTDM_LOG_ERROR, "Unknown pri tapping parameter [%s]", var); - } - } - - if (!peerspan) { - ftdm_log(FTDM_LOG_ERROR, "No valid peerspan was specified!\n"); - return FTDM_FAIL; - } - - pritap = ftdm_calloc(1, sizeof(*pritap)); - if (!pritap) { - return FTDM_FAIL; - } - - pritap->debug = parse_debug(debug); - pritap->dchan = dchan; - pritap->peerspan = peerspan; - pritap->mixaudio = mixaudio; - pritap->iface = iface; - - span->start = ftdm_pritap_start; - span->stop = ftdm_pritap_stop; - span->sig_read = ftdm_pritap_sig_read; - span->signal_cb = sig_cb; - - span->signal_data = pritap; - span->signal_type = FTDM_SIGTYPE_ISDN; - span->outgoing_call = pritap_outgoing_call; - - span->get_channel_sig_status = pritap_get_channel_sig_status; - span->get_span_sig_status = pritap_get_span_sig_status; - - span->state_map = &pritap_state_map; - span->state_processor = state_advance; - - return FTDM_SUCCESS; -} - -/** - * \brief FreeTDM pritap signaling and IO module definition - */ -ftdm_module_t ftdm_module = { - "pritap", - ftdm_pritap_io_init, - ftdm_pritap_unload, - ftdm_pritap_init, - NULL, - NULL, - ftdm_pritap_configure_span, -}; - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2008.vcproj deleted file mode 100644 index 565a31e505..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2008.vcproj +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2010.vcxproj.filters deleted file mode 100644 index 9c91228e09..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2010.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c deleted file mode 100755 index 8b36cdb8f3..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ /dev/null @@ -1,2437 +0,0 @@ -/* - * Copyright (c) 2009, Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Arnaldo Pereira - * Ricardo Barroetaveña - * - */ - -#ifdef __linux__ -#ifndef _DEFAULT_SOURCE -#define _DEFAULT_SOURCE -#endif -#ifndef _BSD_SOURCE -#define _BSD_SOURCE /* for strsep() */ -#endif -#include -#include -#include -#endif -#include -#include -#include -#include - -#include "ftmod_r2_io_mf_lib.h" // ftdm_r2_get_native_channel_mf_generation_iface - -/* when the user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread - * knows it must stop, and we wait for FTDM_R2_RUNNING to be clear, which tells us the - * signaling thread is done. */ -/* FIXME: what about the calls that are already up-and-running? */ -typedef enum { - FTDM_R2_RUNNING = (1 << 0), - FTDM_R2_SPAN_STARTED = (1 << 1), -} ftdm_r2_flag_t; - -/* private call information stored in ftdmchan->call_data void* ptr, - * remember that each time you add a new member to this structure - * most likely you want to clear it in ft_r2_clean_call function - * */ -#define R2CALL(ftdmchan) ((ftdm_r2_call_t*)((ftdmchan)->call_data)) -typedef struct ftdm_r2_call_t { - openr2_chan_t *r2chan; - int accepted:1; - int answer_pending:1; - int disconnect_rcvd:1; - int protocol_error:1; - int localsuspend_on_alarm:1; - ftdm_size_t dnis_index; - ftdm_size_t ani_index; - char logname[255]; - char name[10]; - ftdm_timer_id_t protocol_error_recovery_timer; -} ftdm_r2_call_t; - -/* this is just used as place holder in the stack when configuring the span to avoid using bunch of locals */ -typedef struct ft_r2_conf_s { - /* openr2 types */ - openr2_variant_t variant; - openr2_calling_party_category_t category; - openr2_log_level_t loglevel; - - /* strings */ - char *logdir; - char *advanced_protocol_file; - - /* ints */ - int32_t max_ani; - int32_t max_dnis; - int32_t mfback_timeout; - int32_t metering_pulse_timeout; - ftdm_size_t mf_dump_size; - - /* booleans */ - int immediate_accept; - int skip_category; - int get_ani_first; - int call_files; - int double_answer; - int charge_calls; - int forced_release; - int allow_collect_calls; - int use_channel_native_mf_generation; -} ft_r2_conf_t; - -/* r2 configuration stored in span->signal_data */ -typedef struct ftdm_r2_data_s { - /* span flags */ - ftdm_r2_flag_t flags; - /* openr2 handle for the R2 variant context */ - openr2_context_t *r2context; - /* category to use when making calls */ - openr2_calling_party_category_t category; - /* whether to use OR2_CALL_WITH_CHARGE or OR2_CALL_NO_CHARGE when accepting a call */ - int charge_calls:1; - /* allow or reject collect calls */ - int allow_collect_calls:1; - /* whether to use forced release when hanging up */ - int forced_release:1; - /* whether accept the call when offered, or wait until the user decides to accept */ - int accept_on_offer:1; - /* Size of multi-frequency (or any media) dumps used during protocol errors */ - ftdm_size_t mf_dump_size; - /* max time spent in ms doing real work in a single loop */ - int32_t jobmax; - /* Total number of loops performed so far */ - uint64_t total_loops; - /* number of loops per 10ms increment from 0-9ms, 10-19ms .. 100ms and above */ - uint64_t loops[11]; - /* Total number of sleeps performed so far */ - uint64_t total_sleeps; - /* number of sleeps per 10ms increment from 0-9ms, 10-19ms .. 100ms and above */ - uint64_t sleeps[11]; - /* max time spent in ms sleeping in a single loop */ - int32_t sleepmax; - /* LWP */ - uint32_t monitor_thread_id; - /* Logging directory */ - char logdir[512]; - /* scheduling context */ - ftdm_sched_t *sched; -} ftdm_r2_data_t; - -/* one element per span will be stored in g_mod_data_hash global var to keep track of them - and destroy them on module unload */ -typedef struct ftdm_r2_span_pvt_s { - openr2_context_t *r2context; /* r2 context allocated for this span */ - ftdm_hash_t *r2calls; /* hash table of allocated call data per channel for this span */ - ftdm_sched_t *sched; /* schedule for the span */ -} ftdm_r2_span_pvt_t; - -/* span monitor thread */ -static void *ftdm_r2_run(ftdm_thread_t *me, void *obj); - -/* hash of all the private span allocations - we need to keep track of them to destroy them when unloading the module - since freetdm does not notify signaling modules when destroying a span - span -> ftdm_r2_mod_allocs_t */ -static ftdm_hash_t *g_mod_data_hash; - -/* IO interface for the command API */ -static ftdm_io_interface_t g_ftdm_r2_interface; - -static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan); - -/* whether R2 call accept process is pending */ -#define IS_ACCEPTING_PENDING(ftdmchan) \ - ( (!ftdm_test_flag((ftdmchan), FTDM_CHANNEL_OUTBOUND)) && !R2CALL((ftdmchan))->accepted && \ - ((ftdmchan)->state == FTDM_CHANNEL_STATE_PROGRESS || \ - (ftdmchan)->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || \ - (ftdmchan)->state == FTDM_CHANNEL_STATE_UP) ) - -/* functions not available on windows */ -#ifdef WIN32 -#include - -static __inline int gettimeofday(struct timeval *tp, void *nothing) -{ -#ifdef WITHOUT_MM_LIB - SYSTEMTIME st; - time_t tt; - struct tm tmtm; - /* mktime converts local to UTC */ - GetLocalTime (&st); - tmtm.tm_sec = st.wSecond; - tmtm.tm_min = st.wMinute; - tmtm.tm_hour = st.wHour; - tmtm.tm_mday = st.wDay; - tmtm.tm_mon = st.wMonth - 1; - tmtm.tm_year = st.wYear - 1900; tmtm.tm_isdst = -1; - tt = mktime (&tmtm); - tp->tv_sec = tt; - tp->tv_usec = st.wMilliseconds * 1000; -#else - /** - ** The earlier time calculations using GetLocalTime - ** had a time resolution of 10ms.The timeGetTime, part - ** of multimedia apis offer a better time resolution - ** of 1ms.Need to link against winmm.lib for this - **/ - unsigned long Ticks = 0; - unsigned long Sec =0; - unsigned long Usec = 0; - Ticks = timeGetTime(); - - Sec = Ticks/1000; - Usec = (Ticks - (Sec*1000))*1000; - tp->tv_sec = Sec; - tp->tv_usec = Usec; -#endif /* WITHOUT_MM_LIB */ - (void)nothing; - return 0; -} - -static char *strsep(char **stringp, const char *delim) -{ - char *start = *stringp; - char *ptr; - - if (!start) - return NULL; - - if (!*delim) - ptr = start + strlen(start); - else { - ptr = strpbrk(start, delim); - if (!ptr) { - *stringp = NULL; - return start; - } - } - - *ptr = '\0'; - *stringp = ptr + 1; - - return start; -} -#endif /* WIN32 */ - -static void ftdm_r2_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -{ - ftdm_sigmsg_t sig; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status)); - } - return; -} - -static ftdm_call_cause_t ftdm_r2_cause_to_ftdm_cause(ftdm_channel_t *fchan, openr2_call_disconnect_cause_t cause) -{ - switch (cause) { - - case OR2_CAUSE_NORMAL_CLEARING: - return FTDM_CAUSE_NORMAL_CLEARING; - - case OR2_CAUSE_BUSY_NUMBER: - return FTDM_CAUSE_USER_BUSY; - - case OR2_CAUSE_NETWORK_CONGESTION: - return FTDM_CAUSE_SWITCH_CONGESTION; - - case OR2_CAUSE_UNALLOCATED_NUMBER: - return FTDM_CAUSE_NO_ROUTE_DESTINATION; - - case OR2_CAUSE_NUMBER_CHANGED: - return FTDM_CAUSE_NUMBER_CHANGED; - - case OR2_CAUSE_OUT_OF_ORDER: - return FTDM_CAUSE_NETWORK_OUT_OF_ORDER; - - case OR2_CAUSE_NO_ANSWER: - return FTDM_CAUSE_NO_ANSWER; - - case OR2_CAUSE_UNSPECIFIED: - return FTDM_CAUSE_NORMAL_UNSPECIFIED; - - case OR2_CAUSE_FORCED_RELEASE: - return FTDM_CAUSE_NORMAL_CLEARING; - - case OR2_CAUSE_GLARE: - return FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL; - } - ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "Mapping openr2 cause %d to unspecified\n", cause); - return FTDM_CAUSE_NORMAL_UNSPECIFIED; -} - -static openr2_call_disconnect_cause_t ftdm_r2_ftdm_cause_to_openr2_cause(ftdm_channel_t *fchan) -{ - switch (fchan->caller_data.hangup_cause) { - - case FTDM_CAUSE_NORMAL_CLEARING: - return OR2_CAUSE_NORMAL_CLEARING; - - case FTDM_CAUSE_USER_BUSY: - case FTDM_CAUSE_CALL_REJECTED: - return OR2_CAUSE_BUSY_NUMBER; - - case FTDM_CAUSE_SWITCH_CONGESTION: - return OR2_CAUSE_NETWORK_CONGESTION; - - case FTDM_CAUSE_NO_ROUTE_DESTINATION: - return OR2_CAUSE_UNALLOCATED_NUMBER; - - case FTDM_CAUSE_NUMBER_CHANGED: - return OR2_CAUSE_NUMBER_CHANGED; - - case FTDM_CAUSE_NETWORK_OUT_OF_ORDER: - case FTDM_CAUSE_SERVICE_UNAVAILABLE: - case FTDM_CAUSE_PROTOCOL_ERROR: - return OR2_CAUSE_OUT_OF_ORDER; - - case FTDM_CAUSE_NO_ANSWER: - case FTDM_CAUSE_NO_USER_RESPONSE: - return OR2_CAUSE_NO_ANSWER; - - case FTDM_CAUSE_NORMAL_UNSPECIFIED: - return OR2_CAUSE_UNSPECIFIED; - - case FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL: - return OR2_CAUSE_GLARE; - - } - ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "freetdm hangup cause %d mapped to openr2 cause %s\n", - fchan->caller_data.hangup_cause, openr2_proto_get_disconnect_string(OR2_CAUSE_UNSPECIFIED)); - return OR2_CAUSE_UNSPECIFIED; -} - -static void ft_r2_clean_call(ftdm_r2_call_t *call) -{ - openr2_chan_t *r2chan = call->r2chan; - - /* Do not memset call structure, that clears values we do not want to clear, - * like the log name set in on_call_log_created() */ - call->r2chan = r2chan; - call->accepted = 0; - call->answer_pending = 0; - call->disconnect_rcvd = 0; - call->protocol_error = 0; - call->dnis_index = 0; - call->ani_index = 0; - call->name[0] = 0; - call->protocol_error_recovery_timer = 0; -} - -static void ft_r2_accept_call(ftdm_channel_t *ftdmchan) -{ - openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; - ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; - - // FIXME: we should check the return code from openr2_chan_accept_call and handle error condition - // hanging up the call with protocol error as the reason, this openr2 API will fail only when there something - // wrong at the I/O layer or the library itself - if (r2data->charge_calls) - openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE); - else - openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE); -} - -static void ft_r2_answer_call(ftdm_channel_t *ftdmchan) -{ - openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; - // FIXME - // 1. check openr2_chan_answer_call return code - // 2. The openr2_chan_answer_call_with_mode should be used depending on user settings - // openr2_chan_answer_call_with_mode(r2chan, OR2_ANSWER_SIMPLE); - openr2_chan_answer_call(r2chan); - R2CALL(ftdmchan)->answer_pending = 0; -} - -static __inline__ ftdm_calling_party_category_t ftdm_openr2_cpc_to_r2_ftdm_cpc(openr2_calling_party_category_t cpc) -{ - switch (cpc) { - case OR2_CALLING_PARTY_CATEGORY_UNKNOWN: - return FTDM_CPC_UNKNOWN; - - case OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER: - return FTDM_CPC_ORDINARY; - - case OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER: - return FTDM_CPC_PRIORITY; - - case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_SUBSCRIBER: - return FTDM_CPC_UNKNOWN; - - case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_PRIORITY_SUBSCRIBER: - return FTDM_CPC_UNKNOWN; - - case OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT: - return FTDM_CPC_TEST; - - case OR2_CALLING_PARTY_CATEGORY_PAY_PHONE: - return FTDM_CPC_PAYPHONE; - - case OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL: - return FTDM_CPC_OPERATOR; - } - return FTDM_CPC_INVALID; -} - -static __inline openr2_calling_party_category_t ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdm_calling_party_category_t cpc) -{ - switch (cpc) { - case FTDM_CPC_UNKNOWN: - return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; - - case FTDM_CPC_OPERATOR: - return OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL; - - case FTDM_CPC_ORDINARY: - return OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; - - case FTDM_CPC_PRIORITY: - return OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER; - - case FTDM_CPC_DATA: - return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; - - case FTDM_CPC_TEST: - return OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT; - - case FTDM_CPC_PAYPHONE: - return OR2_CALLING_PARTY_CATEGORY_PAY_PHONE; - - case FTDM_CPC_OPERATOR_FRENCH: - case FTDM_CPC_OPERATOR_ENGLISH: - case FTDM_CPC_OPERATOR_GERMAN: - case FTDM_CPC_OPERATOR_RUSSIAN: - case FTDM_CPC_OPERATOR_SPANISH: - return OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL; - - case FTDM_CPC_INVALID: - return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; - } - return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; -} - -/* this function must be called with the chan mutex held! */ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) -{ - int ret; - ftdm_r2_data_t *r2data; - openr2_calling_party_category_t category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; - - r2data = ftdmchan->span->signal_data; - - ft_r2_clean_call(ftdmchan->call_data); - - if (ftdmchan->caller_data.cpc == FTDM_CPC_INVALID || ftdmchan->caller_data.cpc == FTDM_CPC_UNKNOWN) { - category = r2data->category; - } else { - category = ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdmchan->caller_data.cpc); - } - - /* start io dump */ - if (r2data->mf_dump_size) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size); - } - - ret = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, - ftdmchan->caller_data.cid_num.digits, - ftdmchan->caller_data.dnis.digits, - category, - ftdmchan->caller_data.pres == FTDM_PRES_ALLOWED ? 0 : 1); - - if (ret) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n"); - return FTDM_FAIL; - } - - ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL); - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_r2_start(ftdm_span_t *span) -{ - ftdm_r2_data_t *r2_data = span->signal_data; - ftdm_set_flag(r2_data, FTDM_R2_SPAN_STARTED); - return ftdm_thread_create_detached(ftdm_r2_run, span); -} - -static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span) -{ - ftdm_r2_data_t *r2_data = span->signal_data; - ftdm_clear_flag(r2_data, FTDM_R2_SPAN_STARTED); - while (ftdm_test_flag(r2_data, FTDM_R2_RUNNING)) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for R2 span %s\n", span->name); - ftdm_sleep(100); - } - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status) -{ - openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; - openr2_cas_signal_t rxcas, txcas; - - /* get the current rx and tx cas bits */ - openr2_chan_get_cas(r2chan, &rxcas, &txcas); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - *status = FTDM_SIG_STATE_UP; - } else if (rxcas == OR2_CAS_BLOCK || txcas == OR2_CAS_BLOCK) { - *status = FTDM_SIG_STATE_SUSPENDED; - } else { - *status = FTDM_SIG_STATE_DOWN; - } - - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) -{ - openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; - openr2_cas_signal_t rxcas, txcas; - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, - "Received request to change sig status of alarmed channel to %s", ftdm_signaling_status2str(status)); - - switch (status) { - case FTDM_SIG_STATE_SUSPENDED: - openr2_chan_set_blocked(r2chan); - /* Need to send sig status change to SUSPENDED once out of alarm */ - R2CALL(ftdmchan)->localsuspend_on_alarm = 1; - break; - case FTDM_SIG_STATE_UP: - openr2_chan_set_blocked(r2chan); - /* DO NOT send sig status change to SUSPENDED once out of alarm */ - R2CALL(ftdmchan)->localsuspend_on_alarm = 0; - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); - return FTDM_FAIL; - } - return FTDM_SUCCESS; - } - - /* get the current rx and tx cas bits */ - openr2_chan_get_cas(r2chan, &rxcas, &txcas); - - /* if we're already in the state the user asks us to be, we have nothing to do */ - if (status == FTDM_SIG_STATE_SUSPENDED && txcas == OR2_CAS_BLOCK) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel signaling status already in BLOCK state\n"); - return FTDM_SUCCESS; - } - if (status == FTDM_SIG_STATE_UP && txcas == OR2_CAS_IDLE) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel signaling status already in IDLE state\n"); - return FTDM_SUCCESS; - } - - /* set the signaling as requested and send SIGEVENT_SIGSTATUS_CHANGED, if applicable. - * see docs/sigstatus.txt for details */ - switch(status) { - case FTDM_SIG_STATE_SUSPENDED: - openr2_chan_set_blocked(r2chan); - if (rxcas == OR2_CAS_IDLE) { - ftdm_r2_set_chan_sig_status(ftdmchan, status); - } - break; - case FTDM_SIG_STATE_UP: - openr2_chan_set_idle(r2chan); - if (rxcas == OR2_CAS_IDLE) { - ftdm_r2_set_chan_sig_status(ftdmchan, status); - } - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status) -{ - ftdm_iterator_t *citer = NULL; - ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL); - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - return FTDM_FAIL; - } - /* if ALL channels are non-idle, report SUSPENDED. UP otherwise. */ - *status = FTDM_SIG_STATE_SUSPENDED; - for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { - ftdm_channel_t *fchan = ftdm_iterator_current(citer); - ftdm_channel_lock(fchan); - if (ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) { - *status = FTDM_SIG_STATE_DOWN; - ftdm_channel_unlock(fchan); - break; - } - if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) { - *status = FTDM_SIG_STATE_UP; - ftdm_channel_unlock(fchan); - break; - } - ftdm_channel_unlock(fchan); - } - ftdm_iterator_free(chaniter); - return FTDM_SUCCESS; -} - -static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) -{ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *citer = NULL; - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - return FTDM_FAIL; - } - /* iterate over all channels, setting them to the requested state */ - for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { - ftdm_channel_t *fchan = ftdm_iterator_current(citer); - /* we set channel's state through ftdm_r2_set_channel_sig_status(), since it already takes - * care of notifying the user when appropriate */ - ftdm_channel_lock(fchan); - if ((ftdm_r2_set_channel_sig_status(fchan, status)) != FTDM_SUCCESS) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to set signaling status to %s\n", ftdm_signaling_status2str(status)); - } - ftdm_channel_unlock(fchan); - } - ftdm_iterator_free(chaniter); - return FTDM_SUCCESS; -} - -/* always called from the monitor thread */ -static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) -{ - ftdm_r2_call_t *r2call; - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Received request to start call\n"); - - if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP) { - r2call = R2CALL(ftdmchan); - if (r2call->protocol_error) { - /* we had a protocol error and we were giving some recovery time, cancel the recovery timer now - * that is obvious that the other side recovered */ - ftdm_sched_cancel_timer(r2data->sched, r2call->protocol_error_recovery_timer); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancelled protocol error recovery timer\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - ftdm_channel_advance_states(ftdmchan); - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Cannot start call when channel is in use (state = %s)\n", ftdm_channel_state2str(ftdmchan->state)); - return; - } - - if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot handle request to start call in state %s\n", ftdm_channel_state2str(ftdmchan->state)); - return; - } - - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open channel during incoming call! [%s]\n", ftdmchan->last_error); - return; - } - - memset(ftdmchan->caller_data.dnis.digits, 0, sizeof(ftdmchan->caller_data.collected)); - memset(ftdmchan->caller_data.ani.digits, 0, sizeof(ftdmchan->caller_data.collected)); - - ft_r2_clean_call(ftdmchan->call_data); - r2call = R2CALL(ftdmchan); - - /* start io dump */ - if (r2data->mf_dump_size) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size); - } - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL); -} - -static void dump_mf(openr2_chan_t *r2chan); -/* only called for incoming calls when the ANI, DNIS etc is complete and the user has to decide either to accept or reject the call */ -static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, - openr2_calling_party_category_t category, int ani_restricted) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; - - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = %s, ANI restricted = %s\n", - ani, dnis, openr2_proto_get_category_string(category), ani_restricted ? "Yes" : "No"); - - /* check if this is a collect call and if we should accept it */ - if (!r2data->allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Rejecting collect call\n"); - openr2_chan_disconnect_call(r2chan, OR2_CAUSE_UNALLOCATED_NUMBER); - } else { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - ftdmchan->caller_data.cpc = ftdm_openr2_cpc_to_r2_ftdm_cpc(category); - ftdmchan->caller_data.pres = ani_restricted ? FTDM_PRES_RESTRICTED : FTDM_PRES_ALLOWED; -} - -/* - * Accepting a call in R2 is a lengthy process due to MF tones, - * when the user sends PROGRESS indication (implicitly moving the - * ftdm channel to PROGRESS state) the R2 processing loop - * does not clear FTDM_CHANNEL_STATE_CHANGE immediately as it does - * for all the other states, instead has to wait for on_call_accepted - * callback from openr2, which means the MF has ended and the progress - * indication is done, in order to clear the flag. However, if - * a protocol error or call disconnection (which is indicated using CAS bits) - * occurrs while accepting, we must clear the pending flag, this function - * takes care of that - * */ -static void clear_accept_pending(ftdm_channel_t *fchan) -{ - if (IS_ACCEPTING_PENDING(fchan)) { - ftdm_channel_complete_state(fchan); - } else if (ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_log_chan(fchan, FTDM_LOG_CRIT, "State change flag set in state %s, last state = %s\n", - ftdm_channel_state2str(fchan->state), ftdm_channel_state2str(fchan->last_state)); - ftdm_channel_complete_state(fchan); - } -} - -static void dump_mf(openr2_chan_t *r2chan) -{ - char dfile[512]; - FILE *f = NULL; - int rc = 0; - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; - if (r2data->mf_dump_size) { - char *logname = R2CALL(ftdmchan)->logname; - - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in prefix %s\n", !ftdm_strlen_zero(logname) - ? logname : r2data->logdir); - snprintf(dfile, sizeof(dfile), !ftdm_strlen_zero(logname) ? "%s.s%dc%d.input.alaw" : "%s/s%dc%d.input.alaw", - !ftdm_strlen_zero(logname) ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); - f = fopen(dfile, "wb"); - if (f) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, f); - rc = fclose(f); - if (rc) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failure closing IO input file %s: %s\n", dfile, strerror(errno)); - } - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO input in file %s, error: %s", dfile, strerror(errno)); - } - - snprintf(dfile, sizeof(dfile), !ftdm_strlen_zero(logname) ? "%s.s%dc%d.output.alaw" : "%s/s%dc%d.output.alaw", - !ftdm_strlen_zero(logname) ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); - f = fopen(dfile, "wb"); - if (f) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_OUTPUT, f); - rc = fclose(f); - if (rc) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failure closing IO output file %s: %s\n", dfile, strerror(errno)); - } - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Could not dump IO output in file %s, error: %s", dfile, strerror(errno)); - } - } -} - -static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Call accepted\n"); - - clear_accept_pending(ftdmchan); - - /* at this point the MF signaling has ended and there is no point on keep reading */ - openr2_chan_disable_read(r2chan); - - /* at this point we are no longer responsible for reading and writing, - * we are not interested in the stats anymore */ - ftdm_channel_clear_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); - - - R2CALL(ftdmchan)->accepted = 1; - - /* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */ - if (r2data->mf_dump_size) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); - } - - if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) { - if (R2CALL(ftdmchan)->answer_pending) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Answer was pending, answering now.\n"); - ft_r2_answer_call(ftdmchan); - R2CALL(ftdmchan)->answer_pending = 0; - return; - } - } else { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } -} - -static void ftdm_r2_on_call_answered(openr2_chan_t *r2chan) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Call answered\n"); - /* notify the upper layer of progress in the outbound call */ - if (OR2_DIR_FORWARD == openr2_chan_get_direction(r2chan)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - } -} - -/* may be called in the signaling or media thread depending on whether the hangup is product of MF or CAS signaling */ -static void ftdm_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Call disconnected\n"); - - clear_accept_pending(ftdmchan); - - R2CALL(ftdmchan)->disconnect_rcvd = 1; - - if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call had been disconnected already by the user\n"); - /* just ack the hangup to trigger the on_call_end callback and go down */ - openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING); - return; - } - - ftdmchan->caller_data.hangup_cause = ftdm_r2_cause_to_ftdm_cause(ftdmchan, cause); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); -} - -static void ftdm_r2_on_call_end(openr2_chan_t *r2chan) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Call finished\n"); - - /* the call is done as far as the stack is concerned, lets move to down here */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - /* in some circumstances openr2 can call on_call_init right after this, so let's advance the state right here */ - ftdm_channel_advance_states(ftdmchan); -} - -static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen) -{ -#if 0 - ftdm_log(FTDM_LOG_NOTICE, "Call read data on chan %d\n", openr2_chan_get_number(r2chan)); -#endif -} - -static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm) -{ - ftdm_channel_t *fchan = openr2_chan_get_client_data(r2chan); - - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Alarm notification %d when in state %s (sigstatus = %d)\n", - alarm, ftdm_channel_state2str(fchan->state), ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP) ? 1 : 0); - - if (alarm) { - R2CALL(fchan)->localsuspend_on_alarm = ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED) ? 1 : 0; - if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP) || ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) { - ftdm_r2_set_chan_sig_status(fchan, FTDM_SIG_STATE_DOWN); - } - } -} - -static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "OS error: %s\n", strerror(errorcode)); -} - -static void ftdm_r2_recover_from_protocol_error(void *data) -{ - openr2_chan_t *r2chan = data; - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_channel_lock(ftdmchan); - if (ftdmchan->state != FTDM_CHANNEL_STATE_HANGUP) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Recovering from protocol error but state is %s!\n", ftdm_channel_state2str(ftdmchan->state)); - goto done; - } - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - ftdm_channel_advance_states(ftdmchan); -done: - ftdm_channel_unlock(ftdmchan); -} - -static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Got protocol error when we're already down!\n"); - return; - } - - dump_mf(r2chan); - - clear_accept_pending(ftdmchan); - - R2CALL(ftdmchan)->disconnect_rcvd = 1; - R2CALL(ftdmchan)->protocol_error = 1; - - if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "The user already hung up, finishing call in protocol error\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - return; - } - - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_PROTOCOL_ERROR; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); -} - -static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end blocked in state %s\n", ftdm_channel_state2str(ftdmchan->state)); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP) - || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { - ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED); - } -} - -static void ftdm_r2_on_line_idle(openr2_chan_t *r2chan) -{ - openr2_cas_signal_t rxcas, txcas; - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - - /* get the current rx and tx cas bits */ - openr2_chan_get_cas(r2chan, &rxcas, &txcas); - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end unblocked in state %s\n", ftdm_channel_state2str(ftdmchan->state)); - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP) - && txcas == OR2_CAS_IDLE) { - /* if txcas is not idle, it means we're still blocked as far as the user is concerned, do not send SIGEVENT UP, - * it will be done when the user set the line to IDLE (if the remote is still also IDLE) */ - ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP); - } else if (txcas == OR2_CAS_BLOCK && R2CALL(ftdmchan)->localsuspend_on_alarm) { - /* the user requested to block, we do not notify about state up until the user set the bits to IDLE, however - * if we're just getting back from alarmed condition, we notify about suspended again */ - ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED); - } - R2CALL(ftdmchan)->localsuspend_on_alarm = 0; -} - -static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const char *function, int line, const char *message) -{ - switch (level) { - case OR2_LOG_NOTICE: - ftdm_log(file, function, line, FTDM_LOG_LEVEL_NOTICE, "%s", message); - break; - case OR2_LOG_WARNING: - ftdm_log(file, function, line, FTDM_LOG_LEVEL_WARNING, "%s", message); - break; - case OR2_LOG_ERROR: - ftdm_log(file, function, line, FTDM_LOG_LEVEL_ERROR, "%s", message); - break; - case OR2_LOG_STACK_TRACE: - case OR2_LOG_MF_TRACE: - case OR2_LOG_CAS_TRACE: - case OR2_LOG_DEBUG: - case OR2_LOG_EX_DEBUG: - ftdm_log(file, function, line, FTDM_LOG_LEVEL_DEBUG, "%s", message); - break; - default: - ftdm_log(FTDM_LOG_WARNING, "We should handle logging level %d here.\n", level); - ftdm_log(file, function, line, FTDM_LOG_LEVEL_DEBUG, "%s", message); - break; - } -} - -static void ftdm_r2_on_context_log(openr2_context_t *r2context, const char *file, const char *function, unsigned int line, - openr2_log_level_t level, const char *fmt, va_list ap) -{ -#define CONTEXT_TAG "Context - " - char logmsg[256]; - char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1]; - vsnprintf(logmsg, sizeof(logmsg), fmt, ap); - snprintf(completemsg, sizeof(completemsg), CONTEXT_TAG "%s", logmsg); - ftdm_r2_write_log(level, file, function, line, completemsg); -#undef CONTEXT_TAG -} - -static void ftdm_r2_on_chan_log(openr2_chan_t *r2chan, const char *file, const char *function, unsigned int line, - openr2_log_level_t level, const char *fmt, va_list ap) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - char logmsg[1024]; - char completemsg[sizeof(logmsg)]; - vsnprintf(logmsg, sizeof(logmsg), fmt, ap); - snprintf(completemsg, sizeof(completemsg), "[s%dc%d] [%d:%d] [%s] %s", - ftdmchan->span_id, ftdmchan->chan_id, ftdmchan->physical_span_id, ftdmchan->physical_chan_id, - ftdm_channel_state2str(ftdmchan->state), logmsg); - ftdm_r2_write_log(level, file, function, line, completemsg); -} - -static int ftdm_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit) -{ - ftdm_sigmsg_t sigev; - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_size_t collected_len = R2CALL(ftdmchan)->dnis_index; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "DNIS digit %c received\n", digit); - - /* save the digit we just received */ - ftdmchan->caller_data.dnis.digits[collected_len] = digit; - collected_len++; - ftdmchan->caller_data.dnis.digits[collected_len] = '\0'; - R2CALL(ftdmchan)->dnis_index = collected_len; - - /* notify the user about the new digit and check if we should stop requesting more DNIS */ - memset(&sigev, 0, sizeof(sigev)); - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - sigev.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; - if (ftdm_span_send_signal(ftdmchan->span, &sigev) == FTDM_BREAK) { - ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Requested to stop getting DNIS. Current DNIS = %s\n", ftdmchan->caller_data.dnis.digits); - return OR2_STOP_DNIS_REQUEST; - } - - /* the only other reason to stop requesting DNIS is that there is no more room to save it */ - if (collected_len == (sizeof(ftdmchan->caller_data.dnis.digits) - 1)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "No more room for DNIS. Current DNIS = %s\n", ftdmchan->caller_data.dnis.digits); - return OR2_STOP_DNIS_REQUEST; - } - - return OR2_CONTINUE_DNIS_REQUEST; -} - -static void ftdm_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_size_t collected_len = R2CALL(ftdmchan)->ani_index; - - /* check if we should drop ANI */ - if (collected_len == (sizeof(ftdmchan->caller_data.ani.digits) - 1)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "No more room for ANI, digit dropped: %c\n", digit); - return; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ANI digit %c received\n", digit); - - /* save the digit we just received */ - ftdmchan->caller_data.ani.digits[collected_len] = digit; - collected_len++; - ftdmchan->caller_data.ani.digits[collected_len] = '\0'; - R2CALL(ftdmchan)->ani_index = collected_len; -} - -static void ftdm_r2_on_billing_pulse(openr2_chan_t *r2chan) {} - -static void ftdm_r2_on_call_log_created(openr2_chan_t *r2chan, const char *logname) -{ - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_r2_call_t *r2call = R2CALL(ftdmchan); - /* this is used when dumping I/O for debugging */ - snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname); -} - -static void ftdm_r2_on_call_proceed(openr2_chan_t *r2chan) -{ - ftdm_sigmsg_t sigev; - ftdm_channel_t *fchan = openr2_chan_get_client_data(r2chan); - memset(&sigev, 0, sizeof(sigev)); - sigev.event_id = FTDM_SIGEVENT_PROCEED; - sigev.channel = fchan; - ftdm_span_send_signal(fchan->span, &sigev); -} - -static openr2_event_interface_t ftdm_r2_event_iface = { - /* .on_call_init */ ftdm_r2_on_call_init, - /* .on_call_proceed */ ftdm_r2_on_call_proceed, - /* .on_call_offered */ ftdm_r2_on_call_offered, - /* .on_call_accepted */ ftdm_r2_on_call_accepted, - /* .on_call_answered */ ftdm_r2_on_call_answered, - /* .on_call_disconnect */ ftdm_r2_on_call_disconnect, - /* .on_call_end */ ftdm_r2_on_call_end, - /* .on_call_read */ ftdm_r2_on_call_read, - /* .on_hardware_alarm */ ftdm_r2_on_hardware_alarm, - /* .on_os_error */ ftdm_r2_on_os_error, - /* .on_protocol_error */ ftdm_r2_on_protocol_error, - /* .on_line_blocked */ ftdm_r2_on_line_blocked, - /* .on_line_idle */ ftdm_r2_on_line_idle, - - /* cast seems to be needed to get rid of the annoying warning regarding format attribute */ - /* .on_context_log */ (openr2_handle_context_logging_func)ftdm_r2_on_context_log, - /* .on_dnis_digit_received */ ftdm_r2_on_dnis_digit_received, - /* .on_ani_digit_received */ ftdm_r2_on_ani_digit_received, - - /* so far we do nothing with billing pulses */ - /* .on_billing_pulse_received */ ftdm_r2_on_billing_pulse, - /* .on_call_log_created */ ftdm_r2_on_call_log_created, -}; - -static int ftdm_r2_io_set_cas(openr2_chan_t *r2chan, int cas) -{ - ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan); - ftdm_status_t status = ftdm_channel_command(ftdm_chan, FTDM_COMMAND_SET_CAS_BITS, &cas); - if (FTDM_FAIL == status) { - return -1; - } - return 0; -} - -static int ftdm_r2_io_get_cas(openr2_chan_t *r2chan, int *cas) -{ - ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan); - ftdm_status_t status = ftdm_channel_command(ftdm_chan, FTDM_COMMAND_GET_CAS_BITS, cas); - if (FTDM_FAIL == status) { - return -1; - } - return 0; -} - -static int ftdm_r2_io_flush_write_buffers(openr2_chan_t *r2chan) -{ - ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan); - ftdm_status_t status = ftdm_channel_command(ftdm_chan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL); - if (FTDM_FAIL == status) { - return -1; - } - return 0; -} - -static int ftdm_r2_io_write(openr2_chan_t *r2chan, const void *buf, int size) -{ - ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan); - ftdm_size_t outsize = size; - ftdm_status_t status = ftdm_channel_write(ftdm_chan, (void *)buf, size, &outsize); - if (FTDM_FAIL == status) { - return -1; - } - return (int)outsize; -} - -static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size) -{ - ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan); - ftdm_size_t outsize = size; - ftdm_status_t status = ftdm_channel_read(ftdm_chan, (void *)buf, &outsize); - if (FTDM_FAIL == status) { - return -1; - } - return (int)outsize; -} - -static int ftdm_r2_io_wait(openr2_chan_t *r2chan, int *flags, int block) -{ - ftdm_status_t status; - int32_t timeout; - ftdm_wait_flag_t ftdmflags = 0; - - ftdm_channel_t *fchan = openr2_chan_get_fd(r2chan); - timeout = block ? -1 : 0; - - if (*flags & OR2_IO_READ) { - ftdmflags |= FTDM_READ; - } - if (*flags & OR2_IO_WRITE) { - ftdmflags |= FTDM_WRITE; - } - if (*flags & OR2_IO_OOB_EVENT) { - ftdmflags |= FTDM_EVENTS; - } - - status = ftdm_channel_wait(fchan, &ftdmflags, timeout); - - if (FTDM_SUCCESS != status && FTDM_TIMEOUT != status) { - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Failed to wait for events on channel\n"); - return -1; - } - - *flags = 0; - if (ftdmflags & FTDM_READ) { - *flags |= OR2_IO_READ; - } - if (ftdmflags & FTDM_WRITE) { - *flags |= OR2_IO_WRITE; - } - if (ftdmflags & FTDM_EVENTS) { - *flags |= OR2_IO_OOB_EVENT; - } - - return 0; -} - -/* The following openr2 hooks never get called, read on for reasoning ... */ -/* since freetdm takes care of opening the file descriptor and using openr2_chan_new_from_fd, openr2 should never call this hook */ -static openr2_io_fd_t ftdm_r2_io_open(openr2_context_t *r2context, int channo) -{ - ftdm_log(FTDM_LOG_ERROR, "I should not be called (I/O open)!!\n"); - return NULL; -} - -/* since freetdm takes care of closing the file descriptor and uses openr2_chan_new_from_fd, openr2 should never call this hook */ -static int ftdm_r2_io_close(openr2_chan_t *r2chan) -{ - ftdm_channel_t *fchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "I should not be called (I/O close)!!\n"); - return 0; -} - -/* since freetdm takes care of opening the file descriptor and using openr2_chan_new_from_fd, openr2 should never call this hook */ -static int ftdm_r2_io_setup(openr2_chan_t *r2chan) -{ - ftdm_channel_t *fchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "I should not be called (I/O Setup)!!\n"); - return 0; -} - -static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *event) -{ - ftdm_status_t status; - ftdm_event_t *fevent = NULL; - ftdm_channel_t *ftdmchan = openr2_chan_get_fd(r2chan); - - *event = OR2_OOB_EVENT_NONE; - - status = ftdm_channel_read_event(ftdmchan, &fevent); - - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "failed to retrieve freetdm event!\n"); - return -1; - } - - if (fevent->e_type != FTDM_EVENT_OOB) { - return 0; - } - - switch (fevent->enum_id) { - case FTDM_OOB_CAS_BITS_CHANGE: - { - *event = OR2_OOB_EVENT_CAS_CHANGE; - } - break; - case FTDM_OOB_ALARM_TRAP: - { - *event = OR2_OOB_EVENT_ALARM_ON; - } - break; - case FTDM_OOB_ALARM_CLEAR: - { - *event = OR2_OOB_EVENT_ALARM_OFF; - } - break; - } - return 0; -} - -static int ftdm_r2_io_get_alarm_state(openr2_chan_t *r2chan, int *alarm) -{ - ftdm_channel_t *fchan = openr2_chan_get_fd(r2chan); - ftdm_assert_return(alarm, -1, "Alarm pointer is null\n"); - *alarm = ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM) ? 1 : 0; - return 0; -} - -static openr2_io_interface_t ftdm_r2_io_iface = { - /* .open */ ftdm_r2_io_open, /* never called */ - /* .close */ ftdm_r2_io_close, /* never called */ - /* .set_cas */ ftdm_r2_io_set_cas, - /* .get_cas */ ftdm_r2_io_get_cas, - /* .flush_write_buffers */ ftdm_r2_io_flush_write_buffers, - /* .write */ ftdm_r2_io_write, - /* .read */ ftdm_r2_io_read, - /* .setup */ ftdm_r2_io_setup, /* never called */ - /* .wait */ ftdm_r2_io_wait, - /* .get_oob_event */ ftdm_r2_io_get_oob_event, - /* .get_alarm_state */ ftdm_r2_io_get_alarm_state -}; - -/* resolve a loglevel string, such as "debug,notice,warning", to an openr2 log level integer */ -static openr2_log_level_t ftdm_r2_loglevel_from_string(const char *level) -{ - openr2_log_level_t tmplevel; - openr2_log_level_t newlevel = 0; - char *clevel = NULL; - char *logval = NULL; - - logval = ftdm_malloc(strlen(level)+1); /* alloca man page scared me, so better to use good ol' malloc */ - if (!logval) { - ftdm_log(FTDM_LOG_WARNING, "Ignoring R2 logging parameter: '%s', failed to alloc memory\n", level); - return newlevel; - } - strcpy(logval, level); - while (logval) { - clevel = strsep(&logval, ","); - if (-1 == (tmplevel = openr2_log_get_level(clevel))) { - ftdm_log(FTDM_LOG_WARNING, "Ignoring invalid R2 logging level: '%s'\n", clevel); - continue; - } - newlevel |= tmplevel; - } - ftdm_safe_free(logval); - return newlevel; -} - -static ftdm_state_map_t r2_state_map = { - { - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - - /* Outbound states */ - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - } -}; - -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) -{ - unsigned int i = 0; - int conf_failure = 0; - int intval = 0; - char schedname[255]; - const char *var = NULL, *val = NULL; - const char *log_level = "notice,warning,error"; /* default loglevel, if none is read from conf */ - ftdm_r2_data_t *r2data = NULL; - ftdm_r2_span_pvt_t *spanpvt = NULL; - ftdm_r2_call_t *r2call = NULL; - openr2_chan_t *r2chan = NULL; - unsigned paramindex = 0; - - ft_r2_conf_t r2conf = - { - /* .variant */ OR2_VAR_ITU, - /* .category */ OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER, - /* .loglevel */ OR2_LOG_ERROR | OR2_LOG_WARNING, -#ifdef WIN32 - /* .logdir */ (char *)"c:\\", -#else - /* .logdir */ (char *)"/tmp", -#endif - /* .advanced_protocol_file */ NULL, - /* .max_ani */ 10, - /* .max_dnis */ 4, - /* .mfback_timeout */ -1, - /* .metering_pulse_timeout */ -1, - /* .mf_dump_size */ 0, - /* .immediate_accept */ -1, - /* .skip_category */ -1, - /* .get_ani_first */ -1, - /* .call_files */ 0, - /* .double_answer */ -1, - /* .charge_calls */ -1, - /* .forced_release */ -1, - /* .allow_collect_calls */ -1, - /* .use_channel_native_mf_generation */ 0 - }; - - ftdm_assert_return(sig_cb != NULL, FTDM_FAIL, "No signaling cb provided\n"); - - if (span->signal_type) { - snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling."); - return FTDM_FAIL; - } - - for (; ftdm_parameters[paramindex].var; paramindex++) { - var = ftdm_parameters[paramindex].var; - val = ftdm_parameters[paramindex].val; - ftdm_log(FTDM_LOG_DEBUG, "Reading R2 parameter %s for span %d\n", var, span->span_id); - if (!strcasecmp(var, "variant")) { - if (!val) { - break; - } - if (ftdm_strlen_zero_buf(val)) { - ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 variant parameter\n"); - continue; - } - r2conf.variant = openr2_proto_get_variant(val); - if (r2conf.variant == OR2_VAR_UNKNOWN) { - ftdm_log(FTDM_LOG_ERROR, "Unknown R2 variant %s\n", val); - conf_failure = 1; - break; - } - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d for variant %s\n", span->span_id, val); - } else if (!strcasecmp(var, "category")) { - if (!val) { - break; - } - if (ftdm_strlen_zero_buf(val)) { - ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 category parameter\n"); - continue; - } - r2conf.category = openr2_proto_get_category(val); - if (r2conf.category == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) { - ftdm_log(FTDM_LOG_ERROR, "Unknown R2 caller category %s\n", val); - conf_failure = 1; - break; - } - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with default category %s\n", span->span_id, val); - } else if (!strcasecmp(var, "logdir")) { - if (!val) { - break; - } - if (ftdm_strlen_zero_buf(val)) { - ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 logdir parameter\n"); - continue; - } - r2conf.logdir = (char *)val; - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with logdir %s\n", span->span_id, val); - } else if (!strcasecmp(var, "logging")) { - if (!val) { - break; - } - if (ftdm_strlen_zero_buf(val)) { - ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 logging parameter\n"); - continue; - } - log_level = val; - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with loglevel %s\n", span->name, val); - } else if (!strcasecmp(var, "advanced_protocol_file")) { - if (!val) { - break; - } - if (ftdm_strlen_zero_buf(val)) { - ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 advanced_protocol_file parameter\n"); - continue; - } - r2conf.advanced_protocol_file = (char *)val; - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with advanced protocol file %s\n", span->name, val); - } else if (!strcasecmp(var, "mf_dump_size")) { - intval = atoi(val); - if (intval < 0) { - r2conf.mf_dump_size = FTDM_IO_DUMP_DEFAULT_BUFF_SIZE; - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with default mf_dump_size = %"FTDM_SIZE_FMT" bytes\n", span->name, r2conf.mf_dump_size); - } else { - r2conf.mf_dump_size = intval; - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with mf_dump_size = %"FTDM_SIZE_FMT" bytes\n", span->name, r2conf.mf_dump_size); - } - } else if (!strcasecmp(var, "allow_collect_calls")) { - r2conf.allow_collect_calls = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with allow collect calls max ani = %d\n", span->name, r2conf.allow_collect_calls); - } else if (!strcasecmp(var, "double_answer")) { - r2conf.double_answer = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with double answer = %d\n", span->name, r2conf.double_answer); - } else if (!strcasecmp(var, "immediate_accept")) { - r2conf.immediate_accept = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with immediate accept = %d\n", span->name, r2conf.immediate_accept); - } else if (!strcasecmp(var, "skip_category")) { - r2conf.skip_category = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with skip category = %d\n", span->name, r2conf.skip_category); - } else if (!strcasecmp(var, "forced_release")) { - r2conf.forced_release = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with forced release = %d\n", span->name, r2conf.forced_release); - } else if (!strcasecmp(var, "charge_calls")) { - r2conf.charge_calls = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with charge calls = %d\n", span->name, r2conf.charge_calls); - } else if (!strcasecmp(var, "get_ani_first")) { - r2conf.get_ani_first = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with get ani first = %d\n", span->name, r2conf.get_ani_first); - } else if (!strcasecmp(var, "call_files")) { - r2conf.call_files = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with call files = %d\n", span->name, r2conf.call_files); - } else if (!strcasecmp(var, "mfback_timeout")) { - r2conf.mfback_timeout = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with MF backward timeout = %dms\n", span->name, r2conf.mfback_timeout); - } else if (!strcasecmp(var, "metering_pulse_timeout")) { - r2conf.metering_pulse_timeout = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with metering pulse timeout = %dms\n", span->name, r2conf.metering_pulse_timeout); - } else if (!strcasecmp(var, "max_ani")) { - r2conf.max_ani = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with max ani = %d\n", span->name, r2conf.max_ani); - } else if (!strcasecmp(var, "max_dnis")) { - r2conf.max_dnis = atoi(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with max dnis = %d\n", span->name, r2conf.max_dnis); - } else if (!strcasecmp(var, "use_channel_native_mf_generation")) { - r2conf.use_channel_native_mf_generation = ftdm_true(val); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %s with \"use native channel MF generation\" = %d\n", span->name, r2conf.use_channel_native_mf_generation); - } else { - snprintf(span->last_error, sizeof(span->last_error), "Unknown R2 parameter [%s]", var); - return FTDM_FAIL; - } - } - - if (conf_failure) { - snprintf(span->last_error, sizeof(span->last_error), "R2 configuration error"); - return FTDM_FAIL; - } - - /* set span log level */ - r2conf.loglevel = ftdm_r2_loglevel_from_string(log_level); - ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with loglevel %s\n", span->span_id, log_level); - - r2data = ftdm_malloc(sizeof(*r2data)); - if (!r2data) { - snprintf(span->last_error, sizeof(span->last_error), "Failed to allocate R2 data."); - return FTDM_FAIL; - } - memset(r2data, 0, sizeof(*r2data)); - - spanpvt = ftdm_malloc(sizeof(*spanpvt)); - if (!spanpvt) { - snprintf(span->last_error, sizeof(span->last_error), "Failed to allocate private span data container."); - goto fail; - } - memset(spanpvt, 0, sizeof(*spanpvt)); - - r2data->r2context = openr2_context_new(r2conf.variant, &ftdm_r2_event_iface, r2conf.max_ani, r2conf.max_dnis); - if (!r2data->r2context) { - snprintf(span->last_error, sizeof(span->last_error), "Cannot create openr2 context for span."); - goto fail; - } - openr2_context_set_io_type(r2data->r2context, OR2_IO_CUSTOM, &ftdm_r2_io_iface); - openr2_context_set_log_level(r2data->r2context, r2conf.loglevel); - openr2_context_set_ani_first(r2data->r2context, r2conf.get_ani_first); - openr2_context_set_skip_category_request(r2data->r2context, r2conf.skip_category); - openr2_context_set_mf_back_timeout(r2data->r2context, r2conf.mfback_timeout); - openr2_context_set_metering_pulse_timeout(r2data->r2context, r2conf.metering_pulse_timeout); - openr2_context_set_double_answer(r2data->r2context, r2conf.double_answer); - openr2_context_set_immediate_accept(r2data->r2context, r2conf.immediate_accept); - - ftdm_log(FTDM_LOG_DEBUG, "Setting span %s logdir to %s\n", span->name, r2conf.logdir); - openr2_context_set_log_directory(r2data->r2context, r2conf.logdir); - snprintf(r2data->logdir, sizeof(r2data->logdir), "%s", r2conf.logdir); - - if (r2conf.advanced_protocol_file) { - openr2_context_configure_from_advanced_file(r2data->r2context, r2conf.advanced_protocol_file); - } - - if(r2conf.use_channel_native_mf_generation) { - openr2_context_set_mflib_interface(r2data->r2context, ftdm_r2_get_native_channel_mf_generation_iface()); - } - - spanpvt->r2calls = create_hashtable(FTDM_MAX_CHANNELS_SPAN, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - if (!spanpvt->r2calls) { - snprintf(span->last_error, sizeof(span->last_error), "Cannot create channel calls hash for span."); - goto fail; - } - - for (i = 1; (i <= span->chan_count) && (i <= FTDM_MAX_CHANNELS_SPAN); i++) { - r2chan = openr2_chan_new_from_fd(r2data->r2context, span->channels[i], span->channels[i]->chan_id); - if (!r2chan) { - snprintf(span->last_error, sizeof(span->last_error), "Cannot create all openr2 channels for span."); - goto fail; - } - openr2_chan_set_log_level(r2chan, r2conf.loglevel); - if (r2conf.call_files) { - openr2_chan_enable_call_files(r2chan); - } - - if (r2conf.use_channel_native_mf_generation) { - /* Allocate a new write handle per r2chan */ - ftdm_r2_mf_write_handle_t *mf_write_handle = ftdm_calloc(1, sizeof(*mf_write_handle)); - /* Associate to the FreeTDM channel */ - mf_write_handle->ftdmchan = span->channels[i]; - /* Make sure the FreeTDM channel supports MF the generation feature */ - if (!ftdm_channel_test_feature(mf_write_handle->ftdmchan, FTDM_CHANNEL_FEATURE_MF_GENERATE)) { - ftdm_log_chan_msg(mf_write_handle->ftdmchan, FTDM_LOG_ERROR, - "FreeTDM channel does not support native MF generation: " - "\"use_channel_native_mf_generation\" configuration parameter cannot" - " be used\n"); - goto fail; - } - /* Associate the mf_write_handle to the openR2 channel */ - openr2_chan_set_mflib_handles(r2chan, mf_write_handle, NULL); - } - - r2call = ftdm_calloc(1, sizeof(*r2call)); - if (!r2call) { - snprintf(span->last_error, sizeof(span->last_error), "Cannot create all R2 call data structures for the span."); - ftdm_safe_free(r2chan); - goto fail; - } - openr2_chan_set_logging_func(r2chan, ftdm_r2_on_chan_log); - openr2_chan_set_client_data(r2chan, span->channels[i]); - r2call->r2chan = r2chan; - span->channels[i]->call_data = r2call; - /* value and key are the same so just free one of them */ - snprintf(r2call->name, sizeof(r2call->name), "chancall%d", i); - hashtable_insert(spanpvt->r2calls, (void *)r2call->name, r2call, HASHTABLE_FLAG_FREE_VALUE); - } - r2data->mf_dump_size = r2conf.mf_dump_size; - r2data->category = r2conf.category; - r2data->allow_collect_calls = r2conf.allow_collect_calls; - r2data->flags = 0; - r2data->charge_calls = r2conf.charge_calls; - r2data->forced_release = r2conf.forced_release; - spanpvt->r2context = r2data->r2context; - - /* just the value must be freed by the hash */ - hashtable_insert(g_mod_data_hash, (void *)span->name, spanpvt, HASHTABLE_FLAG_FREE_VALUE); - - span->start = ftdm_r2_start; - span->stop = ftdm_r2_stop; - span->sig_read = NULL; - span->sig_write = NULL; - - span->signal_cb = sig_cb; - span->signal_type = FTDM_SIGTYPE_R2; - span->signal_data = r2data; - span->outgoing_call = r2_outgoing_call; - span->get_span_sig_status = ftdm_r2_get_span_sig_status; - span->set_span_sig_status = ftdm_r2_set_span_sig_status; - span->get_channel_sig_status = ftdm_r2_get_channel_sig_status; - span->set_channel_sig_status = ftdm_r2_set_channel_sig_status; - - span->state_map = &r2_state_map; - span->state_processor = ftdm_r2_state_advance; - - /* use signals queue */ - ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); - - /* we can skip states (going straight from RING to UP) */ - ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES); - - /* setup the scheduler */ - snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name); - ftdm_assert(ftdm_sched_create(&r2data->sched, schedname) == FTDM_SUCCESS, "Failed to create schedule!\n"); - spanpvt->sched = r2data->sched; - - return FTDM_SUCCESS; - -fail: - - if (r2data && r2data->r2context) { - openr2_context_delete(r2data->r2context); - } - if (spanpvt && spanpvt->r2calls) { - hashtable_destroy(spanpvt->r2calls); - } - ftdm_safe_free(r2data); - ftdm_safe_free(spanpvt); - return FTDM_FAIL; - -} - -/* the channel must be locked when calling this function */ -static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) -{ - ftdm_sigmsg_t sigev; - ftdm_status_t ret; - ftdm_r2_call_t *r2call = R2CALL(ftdmchan); - openr2_chan_t *r2chan = r2call->r2chan; - ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; - - memset(&sigev, 0, sizeof(sigev)); - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - - ret = FTDM_SUCCESS; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state)); - - if (IS_ACCEPTING_PENDING(ftdmchan)) { - /* - Moving to PROGRESS, PROGRESS_MEDIA or UP means that we must accept the call first, and accepting - the call in R2 means sending a tone, then waiting for the acknowledge from the other end, - since all of that requires sending and detecting tones, it takes a few milliseconds (I'd say around 100) - which means during that time the user should not try to perform any operations like answer, hangup or anything - else, therefore we DO NOT clear the FTDM_CHANNEL_STATE_CHANGE flag here, we rely on ftdm_io.c to block - the user thread until we're done with the accept (see on_call_accepted callback) and then we clear the state change flag, - otherwise we have a race condition between freetdm calling openr2_chan_answer_call and openr2 accepting the call first, - if freetdm calls openr2_chan_answer_call before the accept cycle completes, openr2 will fail to answer the call */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "State ack for state %s will have to wait a bit\n", ftdm_channel_state2str(ftdmchan->state)); - } else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){ - ftdm_channel_complete_state(ftdmchan); - } - - switch (ftdmchan->state) { - - /* starting an incoming call */ - case FTDM_CHANNEL_STATE_COLLECT: - { - uint32_t interval = 0; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); - ftdm_assert(interval != 0, "Invalid interval!"); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting processing of incoming call with interval %d\n", interval); - openr2_chan_enable_read(r2chan); - } - break; - - /* starting an outgoing call */ - case FTDM_CHANNEL_STATE_DIALING: - { - uint32_t interval = 0; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); - ftdm_assert(interval != 0, "Invalid interval!"); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting outgoing call with interval %d\n", interval); - openr2_chan_enable_read(r2chan); - } - break; - - /* incoming call was offered */ - case FTDM_CHANNEL_STATE_RING: - - /* notify the user about the new call */ - sigev.event_id = FTDM_SIGEVENT_START; - ftdm_span_send_signal(ftdmchan->span, &sigev); - break; - - /* the call is making progress */ - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (!r2call->accepted) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n"); - ft_r2_accept_call(ftdmchan); - } - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n"); - sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - ftdm_span_send_signal(ftdmchan->span, &sigev); - } - } - break; - - /* the call was answered */ - case FTDM_CHANNEL_STATE_UP: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n"); - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (!r2call->accepted) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n"); - // the answering will be done in the on_call_accepted handler - ft_r2_accept_call(ftdmchan); - r2call->answer_pending = 1; - } else { - ft_r2_answer_call(ftdmchan); - } - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying of call answered\n"); - sigev.event_id = FTDM_SIGEVENT_UP; - ftdm_span_send_signal(ftdmchan->span, &sigev); - } - } - break; - - /* just got hangup */ - case FTDM_CHANNEL_STATE_HANGUP: - { - if (!r2call->disconnect_rcvd) { - openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); - /* overwrite the hangup cause if this is an incoming call and forced_release is set */ - if (openr2_chan_get_direction(r2chan) == OR2_DIR_BACKWARD && r2data->forced_release) { - disconnect_cause = OR2_CAUSE_FORCED_RELEASE; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); - /* this will disconnect the call, but need to wait for the call end before moving to DOWN */ - openr2_chan_disconnect_call(r2chan, disconnect_cause); - } else if (!r2call->protocol_error) { - /* just ack the hangup, on_call_end will be called by openr2 right after */ - openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n"); - /* do not set to down yet, give some time for recovery */ - ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100, - ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer); - } - } - break; - - case FTDM_CHANNEL_STATE_TERMINATING: - { - /* if the call has not been started yet we must go to HANGUP right here */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } else { - openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); - /* notify the user of the call terminating and we wait for the user to move us to hangup */ - sigev.event_id = FTDM_SIGEVENT_STOP; - ftdm_span_send_signal(ftdmchan->span, &sigev); - } - } - break; - - /* finished call for good */ - case FTDM_CHANNEL_STATE_DOWN: - { - if (ftdmchan->last_state != FTDM_CHANNEL_STATE_RESET) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n"); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Reset Complete\n"); - } - ret = FTDM_BREAK; - } - break; - - /* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */ - case FTDM_CHANNEL_STATE_RINGING: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n"); - } - break; - - /* put the r2 channel back to IDLE, close ftdmchan and set it's state as DOWN */ - case FTDM_CHANNEL_STATE_RESET: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RESET indicated, putting the R2 channel back to IDLE\n"); - openr2_chan_set_idle(r2chan); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - - default: - { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state)); - } - break; - } - - if (ret == FTDM_BREAK) { - ftdm_channel_t *closed_chan; - closed_chan = ftdmchan; - ftdm_channel_close(&closed_chan); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "State processing ended.\n"); - } - return ret; -} - -static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) -{ - openr2_chan_t *r2chan = NULL; - ftdm_channel_t *ftdmchan = NULL; - ftdm_r2_call_t *call = NULL; - ftdm_status_t status; - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_r2_data_t *r2data = span->signal_data; - int waitms = 20; - unsigned int i; - int res, ms; - int index = 0; - struct timeval start, end; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *citer = NULL; - uint32_t txqueue_size = 4; - short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); - - /* as long as this thread is running, this flag is set */ - ftdm_set_flag(r2data, FTDM_R2_RUNNING); - -#ifdef __linux__ - r2data->monitor_thread_id = syscall(SYS_gettid); -#endif - - ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %u started.\n", r2data->monitor_thread_id); - r2chan = NULL; - chaniter = ftdm_span_get_chan_iterator(span, NULL); - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - goto done; - } - for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { - ftdmchan = ftdm_iterator_current(citer); - ftdm_channel_lock(ftdmchan); - r2chan = R2CALL(ftdmchan)->r2chan; - openr2_chan_set_span_id(r2chan, span->span_id); - openr2_chan_set_idle(r2chan); - openr2_chan_process_cas_signaling(r2chan); - ftdm_channel_unlock(ftdmchan); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txqueue_size); - } - - memset(&start, 0, sizeof(start)); - memset(&end, 0, sizeof(end)); - while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_SPAN_STARTED)) { - res = gettimeofday(&end, NULL); - if (res) { - ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno)); - } - if (start.tv_sec) { - ms = ((end.tv_sec - start.tv_sec) * 1000) - + ((( 1000000 + end.tv_usec - start.tv_usec) / 1000) - 1000); - if (ms < 0) { - ms = 0; - } - if (ms > r2data->jobmax) { - r2data->jobmax = ms; - } - index = (ms / 10); - index = (index > 10) ? 10 : index; - r2data->loops[index]++; - r2data->total_loops++; - } - - /* run any span timers */ - ftdm_sched_run(r2data->sched); - - /* deliver the actual channel events to the user now without any channel locking */ - ftdm_span_trigger_signals(span); - - /* figure out what event to poll each channel for. POLLPRI when the channel is down, - * POLLPRI|POLLIN|POLLOUT otherwise */ - memset(poll_events, 0, sizeof(short)*span->chan_count); - citer = ftdm_span_get_chan_iterator(span, chaniter); - if (!citer) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - goto done; - } - for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) { - ftdmchan = ftdm_iterator_current(citer); - r2chan = R2CALL(ftdmchan)->r2chan; - poll_events[i] = FTDM_EVENTS; - if (openr2_chan_get_read_enabled(r2chan)) { - poll_events[i] |= FTDM_READ; - } - } - status = ftdm_span_poll_event(span, waitms, poll_events); - - /* run any span timers */ - ftdm_sched_run(r2data->sched); - - res = gettimeofday(&start, NULL); - if (res) { - ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno)); - } - - if (FTDM_FAIL == status) { - ftdm_log(FTDM_LOG_CRIT, "Failure waiting I/O! [%s]\n", span->channels[1]->last_error); - continue; - } - - ms = ((start.tv_sec - end.tv_sec) * 1000) - + ((( 1000000 + start.tv_usec - end.tv_usec) / 1000) - 1000); - if (ms < 0) { - ms = 0; - } - if (ms > r2data->sleepmax) { - r2data->sleepmax = ms; - } - index = (ms / 15); - index = (index > 10) ? 10 : index; - r2data->sleeps[index]++; - r2data->total_sleeps++; - - /* this main loop takes care of MF and CAS signaling during call setup and tear down - * for every single channel in the span, do not perform blocking operations here! */ - citer = ftdm_span_get_chan_iterator(span, chaniter); - for ( ; citer; citer = ftdm_iterator_next(citer)) { - ftdmchan = ftdm_iterator_current(citer); - - ftdm_channel_lock(ftdmchan); - - call = R2CALL(ftdmchan); - - /* This let knows the core and io signaling hooks know that - * read/writes come from us and should be allowed */ - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED); - - ftdm_channel_advance_states(ftdmchan); - - r2chan = call->r2chan; - openr2_chan_process_signaling(r2chan); - - ftdm_channel_advance_states(ftdmchan); - - if (!call->accepted) { - /* if the call is not accepted we do not want users reading */ - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED); - } - - ftdm_channel_unlock(ftdmchan); - } - } - -done: - citer = ftdm_span_get_chan_iterator(span, chaniter); - for ( ; citer; citer = ftdm_iterator_next(citer)) { - ftdmchan = ftdm_iterator_current(citer); - ftdm_channel_lock(ftdmchan); - r2chan = R2CALL(ftdmchan)->r2chan; - openr2_chan_set_blocked(r2chan); - ftdm_channel_unlock(ftdmchan); - } - - ftdm_iterator_free(chaniter); - ftdm_safe_free(poll_events); - - ftdm_clear_flag(r2data, FTDM_R2_RUNNING); - ftdm_log(FTDM_LOG_DEBUG, "R2 thread ending.\n"); - - return NULL; -} - -static void __inline__ block_channel(ftdm_channel_t *fchan, ftdm_stream_handle_t *stream) -{ - openr2_chan_t *r2chan = R2CALL(fchan)->r2chan; - ftdm_mutex_lock(fchan->mutex); - if (fchan->state != FTDM_CHANNEL_STATE_DOWN) { - stream->write_function(stream, "cannot block channel %d:%d because has a call in progress\n", - fchan->span_id, fchan->chan_id); - } else { - if (!openr2_chan_set_blocked(r2chan)) { - ftdm_set_flag(fchan, FTDM_CHANNEL_SUSPENDED); - stream->write_function(stream, "blocked channel %d:%d\n", - fchan->span_id, fchan->chan_id); - } else { - stream->write_function(stream, "failed to block channel %d:%d\n", - fchan->span_id, fchan->chan_id); - } - } - ftdm_mutex_unlock(fchan->mutex); -} - -static void __inline__ unblock_channel(ftdm_channel_t *fchan, ftdm_stream_handle_t *stream) -{ - openr2_chan_t *r2chan = R2CALL(fchan)->r2chan; - ftdm_mutex_lock(fchan->mutex); - if (!openr2_chan_set_idle(r2chan)) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED); - stream->write_function(stream, "unblocked channel %d:%d\n", - fchan->span_id, fchan->chan_id); - } else { - stream->write_function(stream, "failed to unblock channel %d:%d\n", - fchan->span_id, fchan->chan_id); - } - ftdm_mutex_unlock(fchan->mutex); -} - -#define FT_SYNTAX "USAGE:\n" \ -"--------------------------------------------------------------------------------\n" \ -"ftdm r2 status \n" \ -"ftdm r2 loopstats \n" \ -"ftdm r2 block|unblock []\n" \ -"ftdm r2 version\n" \ -"ftdm r2 variants\n" \ -"--------------------------------------------------------------------------------\n" -static FIO_API_FUNCTION(ftdm_r2_api) -{ - ftdm_span_t *span = NULL; - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - int span_id = 0; - unsigned int chan_id = 0; - unsigned int i = 0; - ftdm_r2_data_t *r2data = NULL; - openr2_chan_t *r2chan = NULL; - openr2_context_t *r2context = NULL; - openr2_variant_t r2variant; - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - if (argc >= 2) { - if (!strcasecmp(argv[0], "block")) { - int span_id = atoi(argv[1]); - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - - if (span->start != ftdm_r2_start) { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - - if (argc > 2) { - chan_id = atoi(argv[2]); - if (chan_id && chan_id <= span->chan_count) { - block_channel(span->channels[chan_id], stream); - } else { - stream->write_function(stream, "-ERR invalid chan %d.\n", chan_id); - } - } else { - for (i = 1; i <= span->chan_count; i++) { - block_channel(span->channels[i], stream); - } - } - stream->write_function(stream, "+OK blocked.\n"); - goto done; - } else { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - } - - if (!strcasecmp(argv[0], "unblock")) { - span_id = atoi(argv[1]); - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - - if (span->start != ftdm_r2_start) { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - - if (argc > 2) { - chan_id = atoi(argv[2]); - if (chan_id && chan_id <= span->chan_count) { - unblock_channel(span->channels[chan_id], stream); - } else { - stream->write_function(stream, "-ERR invalid chan %d.\n", chan_id); - } - } else { - for (i = 1; i <= span->chan_count; i++) { - unblock_channel(span->channels[i], stream); - } - } - - stream->write_function(stream, "+OK.\n"); - goto done; - } else { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - - } - - if (!strcasecmp(argv[0], "status")) { - //openr2_chan_stats_t stats; - span_id = atoi(argv[1]); - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - if (span->start != ftdm_r2_start) { - stream->write_function(stream, "-ERR not an R2 span.\n"); - goto done; - } - if (!(r2data = span->signal_data)) { - stream->write_function(stream, "-ERR invalid span. No R2 signal data in span.\n"); - goto done; - } - r2context = r2data->r2context; - r2variant = openr2_context_get_variant(r2context); - stream->write_function(stream, - "Variant: %s\n" - "Max ANI: %d\n" - "Max DNIS: %d\n" - "ANI First: %s\n" - "Immediate Accept: %s\n" - "Job Thread: %u\n" - "Job Max ms: %d\n" - "Job Loops: %lu\n", - openr2_proto_get_variant_string(r2variant), - openr2_context_get_max_ani(r2context), - openr2_context_get_max_dnis(r2context), - openr2_context_get_ani_first(r2context) ? "Yes" : "No", - openr2_context_get_immediate_accept(r2context) ? "Yes" : "No", - r2data->monitor_thread_id, - r2data->jobmax, - r2data->total_loops); - stream->write_function(stream, "\n"); - stream->write_function(stream, "%4s %-12.12s %-12.12s\n", "Channel", "Tx CAS", "Rx CAS"); - for (i = 1; i <= span->chan_count; i++) { - r2chan = R2CALL(span->channels[i])->r2chan; - stream->write_function(stream, "%4d %-12.12s %-12.12s\n", - span->channels[i]->chan_id, - openr2_chan_get_tx_cas_string(r2chan), - openr2_chan_get_rx_cas_string(r2chan)); - } - stream->write_function(stream, "\n"); - stream->write_function(stream, "+OK.\n"); - goto done; - } else { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - } - - if (!strcasecmp(argv[0], "loopstats")) { - int range; - float pct; - span_id = atoi(argv[1]); - - if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) { - if (span->start != ftdm_r2_start) { - stream->write_function(stream, "-ERR not an R2 span.\n"); - goto done; - } - if (!(r2data = span->signal_data)) { - stream->write_function(stream, "-ERR invalid span. No R2 signal data in span.\n"); - goto done; - } - stream->write_function(stream, "-- Working --\n"); - stream->write_function(stream, "Total loops: %llu\n", r2data->total_loops); - range = 0; - for (i = 0; i < ftdm_array_len(r2data->loops); i++) { - pct = 100*(float)r2data->loops[i]/r2data->total_loops; - if ((i + 1) == ftdm_array_len(r2data->loops)) { - stream->write_function(stream, ">= %dms: %llu - %.03lf%%\n", range, r2data->loops[i], pct); - } else { - stream->write_function(stream, "%d-%dms: %llu - %.03lf%%\n", range, range + 9, r2data->loops[i], pct); - } - range += 10; - } - stream->write_function(stream, "\n"); - - stream->write_function(stream, "-- Sleeping --\n"); - stream->write_function(stream, "Total sleeps: %llu\n", r2data->total_sleeps); - range = 0; - for (i = 0; i < ftdm_array_len(r2data->sleeps); i++) { - pct = 100*(float)r2data->sleeps[i]/r2data->total_sleeps; - if ((i + 1) == ftdm_array_len(r2data->sleeps)) { - stream->write_function(stream, ">= %dms: %llu - %.03lf%%\n", range, r2data->sleeps[i], pct); - } else { - stream->write_function(stream, "%d-%dms: %llu - %.03lf%%\n", range, range + 14, r2data->sleeps[i], pct); - } - range += 15; - } - stream->write_function(stream, "\n"); - - stream->write_function(stream, "+OK.\n"); - goto done; - } else { - stream->write_function(stream, "-ERR invalid span.\n"); - goto done; - } - } - - } - - if (argc == 1) { - if (!strcasecmp(argv[0], "version")) { - stream->write_function(stream, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision()); - stream->write_function(stream, "+OK.\n"); - goto done; - } - - if (!strcasecmp(argv[0], "variants")) { - int32_t numvariants = 0; - const openr2_variant_entry_t *variants = openr2_proto_get_variant_list(&numvariants); - if (!variants) { - stream->write_function(stream, "-ERR failed to retrieve openr2 variant list.\n"); - goto done; - } -#define VARIANT_FORMAT "%4s %40s\n" - stream->write_function(stream, VARIANT_FORMAT, "Variant Code", "Country"); - numvariants--; - for (; numvariants; numvariants--) { - stream->write_function(stream, VARIANT_FORMAT, variants[numvariants].name, variants[numvariants].country); - } - stream->write_function(stream, "+OK.\n"); -#undef VARIANT_FORMAT - goto done; - } - } - - stream->write_function(stream, "%s", FT_SYNTAX); - -done: - - ftdm_safe_free(mycmd); - - return FTDM_SUCCESS; - -} - -static FIO_IO_LOAD_FUNCTION(ftdm_r2_io_init) -{ - assert(fio != NULL); - memset(&g_ftdm_r2_interface, 0, sizeof(g_ftdm_r2_interface)); - - g_ftdm_r2_interface.name = "r2"; - g_ftdm_r2_interface.api = ftdm_r2_api; - - *fio = &g_ftdm_r2_interface; - - return FTDM_SUCCESS; -} - -static FIO_SIG_LOAD_FUNCTION(ftdm_r2_init) -{ - g_mod_data_hash = create_hashtable(10, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - if (!g_mod_data_hash) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -static FIO_SIG_UNLOAD_FUNCTION(ftdm_r2_destroy) -{ - ftdm_hash_iterator_t *i = NULL; - ftdm_r2_span_pvt_t *spanpvt = NULL; - const void *key = NULL; - void *val = NULL; - for (i = hashtable_first(g_mod_data_hash); i; i = hashtable_next(i)) { - hashtable_this(i, &key, NULL, &val); - if (key && val) { - spanpvt = val; - openr2_context_delete(spanpvt->r2context); - hashtable_destroy(spanpvt->r2calls); - ftdm_sched_destroy(&spanpvt->sched); - } - } - hashtable_destroy(g_mod_data_hash); - return FTDM_SUCCESS; -} - -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - /* .name */ "r2", - /* .io_load */ ftdm_r2_io_init, - /* .io_unload */ NULL, - /* .sig_load */ ftdm_r2_init, - /* .sig_configure */ NULL, - /* .sig_unload */ ftdm_r2_destroy, - /* .configure_span_signaling */ ftdm_r2_configure_span_signaling -}; - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2_io_mf_lib.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2_io_mf_lib.c deleted file mode 100755 index 0b17885ba9..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2_io_mf_lib.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2011 Sebastien Trottier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include - -#include - -#include "ftmod_r2_io_mf_lib.h" - -/* Convert openr2 MF tone enum value to FreeTDM MF tone value - 1-15 bitwise OR FTDM_MF_DIRECTION_FORWARD/BACKWARD - 0 (stop playing) - openr2_mf_tone_t defined in r2proto.h -*/ -static int ftdm_r2_openr2_mf_tone_to_ftdm_mf_tone(openr2_mf_tone_t - openr2_tone_value, int forward_signals) -{ - int tone; - - switch (openr2_tone_value) { - case 0: return 0; -#define TONE_FROM_NAME(name) case OR2_MF_TONE_##name: tone = name; break; - TONE_FROM_NAME(1) - TONE_FROM_NAME(2) - TONE_FROM_NAME(3) - TONE_FROM_NAME(4) - TONE_FROM_NAME(5) - TONE_FROM_NAME(6) - TONE_FROM_NAME(7) - TONE_FROM_NAME(8) - TONE_FROM_NAME(9) - TONE_FROM_NAME(10) - TONE_FROM_NAME(11) - TONE_FROM_NAME(12) - TONE_FROM_NAME(13) - TONE_FROM_NAME(14) - TONE_FROM_NAME(15) -#undef TONE_FROM_NAME - default: - ftdm_assert(0, "Invalid openr2_tone_value\n"); - return -1; - } - - /* Add flag corresponding to direction */ - if (forward_signals) { - tone |= FTDM_MF_DIRECTION_FORWARD; - } else { - tone |= FTDM_MF_DIRECTION_BACKWARD; - } - - return tone; -} - -/* MF generation routines (using IO command of a FreeTDM channel) - write_init stores the direction of the MF to generate */ -static void *ftdm_r2_io_mf_write_init(ftdm_r2_mf_write_handle_t *handle, int forward_signals) -{ - ftdm_log_chan(handle->ftdmchan, FTDM_LOG_DEBUG, "ftdm_r2_io_mf_write_init, " - "forward = %d\n", forward_signals); - - handle->fwd = forward_signals; - return handle; -} - -static int ftdm_r2_io_mf_generate_tone(ftdm_r2_mf_write_handle_t *handle, int16_t buffer[], int samples) -{ - /* Our mf_want_generate implementation always return 0, so mf_generate_tone should never be called */ - ftdm_assert(0, "ftdm_r2_io_mf_generate_tone not implemented\n"); - return 0; -} - -/* \brief mf_select_tone starts tone generation or stops current tone - * \return 0 on success, -1 on error - */ -static int ftdm_r2_io_mf_select_tone(ftdm_r2_mf_write_handle_t *handle, char signal) -{ - int tone; /* (0, 1-15) (0 meaning to stop playing) */ - - ftdm_log_chan(handle->ftdmchan, FTDM_LOG_DEBUG, "ftdm_r2_io_mf_select_tone, " - "signal = %c\n", signal); - - if (-1 == (tone = ftdm_r2_openr2_mf_tone_to_ftdm_mf_tone(signal, handle->fwd))) { - return -1; - } - - /* Start/stop playback directly here, as select tone is called each time a tone - is started or stopped (called if tone changes, but silence is tone 0, - triggering a tone change) */ - if (tone > 0) { - ftdm_channel_command(handle->ftdmchan, FTDM_COMMAND_START_MF_PLAYBACK, &tone); - } else { - /* tone 0 means to stop current tone */ - ftdm_channel_command(handle->ftdmchan, FTDM_COMMAND_STOP_MF_PLAYBACK, NULL); - } - return 0; -} - -static int ftdm_r2_io_mf_want_generate(ftdm_r2_mf_write_handle_t *handle, int signal) -{ - /* Return 0, meaning mf_generate_tone doesn't need to be called */ - return 0; -} - -/* MF lib interface that generate MF tones via FreeTDM channel IO commands - MF detection using the default openr2 provider (r2engine) */ -static openr2_mflib_interface_t g_mf_ftdm_io_iface = { - /* .mf_read_init */ (openr2_mf_read_init_func)openr2_mf_rx_init, - /* .mf_write_init */ (openr2_mf_write_init_func)ftdm_r2_io_mf_write_init, - /* .mf_detect_tone */ (openr2_mf_detect_tone_func)openr2_mf_rx, - /* .mf_generate_tone */ (openr2_mf_generate_tone_func)ftdm_r2_io_mf_generate_tone, - /* .mf_select_tone */ (openr2_mf_select_tone_func)ftdm_r2_io_mf_select_tone, - /* .mf_want_generate */ (openr2_mf_want_generate_func)ftdm_r2_io_mf_want_generate, - /* .mf_read_dispose */ NULL, - /* .mf_write_dispose */ NULL -}; - -openr2_mflib_interface_t *ftdm_r2_get_native_channel_mf_generation_iface() -{ - return &g_mf_ftdm_io_iface; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2_io_mf_lib.h b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2_io_mf_lib.h deleted file mode 100755 index cf3c171c3d..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2_io_mf_lib.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2011 Sebastien Trottier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _FTMOD_R2_IO_MFLIB_H_ -#define _FTMOD_R2_IO_MFLIB_H_ - -#include - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -/* MFC/R2 tone generator handle (mf_write_handle) */ -typedef struct { - /*! FTDM channel performing the MF generation */ - ftdm_channel_t *ftdmchan; - /*! 1 if generating forward tones, otherwise generating reverse tones. */ - int fwd; -} ftdm_r2_mf_write_handle_t; - -/* MF lib interface that generate MF tones via FreeTDM channel IO commands - MF detection using the default openr2 provider (r2engine) */ -openr2_mflib_interface_t *ftdm_r2_get_native_channel_mf_generation_iface(void); - -#if defined(__cplusplus) -} /* endif extern "C" */ -#endif - -#endif /* endif defined _FTMOD_R2_IO_MFLIB_H_ */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj deleted file mode 100644 index f6263907e1..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj.filters deleted file mode 100644 index 5f592fa9ef..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj.filters +++ /dev/null @@ -1,57 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c deleted file mode 100644 index ed0a99dc95..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ /dev/null @@ -1,1563 +0,0 @@ - -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "ftmod_sangoma_isdn.h" - -#ifdef FTDM_DEBUG_CHAN_MEMORY -#include -#endif - -static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj); -static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span); -static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span); -static ftdm_status_t ftdm_sangoma_isdn_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf); - -ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event); -static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event); -static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan); -static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event); -static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan); -static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *ftdmchan); - -static ftdm_io_interface_t g_sngisdn_io_interface; -static sng_isdn_event_interface_t g_sngisdn_event_interface; - -ftdm_sngisdn_data_t g_sngisdn_data; - -SNGISDN_ENUM_NAMES(SNGISDN_TRANSFER_TYPE_NAMES, SNGISDN_TRANSFER_TYPE_STRINGS) -SNGISDN_STR2ENUM(ftdm_str2sngisdn_transfer_type, sngisdn_transfer_type2str, sngisdn_transfer_type_t, SNGISDN_TRANSFER_TYPE_NAMES, SNGISDN_TRANSFER_INVALID) - -ftdm_state_map_t sangoma_isdn_state_map = { - { - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_DIALING, - FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_GET_CALLERID, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_GET_CALLERID, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_TRANSFER, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TRANSFER, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TRANSFER, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_TERMINATING,FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_ANY, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_DIALING, - FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, - FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - } - } -}; - -static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - sngisdn_snd_event(signal_data, event); - - switch (event) { - /* Check if the span woke up from power-saving mode */ - case FTDM_OOB_ALARM_CLEAR: - if (FTDM_SPAN_IS_BRI(span)) { - ftdm_channel_t *ftdmchan; - sngisdn_chan_data_t *sngisdn_info; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); - sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; - - if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) { - ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); - - ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) ftdmchan->call_data, NULL); - } - } - ftdm_iterator_free(chaniter); - } - break; - default: - /* Ignore other events for now */ - break; - } -} - -static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *dchan) -{ - ftdm_status_t ret_status; - uint32_t queue_size; - - queue_size = SNGISDN_DCHAN_QUEUE_LEN; - ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &queue_size); - ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Rx Queue size"); - - queue_size = SNGISDN_DCHAN_QUEUE_LEN; - ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &queue_size); - ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Tx Queue size"); - - RETVOID; -} - -static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan) -{ - ftdm_status_t ret_status; - ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED; - ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_LINK_STATUS, &status); - if (ret_status != FTDM_SUCCESS) { - ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to wake-up link\n"); - } - return; -} - -static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj) -{ - uint8_t data[8192]; - unsigned i = 0; - ftdm_status_t status = FTDM_SUCCESS; - ftdm_span_t *span = (ftdm_span_t*) obj; - ftdm_size_t len = 0; - ftdm_channel_t *ftdmchan = NULL; - unsigned waitms = 10000; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *citer = NULL; - ftdm_event_t *event; - short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); - - /* Initialize the d-channel */ - chaniter = ftdm_span_get_chan_iterator(span, NULL); - if (!chaniter) { - ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); - goto done; - } - - while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) { - len = 1000; - waitms = 1000; - memset(poll_events, 0, sizeof(short)*span->chan_count); - - for (i = 0, citer = ftdm_span_get_chan_iterator(span, chaniter); citer; citer = ftdm_iterator_next(citer), i++) { - ftdmchan = ftdm_iterator_current(citer); - - poll_events[i] |= FTDM_EVENTS; - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED)) { - poll_events[i] |= FTDM_READ; - waitms = 20; - } - } else { - /* We always read the d-channel */ - poll_events[i] |= FTDM_READ; - } - } - - status = ftdm_span_poll_event(span, waitms, poll_events); - switch (status) { - case FTDM_FAIL: - ftdm_log(FTDM_LOG_CRIT, "Failed to poll span for IO\n"); - break; - case FTDM_TIMEOUT: - break; - case FTDM_SUCCESS: - /* Check if there are any channels that have data available */ - for (citer = ftdm_span_get_chan_iterator(span, chaniter); citer; citer = ftdm_iterator_next(citer)) { - len = sizeof(data); - ftdmchan = ftdm_iterator_current(citer); - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED)) { - if (ftdm_test_io_flag(ftdmchan, FTDM_CHANNEL_IO_READ)) { - status = ftdm_raw_read(ftdmchan, data, &len); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "raw I/O read failed\n"); - continue; - } - - status = ftdm_channel_process_media(ftdmchan, data, &len); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to process media\n"); - continue; - } - } - } - } else { - if (ftdm_test_io_flag(ftdmchan, FTDM_CHANNEL_IO_READ)) { - status = ftdm_channel_read(ftdmchan, data, &len); - if (status == FTDM_SUCCESS) { - sngisdn_snd_data(ftdmchan, data, len); - } - } - } - } - - /* Check if there are any channels that have events available */ - while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) { - ftdm_sangoma_isdn_process_phy_events(span, event->enum_id); - } - - break; - default: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Unhandled IO event\n"); - } - } -done: - ftdm_iterator_free(chaniter); - ftdm_safe_free(poll_events); - return NULL; -} - -static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj) -{ - ftdm_interrupt_t *ftdm_sangoma_isdn_int[3]; - ftdm_status_t ret_status; - ftdm_span_t *span = (ftdm_span_t *) obj; - ftdm_channel_t *ftdmchan = NULL; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - sngisdn_event_data_t *sngisdn_event = NULL; - int32_t sleep = SNGISDN_EVENT_POLL_RATE; - - ftdm_log(FTDM_LOG_INFO, "ftmod_sangoma_isdn monitor thread for span=%u started.\n", span->span_id); - - /* set IN_THREAD flag so that we know this thread is running */ - ftdm_set_flag(span, FTDM_SPAN_IN_THREAD); - - /* get an interrupt queue for this span */ - if (ftdm_queue_get_interrupt(span->pendingchans, &ftdm_sangoma_isdn_int[0]) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to get a ftdm_interrupt for span = %s!\n", span->name); - goto ftdm_sangoma_isdn_run_exit; - } - - if (ftdm_queue_get_interrupt(span->pendingsignals, &ftdm_sangoma_isdn_int[1]) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to get a signal interrupt for span = %s!\n", span->name); - goto ftdm_sangoma_isdn_run_exit; - } - - if (ftdm_queue_get_interrupt(signal_data->event_queue, &ftdm_sangoma_isdn_int[2]) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to get a event interrupt for span = %s!\n", span->name); - goto ftdm_sangoma_isdn_run_exit; - } - - while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) { - /* Check if there are any timers to process */ - ftdm_sched_run(signal_data->sched); - ftdm_span_trigger_signals(span); - - if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) { - if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) { - sleep = SNGISDN_EVENT_POLL_RATE; - } - } - ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 3, sleep); - /* find out why we returned from the interrupt queue */ - switch (ret_status) { - case FTDM_SUCCESS: /* there was a state change on the span */ - /* process all pending state changes */ - while ((ftdmchan = ftdm_queue_dequeue(span->pendingchans))) { - /* double check that this channel has a state change pending */ - ftdm_channel_lock(ftdmchan); - ftdm_channel_advance_states(ftdmchan); - ftdm_channel_unlock(ftdmchan); - } - - while ((sngisdn_event = ftdm_queue_dequeue(signal_data->event_queue))) { - ftdm_sangoma_isdn_process_stack_event(span, sngisdn_event); - ftdm_safe_free(sngisdn_event); - } - break; - case FTDM_TIMEOUT: - /* twiddle */ - break; - case FTDM_FAIL: - ftdm_log(FTDM_LOG_ERROR, "%s: ftdm_interrupt_wait returned error!\n", span->name); - break; - - default: - ftdm_log(FTDM_LOG_ERROR, "%s: ftdm_interrupt_wait returned with unknown code\n", span->name); - break; - } - } - - /* clear the IN_THREAD flag so that we know the thread is done */ - ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); - - ftdm_log(FTDM_LOG_INFO, "ftmod_sangoma_isdn monitor thread for span %s stopping.\n", span->name); - - return NULL; - -ftdm_sangoma_isdn_run_exit: - - /* clear the IN_THREAD flag so that we know the thread is done */ - ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); - - ftdm_log(FTDM_LOG_INFO, "ftmod_sangoma_isdn monitor thread for span %s stopping due to error.\n", span->name); - - return NULL; -} - - -/** - * \brief Checks if span has state changes pending and processes - * \param span Span where event was fired - * \param sngisdn_event Event to handle - * \return The locked FTDM channel associated to the event if any, NULL otherwise - */ - -ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event) -{ - ftdm_channel_t *ftdmchan = NULL; - switch (sngisdn_event->event_id) { - /* Events that do not have a channel associated to them */ - case SNGISDN_EVENT_SRV_IND: - case SNGISDN_EVENT_SRV_CFM: - case SNGISDN_EVENT_RST_CFM: - case SNGISDN_EVENT_RST_IND: - return NULL; - break; - case SNGISDN_EVENT_CON_IND: - case SNGISDN_EVENT_CON_CFM: - case SNGISDN_EVENT_CNST_IND: - case SNGISDN_EVENT_DISC_IND: - case SNGISDN_EVENT_REL_IND: - case SNGISDN_EVENT_DAT_IND: - case SNGISDN_EVENT_SSHL_IND: - case SNGISDN_EVENT_SSHL_CFM: - case SNGISDN_EVENT_RMRT_IND: - case SNGISDN_EVENT_RMRT_CFM: - case SNGISDN_EVENT_FLC_IND: - case SNGISDN_EVENT_FAC_IND: - case SNGISDN_EVENT_STA_CFM: - ftdmchan = sngisdn_event->sngisdn_info->ftdmchan; - ftdm_assert_return(ftdmchan, NULL,"Event should have a channel associated\n"); - break; - } - ftdm_channel_lock(ftdmchan); - ftdm_channel_advance_states(ftdmchan); - return ftdmchan; -} - - - -static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event) -{ - ftdm_channel_t *ftdmchan = NULL; - - ftdmchan = ftdm_sangoma_isdn_process_event_states(span, sngisdn_event); - switch(sngisdn_event->event_id) { - case SNGISDN_EVENT_CON_IND: - sngisdn_process_con_ind(sngisdn_event); - break; - case SNGISDN_EVENT_CON_CFM: - sngisdn_process_con_cfm(sngisdn_event); - break; - case SNGISDN_EVENT_CNST_IND: - sngisdn_process_cnst_ind(sngisdn_event); - break; - case SNGISDN_EVENT_DISC_IND: - sngisdn_process_disc_ind(sngisdn_event); - break; - case SNGISDN_EVENT_REL_IND: - sngisdn_process_rel_ind(sngisdn_event); - break; - case SNGISDN_EVENT_DAT_IND: - sngisdn_process_dat_ind(sngisdn_event); - break; - case SNGISDN_EVENT_SSHL_IND: - sngisdn_process_sshl_ind(sngisdn_event); - break; - case SNGISDN_EVENT_SSHL_CFM: - sngisdn_process_sshl_cfm(sngisdn_event); - break; - case SNGISDN_EVENT_RMRT_IND: - sngisdn_process_rmrt_ind(sngisdn_event); - break; - case SNGISDN_EVENT_RMRT_CFM: - sngisdn_process_rmrt_cfm(sngisdn_event); - break; - case SNGISDN_EVENT_FLC_IND: - sngisdn_process_flc_ind(sngisdn_event); - break; - case SNGISDN_EVENT_FAC_IND: - sngisdn_process_fac_ind(sngisdn_event); - break; - case SNGISDN_EVENT_STA_CFM: - sngisdn_process_sta_cfm(sngisdn_event); - break; - case SNGISDN_EVENT_SRV_IND: - sngisdn_process_srv_ind(sngisdn_event); - break; - case SNGISDN_EVENT_SRV_CFM: - sngisdn_process_srv_cfm(sngisdn_event); - break; - case SNGISDN_EVENT_RST_CFM: - sngisdn_process_rst_cfm(sngisdn_event); - break; - case SNGISDN_EVENT_RST_IND: - sngisdn_process_rst_ind(sngisdn_event); - break; - } - if (ftdmchan != NULL) { - ftdm_channel_advance_states(ftdmchan); - ftdm_channel_unlock(ftdmchan); - } -} - -/* this function is called with the channel already locked by the core */ -static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) -{ - ftdm_sigmsg_t sigev; - ftdm_channel_state_t initial_state; - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - uint8_t state_change = 0; - - memset(&sigev, 0, sizeof(sigev)); - - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - -#ifdef FTDM_DEBUG_CHAN_MEMORY - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { - ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ) == 0, "Failed to mprotect"); - } -#endif - - /* Only needed for debugging */ - initial_state = ftdmchan->state; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "processing state change to %s\n", ftdm_channel_state2str(ftdmchan->state)); - - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_COLLECT: /* SETUP received but waiting on digits */ - { - /* TODO: Re-implement this. There is a way to re-evaluate new incoming digits from dialplan as they come */ - sngisdn_snd_setup_ack(ftdmchan); - /* Just wait in this state until we get enough digits or T302 timeout */ - } - break; - case FTDM_CHANNEL_STATE_GET_CALLERID: - { - /* By default, we do not send a progress indicator in the proceed */ - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; - sngisdn_snd_proceed(ftdmchan, prog_ind); - - /* Wait in this state until we get FACILITY msg */ - } - break; - case FTDM_CHANNEL_STATE_RING: /* incoming call request */ - { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits); - - /* we have enough information to inform FTDM of the call*/ - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_START); - } - break; - case FTDM_CHANNEL_STATE_DIALING: /* outgoing call request */ - { - if (FTDM_SPAN_IS_BRI(ftdmchan->span) && ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) { - ftdm_signaling_status_t sigstatus; - ftdm_span_get_sig_status(ftdmchan->span, &sigstatus); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) { - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)ftdmchan->span->signal_data; - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Physical Line activation\n"); - sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING); - ftdm_sangoma_isdn_wakeup_phy(ftdmchan); - ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL); - } else if (sigstatus == FTDM_SIG_STATE_DOWN) { - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)ftdmchan->span->signal_data; - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Q.921 Line activation\n"); - sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING); - sngisdn_snd_dl_req(ftdmchan); - ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL); - } else { - sngisdn_snd_setup(ftdmchan); - } - } else { - sngisdn_snd_setup(ftdmchan); - } - } - break; - case FTDM_CHANNEL_STATE_PROCEED: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - /*OUTBOUND...so we were told by the line of this so noifiy the user*/ - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_PROCEED); - - if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { - state_change++; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } - } else { - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; - sngisdn_snd_proceed(ftdmchan, prog_ind); - } - } - break; - case FTDM_CHANNEL_STATE_RINGING: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - /* OUTBOUND...so we were told by the line of this so notify the user */ - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_RINGING); - - if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { - state_change++; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } - } else { - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; - sngisdn_snd_alert(ftdmchan, prog_ind); - } - } - break; - case FTDM_CHANNEL_STATE_PROGRESS: - { - /*check if the channel is inbound or outbound*/ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - /*OUTBOUND...so we were told by the line of this so noifiy the user*/ - - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_PROGRESS); - } else { - /* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */ - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; - sngisdn_snd_progress(ftdmchan, prog_ind); - } - } - break; - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_PROGRESS_MEDIA); - } else { - /* Send a progress message, indicating: In-band information/pattern available */ - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_IB_AVAIL}; - sngisdn_snd_progress(ftdmchan, prog_ind); - } - } - break; - case FTDM_CHANNEL_STATE_UP: /* call is answered */ - { - /* check if the channel is inbound or outbound */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - /* OUTBOUND ... so we were told by the line that the other side answered */ - - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_UP); - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP && - ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->signalling == SNGISDN_SIGNALING_NET) { - /* Assign the call to a specific equipment */ - sngisdn_snd_con_complete(ftdmchan); - } - } else { - /* INBOUND ... so FS told us it just answered ... tell the stack */ - sngisdn_snd_connect(ftdmchan); - } - } - break; - case FTDM_CHANNEL_STATE_CANCEL: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Hanging up call before informing user!\n"); - - /* Send a release complete */ - sngisdn_snd_release(ftdmchan, 0); - /*now go to the HANGUP complete state*/ - state_change++; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - } - break; - case FTDM_CHANNEL_STATE_TERMINATING: /* call is hung up by the remote end */ - { - /* this state is set when the line is hanging up */ - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_STOP); - } - break; - case FTDM_CHANNEL_STATE_HANGUP: /* call is hung up locally */ - { - if (sngisdn_test_flag(sngisdn_info, FLAG_REMOTE_ABORT)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Acknowledging remote abort\n"); - } else if (sngisdn_test_flag(sngisdn_info, FLAG_REMOTE_REL)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Acknowledging remote hangup\n"); - sngisdn_snd_release(ftdmchan, 0); - } else if (sngisdn_test_flag(sngisdn_info, FLAG_LOCAL_ABORT)) { - /* We aborted this call before sending anything to the stack, so nothing to do anymore */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Clearing local states from local abort\n"); - } else if (sngisdn_test_flag(sngisdn_info, FLAG_GLARE)) { - /* We are hangup local call because there was a glare, we are waiting for a - RELEASE on this call, before we can process the saved call */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Waiting for RELEASE on hungup glared call\n"); - } else if (sngisdn_test_flag(sngisdn_info, FLAG_SEND_DISC)) { - /* Remote side sent a PROGRESS message, but cause indicates disconnect or T310 expired*/ - sngisdn_snd_disconnect(ftdmchan); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Hanging up call upon local request!\n"); - - /* set the flag to indicate this hangup is started from the local side */ - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_REL); - - switch(ftdmchan->last_state) { - case FTDM_CHANNEL_STATE_RING: - /* If we never sent PROCEED/ALERT/PROGRESS/CONNECT on an incoming call, we need to send release instead of disconnect */ - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - sngisdn_snd_release(ftdmchan, 0); - break; - case FTDM_CHANNEL_STATE_DIALING: - /* If we never received a PROCEED/ALERT/PROGRESS/CONNECT on an outgoing call, we need to send release instead of disconnect */ - sngisdn_snd_release(ftdmchan, 0); - break; - case FTDM_CHANNEL_STATE_PROCEED: - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (((sngisdn_span_data_t*)(ftdmchan->span->signal_data))->switchtype == SNGISDN_SWITCH_4ESS || - ((sngisdn_span_data_t*)(ftdmchan->span->signal_data))->switchtype == SNGISDN_SWITCH_5ESS) { - - /* When using 5ESS, if the user wants to clear an inbound call, the correct procedure is to send a PROGRESS with in-band info available, and play tones. Then send a DISCONNECT. If we reached this point, it means user did not try to play-tones, so send a RELEASE because remote side does not expect DISCONNECT in state 3 */ - sngisdn_snd_release(ftdmchan, 0); - break; - } - } - /* fall-through */ - default: - sngisdn_snd_disconnect(ftdmchan); - break; - } - } - /* now go to the HANGUP complete state */ - state_change++; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - } - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - { - if (sngisdn_test_flag(sngisdn_info, FLAG_REMOTE_ABORT) || - sngisdn_test_flag(sngisdn_info, FLAG_LOCAL_ABORT)) { - /* If the remote side aborted, we will not get anymore message for this call */ - state_change++; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - /* waiting on remote confirmation before moving to down */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Waiting for release from stack\n"); - } - } - break; - case FTDM_CHANNEL_STATE_DOWN: /* the call is finished and removed */ - { - uint8_t glare = sngisdn_test_flag(sngisdn_info, FLAG_GLARE); - /* clear all of the call specific data store in the channel structure */ - clear_call_data(sngisdn_info); - - /* Close the channel even if we had a glare, we will re-open it when processing state COLLECT for the - "glared call" */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - ftdm_channel_t *close_chan = ftdmchan; - /* close the channel */ - ftdm_channel_close(&close_chan); - } - if (glare) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Glare detected, processing saved call\n"); - /* We are calling sngisdn_rcv_con_ind with ftdmchan->mutex being locked, - so no other threads will be able to touch this channel. The next time we will - process this channel is in this function, and it should be in state COLLECT (set inside - sngisdn_rcv_con_ind)*/ - sngisdn_rcv_con_ind(sngisdn_info->glare.suId, sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId, &sngisdn_info->glare.setup, sngisdn_info->glare.dChan, sngisdn_info->glare.ces); - } - } - break; - case FTDM_CHANNEL_STATE_TRANSFER: - { - /* sngisdn_transfer function will always result in a state change */ - sngisdn_transfer(ftdmchan); - state_change++; - } - break; - case FTDM_CHANNEL_STATE_RESTART: - { - /* IMPLEMENT ME */ - } - break; - case FTDM_CHANNEL_STATE_SUSPENDED: - { - /* IMPLEMENT ME */ - } - break; - case FTDM_CHANNEL_STATE_RESET: - { - sngisdn_snd_restart(ftdmchan); - } - break; - default: - { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "unsupported sngisdn_rcvd state %s\n", ftdm_channel_state2str(ftdmchan->state)); - } - break; - } - - if (!state_change) { - /* Acknowledge the state change */ - ftdm_channel_complete_state(ftdmchan); - } - - /* If sngisdn_info->variables is not NULL, it means did not send any - * sigevent to the user, therefore we have to free that hashtable */ - if (sngisdn_info->variables) { - hashtable_destroy(sngisdn_info->variables); - sngisdn_info->variables = NULL; - } - - /* If sngisdn_info->raw_data is not NULL, it means did not send any - * sigevent to the user, therefore we have to free that raw data */ - if (sngisdn_info->raw_data) { - ftdm_safe_free(sngisdn_info->raw_data); - sngisdn_info->raw_data = NULL; - sngisdn_info->raw_data_len = 0; - } - - if (ftdmchan->state == initial_state) { - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "state change flag is still set, but we did not change state\n"); - } -#ifdef FTDM_DEBUG_CHAN_MEMORY - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { - ftdm_assert(mprotect(ftdmchan, sizeof(*ftdmchan), PROT_READ|PROT_WRITE) == 0, "Failed to mprotect"); - } -#endif - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_INDICATE_FUNCTION(ftdm_sangoma_isdn_indicate) -{ - ftdm_status_t status = FTDM_FAIL; - - switch (indication) { - case FTDM_CHANNEL_INDICATE_FACILITY: - sngisdn_snd_fac_req(ftdmchan); - status = FTDM_SUCCESS; - break; - default: - status = FTDM_NOTIMPL; - } - return status; -} - -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call) -{ - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - ftdm_status_t status = FTDM_FAIL; - - if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) { - if (sngisdn_test_flag(sngisdn_info, FLAG_GLARE)) { - /* A call came in after we called ftdm_channel_open_chan for this call, but before we got here */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Glare detected - aborting outgoing call\n"); - - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - - status = FTDM_BREAK; - } else { - status = FTDM_SUCCESS; - } - } else { - /* the channel is already used...this can't be, end the request */ - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Outgoing call requested channel in already in use (%s)\n", ftdm_channel_state2str(ftdmchan->state)); - status = FTDM_BREAK; - } - - return status; -} -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_chan_sig_status) -{ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - *status = FTDM_SIG_STATE_UP; - } else { - *status = FTDM_SIG_STATE_DOWN; - } - - return FTDM_SUCCESS; -} - -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_chan_sig_status) -{ - ftdm_log(FTDM_LOG_ERROR,"Cannot set channel status in this module\n"); - return FTDM_NOTIMPL; -} - -static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_span_sig_status) -{ - if (ftdm_test_flag(span->channels[1], FTDM_CHANNEL_SIG_UP)) { - *status = FTDM_SIG_STATE_UP; - } else { - *status = FTDM_SIG_STATE_DOWN; - } - - return FTDM_SUCCESS; -} - -static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status) -{ - ftdm_log(FTDM_LOG_ERROR,"Cannot set span status in this module\n"); - return FTDM_NOTIMPL; -} - -static ftdm_status_t ftdm_sangoma_isdn_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf) -{ - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - switch(sngisdn_info->transfer_data.type) { - case SNGISDN_TRANSFER_ATT_COURTESY_VRU: - case SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA: - return sngisdn_att_transfer_process_dtmf(ftdmchan, dtmf); - default: - /* We do not care about DTMF events, do nothing */ - break; - } - - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_sangoma_isdn_perform_start(ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = span->signal_data; - - ftdm_log(FTDM_LOG_DEBUG, "Actually starting span:%s\n", span->name); - /* clear the monitor thread stop flag */ - ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD); - ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); - - if (signal_data->trace_q921 == SNGISDN_OPT_TRUE || - signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) { - - sngisdn_activate_trace(span, SNGISDN_TRACE_Q921); - } - - if (signal_data->trace_q931 == SNGISDN_OPT_TRUE || - signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) { - - sngisdn_activate_trace(span, SNGISDN_TRACE_Q931); - } - - /*start the span monitor thread*/ - if (ftdm_thread_create_detached(ftdm_sangoma_isdn_run, span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN Span Monitor Thread!\n"); - return FTDM_FAIL; - } - - /*start the dchan monitor thread*/ - if (ftdm_thread_create_detached(ftdm_sangoma_isdn_io_run, span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN d-channel Monitor Thread!\n"); - return FTDM_FAIL; - } - - if (signal_data->restart_timeout) { - ftdm_log(FTDM_LOG_DEBUG, "%s:Scheduling Restart timeout\n", signal_data->ftdm_span->name); - ftdm_sched_timer(signal_data->sched, "restart_timeout", signal_data->restart_timeout, - sngisdn_restart_timeout, (void*) signal_data, &signal_data->timers[SNGISDN_SPAN_TIMER_RESTART]); - } - - ftdm_log(FTDM_LOG_DEBUG,"Finished starting span %s\n", span->name); - return FTDM_SUCCESS; -} - - -static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = span->signal_data; - - ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id); - - if (signal_data->dchan) { - ftdm_channel_set_feature(signal_data->dchan, FTDM_CHANNEL_FEATURE_IO_STATS); - ftdm_channel_open_chan(signal_data->dchan); - ftdm_sangoma_isdn_dchan_set_queue_size(signal_data->dchan); - } - - if (signal_data->nfas.trunk) { - if (signal_data->nfas.trunk->num_spans == signal_data->nfas.trunk->num_spans_configured) { - int i; - ftdm_log(FTDM_LOG_DEBUG, "Starting span for all spans within trunkgroup:%s\n", signal_data->nfas.trunk->name); - - sngisdn_stack_start(signal_data->nfas.trunk->dchan->ftdm_span); - ftdm_sangoma_isdn_perform_start(signal_data->nfas.trunk->dchan->ftdm_span); - - if (signal_data->nfas.trunk->backup) { - sngisdn_stack_start(signal_data->nfas.trunk->backup->ftdm_span); - ftdm_sangoma_isdn_perform_start(signal_data->nfas.trunk->backup->ftdm_span); - } - - for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { - if (signal_data->nfas.trunk->spans[i] && - signal_data->nfas.trunk->spans[i]->nfas.sigchan == SNGISDN_NFAS_DCHAN_NONE) { - sngisdn_stack_start(signal_data->nfas.trunk->spans[i]->ftdm_span); - ftdm_sangoma_isdn_perform_start(signal_data->nfas.trunk->spans[i]->ftdm_span); - } - } - - return FTDM_SUCCESS; - } else { - ftdm_log(FTDM_LOG_DEBUG, "Delaying span start until all spans within trunkgroup are started: %s\n", signal_data->nfas.trunk->name); - return FTDM_SUCCESS; - } - } - - if (sngisdn_stack_start(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name); - return FTDM_FAIL; - } - - ftdm_sangoma_isdn_perform_start(span); - - return FTDM_SUCCESS; -} - -static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) -{ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - unsigned i; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - ftdm_log(FTDM_LOG_INFO, "Stopping span %s\n", span->name); - - /* throw the STOP_THREAD flag to signal monitor thread stop */ - ftdm_set_flag(span, FTDM_SPAN_STOP_THREAD); - - /* wait for the thread to stop */ - while (ftdm_test_flag(span, FTDM_SPAN_IN_THREAD)) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for monitor thread to end for span %s\n", span->name); - ftdm_sleep(10); - } - - if (sngisdn_stack_stop(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name); - } - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_safe_free(((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data); - ((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = NULL; - } - ftdm_iterator_free(chaniter); - - ftdm_sched_destroy(&signal_data->sched); - ftdm_queue_destroy(&signal_data->event_queue); - for (i = 0 ; i < signal_data->num_local_numbers ; i++) { - if (signal_data->local_numbers[i] != NULL) { - ftdm_safe_free(signal_data->local_numbers[i]); - } - } - ftdm_safe_free(span->signal_data); - - ftdm_log(FTDM_LOG_DEBUG, "Finished stopping span %s\n", span->name); - - return FTDM_SUCCESS; -} - -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) -{ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - sngisdn_span_data_t *signal_data; - - ftdm_log(FTDM_LOG_INFO, "Configuring ftmod_sangoma_isdn span = %s\n", span->name); - - signal_data = ftdm_calloc(1, sizeof(sngisdn_span_data_t)); - signal_data->ftdm_span = span; - span->signal_data = signal_data; - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - sngisdn_chan_data_t *chan_data = ftdm_calloc(1, sizeof(sngisdn_chan_data_t)); - chan_data->ftdmchan = ((ftdm_channel_t*)ftdm_iterator_current(curr)); - ((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = chan_data; - - } - ftdm_iterator_free(chaniter); - - if (ftmod_isdn_parse_cfg(ftdm_parameters, span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Failed to parse configuration\n"); - return FTDM_FAIL; - } - - if (signal_data->nfas.trunk) { - if (signal_data->nfas.trunk->num_spans == ++signal_data->nfas.trunk->num_spans_configured) { - int i; - ftdm_log(FTDM_LOG_DEBUG, "Starting stack configuration for all spans within trunkgroup:%s\n", signal_data->nfas.trunk->name); - - sngisdn_stack_cfg(signal_data->nfas.trunk->dchan->ftdm_span); - if (signal_data->nfas.trunk->backup) { - sngisdn_stack_cfg(signal_data->nfas.trunk->backup->ftdm_span); - } - - for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { - if (signal_data->nfas.trunk->spans[i] && - signal_data->nfas.trunk->spans[i]->nfas.sigchan == SNGISDN_NFAS_DCHAN_NONE) { - sngisdn_stack_cfg(signal_data->nfas.trunk->spans[i]->ftdm_span); - } - } - } else { - ftdm_log(FTDM_LOG_DEBUG, "Delaying span stack configuration until all spans within trunkgroup are started:%s\n", signal_data->nfas.trunk->name); - } - } else if (sngisdn_stack_cfg(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Sangoma ISDN Stack configuration failed\n"); - return FTDM_FAIL; - } - - if (signal_data->cid_name_method == SNGISDN_CID_NAME_AUTO) { - switch (signal_data->switchtype) { - case SNGISDN_SWITCH_EUROISDN: - if (FTDM_SPAN_IS_BRI(span)) { - signal_data->cid_name_method = SNGISDN_CID_NAME_USR_USR_IE; - } else { - signal_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE; - } - break; - case SNGISDN_SWITCH_DMS100: - signal_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE; - break; - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_4ESS: - signal_data->cid_name_method = SNGISDN_CID_NAME_FACILITY_IE; - break; - default: - break; - } - } - - if (signal_data->send_cid_name == SNGISDN_OPT_DEFAULT) { - switch (signal_data->switchtype) { - case SNGISDN_SWITCH_EUROISDN: -#ifdef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_4ESS: -#endif - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - signal_data->send_cid_name = SNGISDN_OPT_TRUE; - } else { - signal_data->send_cid_name = SNGISDN_OPT_FALSE; - } - break; - case SNGISDN_SWITCH_DMS100: - signal_data->send_cid_name = SNGISDN_OPT_TRUE; - break; -#ifndef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_4ESS: - signal_data->send_cid_name = SNGISDN_OPT_FALSE; - break; -#endif - default: - signal_data->send_cid_name = SNGISDN_OPT_FALSE; - break; - } - } else if (signal_data->send_cid_name == SNGISDN_OPT_TRUE) { - switch (signal_data->switchtype) { - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_4ESS: -#ifndef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY - ftdm_log(FTDM_LOG_WARNING, "Sending Calling Name in Facility IE not supported, please update your libsng_isdn library\n"); - signal_data->send_cid_name = SNGISDN_OPT_FALSE; -#endif - break; - case SNGISDN_SWITCH_INSNET: /* Don't know how to transmit caller ID name on INSNET */ - case SNGISDN_SWITCH_QSIG: /* It seems like QSIG does not support Caller ID */ - signal_data->send_cid_name = SNGISDN_OPT_FALSE; - break; - case SNGISDN_SWITCH_EUROISDN: - break; - default: - signal_data->send_cid_name = SNGISDN_OPT_FALSE; - break; - } - } - - span->start = ftdm_sangoma_isdn_start; - span->stop = ftdm_sangoma_isdn_stop; - span->signal_type = FTDM_SIGTYPE_ISDN; - span->outgoing_call = ftdm_sangoma_isdn_outgoing_call; - span->indicate = ftdm_sangoma_isdn_indicate; - span->channel_request = NULL; - span->signal_cb = sig_cb; - span->sig_queue_dtmf = ftdm_sangoma_isdn_dtmf; - span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status; - span->set_channel_sig_status = ftdm_sangoma_isdn_set_chan_sig_status; - span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status; - span->set_span_sig_status = ftdm_sangoma_isdn_set_span_sig_status; - span->state_map = &sangoma_isdn_state_map; - span->state_processor = ftdm_sangoma_isdn_process_state_change; - ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); - ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); - ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE); - ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES); - ftdm_set_flag(span, FTDM_SPAN_NON_STOPPABLE); - ftdm_set_flag(span, FTDM_SPAN_USE_TRANSFER); - - if (FTDM_SPAN_IS_BRI(span)) { - sngisdn_set_span_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING); - } - - /* Initialize scheduling context */ - ftdm_assert(ftdm_sched_create(&((sngisdn_span_data_t*)span->signal_data)->sched, "sngisdn_schedule") == FTDM_SUCCESS, "Failed to create a new schedule!!"); - - /* Initialize the event queue */ - ftdm_assert(ftdm_queue_create(&((sngisdn_span_data_t*)span->signal_data)->event_queue, SNGISDN_EVENT_QUEUE_SIZE) == FTDM_SUCCESS, "Failed to create a new queue!!"); - - ftdm_log(FTDM_LOG_INFO, "Finished configuring ftmod_sangoma_isdn span = %s\n", span->name); - return FTDM_SUCCESS; -} - -static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) -{ - unsigned i; - ftdm_log(FTDM_LOG_INFO, "Loading ftmod_sangoma_isdn...\n"); - - memset(&g_sngisdn_data, 0, sizeof(g_sngisdn_data)); - memset(&g_sngisdn_event_interface, 0, sizeof(g_sngisdn_event_interface)); - /* set callbacks */ - g_sngisdn_event_interface.cc.sng_con_ind = sngisdn_rcv_con_ind; - g_sngisdn_event_interface.cc.sng_con_cfm = sngisdn_rcv_con_cfm; - g_sngisdn_event_interface.cc.sng_cnst_ind = sngisdn_rcv_cnst_ind; - g_sngisdn_event_interface.cc.sng_disc_ind = sngisdn_rcv_disc_ind; - g_sngisdn_event_interface.cc.sng_rel_ind = sngisdn_rcv_rel_ind; - g_sngisdn_event_interface.cc.sng_dat_ind = sngisdn_rcv_dat_ind; - g_sngisdn_event_interface.cc.sng_sshl_ind = sngisdn_rcv_sshl_ind; - g_sngisdn_event_interface.cc.sng_sshl_cfm = sngisdn_rcv_sshl_cfm; - g_sngisdn_event_interface.cc.sng_rmrt_ind = sngisdn_rcv_rmrt_ind; - g_sngisdn_event_interface.cc.sng_rmrt_cfm = sngisdn_rcv_rmrt_cfm; - g_sngisdn_event_interface.cc.sng_flc_ind = sngisdn_rcv_flc_ind; - g_sngisdn_event_interface.cc.sng_fac_ind = sngisdn_rcv_fac_ind; - g_sngisdn_event_interface.cc.sng_sta_cfm = sngisdn_rcv_sta_cfm; - g_sngisdn_event_interface.cc.sng_srv_ind = sngisdn_rcv_srv_ind; - g_sngisdn_event_interface.cc.sng_srv_cfm = sngisdn_rcv_srv_cfm; - g_sngisdn_event_interface.cc.sng_rst_ind = sngisdn_rcv_rst_ind; - g_sngisdn_event_interface.cc.sng_rst_cfm = sngisdn_rcv_rst_cfm; - - g_sngisdn_event_interface.lg.sng_log = sngisdn_rcv_sng_log; - g_sngisdn_event_interface.lg.sng_assert = sngisdn_rcv_sng_assert; - - g_sngisdn_event_interface.sta.sng_phy_sta_ind = sngisdn_rcv_phy_ind; - g_sngisdn_event_interface.sta.sng_q921_sta_ind = sngisdn_rcv_q921_ind; - g_sngisdn_event_interface.sta.sng_q921_trc_ind = sngisdn_rcv_q921_trace; - g_sngisdn_event_interface.sta.sng_q931_sta_ind = sngisdn_rcv_q931_ind; - g_sngisdn_event_interface.sta.sng_q931_trc_ind = sngisdn_rcv_q931_trace; - g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind; - - g_sngisdn_event_interface.io.sng_l1_data_req = sngisdn_rcv_l1_data_req; - g_sngisdn_event_interface.io.sng_l1_cmd_req = sngisdn_rcv_l1_cmd_req; - - for(i=1;i<=MAX_VARIANTS;i++) { - ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex); - } - - /* initalize sng_isdn library */ - ftdm_assert_return(!sng_isdn_init(&g_sngisdn_event_interface), FTDM_FAIL, "Failed to initialize stack\n"); - - /* Load Stack General Configuration */ - sngisdn_start_gen_cfg(); - - return FTDM_SUCCESS; -} - -static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_isdn_unload) -{ - unsigned i; - ftdm_log(FTDM_LOG_INFO, "Starting ftmod_sangoma_isdn unload...\n"); - - sng_isdn_free(); - - for(i=1;i<=MAX_VARIANTS;i++) { - ftdm_mutex_destroy(&g_sngisdn_data.ccs[i].mutex); - } - - ftdm_log(FTDM_LOG_INFO, "Finished ftmod_sangoma_isdn unload!\n"); - return FTDM_SUCCESS; -} - -#define SANGOMA_ISDN_API_USAGE_TRACE "ftdm sangoma_isdn trace \n" -#define SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS "ftdm sangoma_isdn l1_stats \n" -#define SANGOMA_ISDN_API_USAGE_SHOW_SPANS "ftdm sangoma_isdn show_spans []\n" - -#define SANGOMA_ISDN_API_USAGE "\t"SANGOMA_ISDN_API_USAGE_TRACE \ - "\t"SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS \ - "\t"SANGOMA_ISDN_API_USAGE_SHOW_SPANS - -static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) -{ - ftdm_status_t status = FTDM_EINVAL; - char *mycmd = NULL, *argv[10] = { 0 }; - int argc = 0; - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - } - - /*ftdm_log(FTDM_LOG_DEBUG, "Sangoma argc:%d argv[0]:%s argv[1]:%s argv[2]:%s \n", argc, argv[0], argv[1], argv[2]);*/ - if (argc <= 0) { - ftdm_log(FTDM_LOG_ERROR, "No parameters provided\n"); - goto done; - } - - /* TODO: Move functions to table + function pointers */ - if (!strcasecmp(argv[0], "trace")) { - char *trace_opt; - - ftdm_span_t *span; - - if (argc < 3) { - ftdm_log(FTDM_LOG_ERROR, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_TRACE); - status = FTDM_FAIL; - goto done; - } - trace_opt = argv[1]; - - status = ftdm_span_find_by_name(argv[2], &span); - if (FTDM_SUCCESS != status) { - stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]); - - status = FTDM_FAIL; - goto done; - } - - if (!strcasecmp(trace_opt, "q921")) { - status = sngisdn_activate_trace(span, SNGISDN_TRACE_Q921); - } else if (!strcasecmp(trace_opt, "q931")) { - status = sngisdn_activate_trace(span, SNGISDN_TRACE_Q931); - } else if (!strcasecmp(trace_opt, "disable")) { - status = sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE); - } else { - stream->write_function(stream, "-ERR invalid trace option \n"); - status = FTDM_FAIL; - } - goto done; - } - - if (!strcasecmp(argv[0], "l1_stats")) { - ftdm_span_t *span; - if (argc < 2) { - stream->write_function(stream, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS); - status = FTDM_FAIL; - goto done; - } - status = ftdm_span_find_by_name(argv[1], &span); - if (FTDM_SUCCESS != status) { - stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]); - - status = FTDM_FAIL; - goto done; - } - status = sngisdn_show_l1_stats(stream, span); - goto done; - } - - if (!strcasecmp(argv[0], "show_spans")) { - ftdm_span_t *span = NULL; - if (argc == 2) { - status = ftdm_span_find_by_name(argv[1], &span); - if (FTDM_SUCCESS != status) { - stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]); - - stream->write_function(stream, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_SHOW_SPANS); - status = FTDM_FAIL; - goto done; - } - status = sngisdn_show_span(stream, span); - goto done; - } - status = sngisdn_show_spans(stream); - goto done; - } - - if (!strcasecmp(argv[0], "check_ids")) { - status = sngisdn_check_free_ids(); - goto done; - } - if (!strcasecmp(argv[0], "check_mem")) { - sngisdn_get_memory_info(); - } -done: - switch (status) { - case FTDM_SUCCESS: - stream->write_function(stream, "Command executed OK\n"); - break; - case FTDM_EINVAL: - stream->write_function(stream, "Invalid arguments [%s]\n", mycmd); - stream->write_function(stream, "Usage:\n%s\n", SANGOMA_ISDN_API_USAGE); - break; - default: - /* FTDM_FAIL - Do nothing since we already printed the cause of the error */ - break; - } - - /* Return SUCCESS because we do not want to print the general FTDM usage list */ - status = FTDM_SUCCESS; - - ftdm_safe_free(mycmd); - return status; -} - - -static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_isdn_io_init) -{ - memset(&g_sngisdn_io_interface, 0, sizeof(g_sngisdn_io_interface)); - - g_sngisdn_io_interface.name = "sangoma_isdn"; - g_sngisdn_io_interface.api = ftdm_sangoma_isdn_api; - - *fio = &g_sngisdn_io_interface; - - return FTDM_SUCCESS; -} - -EX_DECLARE_DATA ftdm_module_t ftdm_module = -{ - "sangoma_isdn", /* char name[256]; */ - ftdm_sangoma_isdn_io_init, /* fio_io_load_t */ - NULL, /* fio_io_unload_t */ - ftdm_sangoma_isdn_init, /* fio_sig_load_t */ - NULL, /* fio_sig_configure_t */ - ftdm_sangoma_isdn_unload, /* fio_sig_unload_t */ - ftdm_sangoma_isdn_span_config /* fio_configure_span_signaling_t */ -}; - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ - - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h deleted file mode 100644 index 64c1a20999..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __FTMOD_SNG_ISDN_H__ -#define __FTMOD_SNG_ISDN_H__ - -#include -#include -#include -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#include "private/ftdm_core.h" -#include "ftmod_sangoma_isdn_user.h" - -#ifdef WIN32 -#include -#else -#include -#endif - -/* Theoretical limit for MAX_SPANS_PER_NFAS_LINK is 31, - but set to 8 for now to save some memory */ - -#define MAX_SPANS_PER_NFAS_LINK 16 -#define MAX_NFAS_GROUPS 16 -#define NUM_E1_CHANNELS_PER_SPAN 32 -#define NUM_T1_CHANNELS_PER_SPAN 24 -#define NUM_BRI_CHANNELS_PER_SPAN 2 -#define SNGISDN_EVENT_QUEUE_SIZE 100 -#define SNGISDN_EVENT_POLL_RATE 100 -#define SNGISDN_NUM_LOCAL_NUMBERS 8 -#define SNGISDN_DCHAN_QUEUE_LEN 200 -#define MAX_NFAS_GROUP_NAME 50 - -#define NSG - -#ifndef MI_NOTIFY -#define MI_NOTIFY 0x14 -#endif - -typedef enum { - FLAG_RESET_RX = (1 << 0), - FLAG_RESET_TX = (1 << 1), - FLAG_REMOTE_REL = (1 << 2), - FLAG_LOCAL_REL = (1 << 3), - FLAG_REMOTE_ABORT = (1 << 4), - FLAG_LOCAL_ABORT = (1 << 5), - FLAG_GLARE = (1 << 6), - FLAG_DELAYED_REL = (1 << 7), - FLAG_SENT_PROCEED = (1 << 8), - FLAG_SEND_DISC = (1 << 9), - /* Used for BRI only, flag is set after we request line CONNECTED */ - FLAG_ACTIVATING = (1 << 10), - /* Used when we receive an ALERT msg + inband tones ready */ - FLAG_MEDIA_READY = (1 << 11), - /* Set when we already sent a Channel ID IE */ - FLAG_SENT_CHAN_ID = (1 << 12), - /* Set when we already sent a Connect */ - FLAG_SENT_CONNECT = (1 << 13), -} sngisdn_flag_t; - - -typedef enum { - SNGISDN_SWITCH_INVALID = 0, /* invalid */ - SNGISDN_SWITCH_NI2 , /* national isdn-2 */ - SNGISDN_SWITCH_5ESS, /* att 5ess */ - SNGISDN_SWITCH_4ESS, /* att 4ess */ - SNGISDN_SWITCH_DMS100, /* nt dms100 */ - SNGISDN_SWITCH_EUROISDN,/* etsi */ - SNGISDN_SWITCH_QSIG, /* etsi qsig */ - SNGISDN_SWITCH_INSNET, /* int - net */ -} sngisdn_switchtype_t; - -typedef enum { - SNGISDN_SIGNALING_INVALID = 0, /* invalid */ - SNGISDN_SIGNALING_CPE , /* customer side emulation */ - SNGISDN_SIGNALING_NET, /* network side emulation */ -} sngisdn_signalingtype_t; - -typedef enum { - SNGISDN_TRACE_DISABLE = 0, - SNGISDN_TRACE_Q921 = 1, - SNGISDN_TRACE_Q931 = 2, -} sngisdn_tracetype_t; - -typedef enum { - SNGISDN_OPT_DEFAULT = 0, - SNGISDN_OPT_TRUE = 1, - SNGISDN_OPT_FALSE = 2, -} sngisdn_opt_t; - -typedef enum { - SNGISDN_EARLY_MEDIA_ON_PROCEED = (1 << 0), - SNGISDN_EARLY_MEDIA_ON_PROGRESS = (1 << 1), - SNGISDN_EARLY_MEDIA_ON_ALERT= (1 << 2), -} sngisdn_early_media_opt_t; - -typedef enum { - SNGISDN_AVAIL_DOWN = 1, - SNGISDN_AVAIL_PWR_SAVING = 5, - SNGISDN_AVAIL_UP = 10, -} sngisdn_avail_t; - -typedef enum { - SNGISDN_CID_NAME_AUTO, - SNGISDN_CID_NAME_DISPLAY_IE, - SNGISDN_CID_NAME_USR_USR_IE, - SNGISDN_CID_NAME_FACILITY_IE, -} sngisdn_cid_name_t; - -typedef enum { - SNGISDN_EVENT_CON_IND = 1, - SNGISDN_EVENT_CON_CFM, - SNGISDN_EVENT_CNST_IND, - SNGISDN_EVENT_DISC_IND, - SNGISDN_EVENT_REL_IND, - SNGISDN_EVENT_DAT_IND, - SNGISDN_EVENT_SSHL_IND, - SNGISDN_EVENT_SSHL_CFM, - SNGISDN_EVENT_RMRT_IND, - SNGISDN_EVENT_RMRT_CFM, - SNGISDN_EVENT_FLC_IND, - SNGISDN_EVENT_FAC_IND, - SNGISDN_EVENT_STA_CFM, - SNGISDN_EVENT_SRV_IND, - SNGISDN_EVENT_SRV_CFM, - SNGISDN_EVENT_RST_CFM, - SNGISDN_EVENT_RST_IND, -} ftdm_sngisdn_event_id_t; - -typedef struct ftdm_sngisdn_prog_ind { - ftdm_sngisdn_progind_loc_t loc; /* location */ - ftdm_sngisdn_progind_descr_t descr; /* description */ -} ftdm_sngisdn_progind_t; - -/* Only timers that can be cancelled are listed here */ -#define SNGISDN_NUM_CHAN_TIMERS 2 -/* Increase SNGISDN_NUM_CHAN_TIMERS as number of ftdm_sngisdn_chan_timer_t increases */ -typedef enum { - SNGISDN_CHAN_TIMER_FACILITY, - SNGISDN_CHAN_TIMER_ATT_TRANSFER, -} ftdm_sngisdn_chan_timer_t; - -#define SNGISDN_NUM_SPAN_TIMERS 1 -/* Increase SNGISDN_NUM_SPAN_TIMERS as number of ftdm_sngisdn_spanan_timer_t increases */ -typedef enum { - SNGISDN_SPAN_TIMER_RESTART, -} ftdm_sngisdn_span_timer_t; - -typedef struct sngisdn_glare_data { - int16_t suId; - uint32_t suInstId; - uint32_t spInstId; - int16_t dChan; - ConEvnt setup; - uint8_t ces; -} sngisdn_glare_data_t; - -typedef enum { - SNGISDN_TRANSFER_NONE = 0, /* Default value, no transfer being done */ - SNGISDN_TRANSFER_ATT_COURTESY_VRU, - SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA, - SNGISDN_TRANSFER_INVALID, -} sngisdn_transfer_type_t; -#define SNGISDN_TRANSFER_TYPE_STRINGS "NONE", "ATT_COURTESY_VRU", "ATT_COURTERY_VRU_DATA", "INVALID" -SNGISDN_STR2ENUM_P(ftdm_str2sngisdn_transfer_type, sngisdn_transfer_type2str, sngisdn_transfer_type_t) - -/* From section 4.2 of TR50075, max length of data is 100 when single UUI is sent */ -#define COURTESY_TRANSFER_MAX_DATA_SIZE 100 - -typedef struct _att_courtesy_vru -{ - char dtmf_digits [20]; - char data[COURTESY_TRANSFER_MAX_DATA_SIZE]; -} att_courtesy_vru_t; - -typedef struct _sngisdn_transfer_data -{ - sngisdn_transfer_type_t type; /* Specifies which type of transfer is being used */ - ftdm_transfer_response_t response; - union - { - att_courtesy_vru_t att_courtesy_vru; - } tdata; -} sngisdn_transfer_data_t; - -/* Channel specific data */ -typedef struct sngisdn_chan_data { - ftdm_channel_t *ftdmchan; - uint32_t flags; - uint8_t ces; /* used only for BRI, otherwise always 0 */ - uint8_t dchan_id; - uint16_t call_ref; /* Q.931 call reference, only valid for ETSI/INSNET/QSIG */ - uint32_t suInstId; /* instance ID generated locally */ - uint32_t spInstId; /* instance ID generated by stack */ - - uint8_t globalFlg; - sngisdn_glare_data_t glare; - ftdm_timer_id_t timers[SNGISDN_NUM_CHAN_TIMERS]; - sngisdn_transfer_data_t transfer_data; - - /* variables saved here will be sent to the user application - on next SIGEVENT_XXX */ - ftdm_hash_t* variables; - - /* raw_data saved here will be sent to the user application - on next SIGEVENT_XXX */ - void *raw_data; - ftdm_size_t raw_data_len; -} sngisdn_chan_data_t; - -struct sngisdn_nfas_data; -typedef struct sngisdn_nfas_data sngisdn_nfas_data_t; - -typedef enum { - SNGISDN_NFAS_DCHAN_NONE, - SNGISDN_NFAS_DCHAN_PRIMARY, - SNGISDN_NFAS_DCHAN_BACKUP, -} sngisdn_nfas_sigchan_t; - -/* Span specific data */ -typedef struct sngisdn_span_data { - ftdm_span_t *ftdm_span; - ftdm_channel_t *dchan; - uint8_t link_id; - uint8_t switchtype; - uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */ - uint8_t cc_id; - ftdm_signaling_status_t sigstatus; - - uint8_t tei; - uint8_t min_digits; - uint8_t trace_flags; /* TODO change to bit map of sngisdn_tracetype_t */ - uint8_t early_media_flags; /* bit map of ftdm_sngisdn_early_media_opt_t */ - uint8_t overlap_dial; - uint8_t setup_arb; - uint8_t facility_ie_decode; - uint8_t facility; - int32_t facility_timeout; - uint8_t att_remove_dtmf; - int32_t transfer_timeout; - uint8_t num_local_numbers; - uint8_t ignore_cause_value; - uint8_t trace_q931; /* TODO: combine with trace_flags */ - uint8_t trace_q921; /* TODO: combine with trace_flags */ - uint8_t raw_trace_q931; /* TODO: combine with trace_flags */ - uint8_t raw_trace_q921; /* TODO: combine with trace_flags */ - uint8_t timer_t3; - uint8_t restart_opt; - uint8_t restart_timeout; - uint8_t force_sending_complete; - uint8_t cid_name_method; - uint8_t send_cid_name; - uint8_t send_connect_ack; - uint8_t dl_request_pending; /* Whether we have a DL request pending */ - - - int32_t timer_t301; - int32_t timer_t302; - int32_t timer_t303; - int32_t timer_t304; - int32_t timer_t305; - int32_t timer_t306; - int32_t timer_t307; - int32_t timer_t308; - int32_t timer_t310; - int32_t timer_t312; - int32_t timer_t313; - int32_t timer_t314; - int32_t timer_t316; - int32_t timer_t318; - int32_t timer_t319; - int32_t timer_t322; - char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; - ftdm_timer_id_t timers[SNGISDN_NUM_SPAN_TIMERS]; - ftdm_sched_t *sched; - ftdm_queue_t *event_queue; - - struct nfas_info { - sngisdn_nfas_data_t *trunk; - sngisdn_nfas_sigchan_t sigchan; - uint8_t interface_id; - } nfas; - - uint32_t num_chans; - sngisdn_chan_data_t *channels[NUM_E1_CHANNELS_PER_SPAN]; -} sngisdn_span_data_t; - -typedef struct sngisdn_event_data { - - int16_t suId; - int16_t dChan; - uint32_t suInstId; - uint32_t spInstId; - uint8_t ces; - uint8_t action; - uint8_t evntType; - - sngisdn_chan_data_t *sngisdn_info; - sngisdn_span_data_t *signal_data; - - ftdm_sngisdn_event_id_t event_id; - - union - { - ConEvnt conEvnt; - CnStEvnt cnStEvnt; - DiscEvnt discEvnt; - RelEvnt relEvnt; - InfoEvnt infoEvnt; - SsHlEvnt ssHlEvnt; - RmRtEvnt rmRtEvnt; - StaEvnt staEvnt; - FacEvnt facEvnt; - Srv srvEvnt; - Rst rstEvnt; - }event; - -} sngisdn_event_data_t; - -struct sngisdn_nfas_data { - char name[MAX_NFAS_GROUP_NAME]; - - char dchan_span_name[20]; - sngisdn_span_data_t *dchan; /* Span that contains primary d-channel */ - - char backup_span_name[20]; - sngisdn_span_data_t *backup; /* Span that contains backup d-channel */ - uint8_t num_spans; /* Number of spans within this NFAS */ - uint8_t num_spans_configured; - sngisdn_span_data_t *spans[MAX_SPANS_PER_NFAS_LINK+1]; //indexed by logical span id -}; - -typedef struct sngisdn_cc { - /* TODO: use flags instead of config_done and activation_done */ - uint8_t config_done; - uint8_t activation_done; - uint8_t switchtype; - ftdm_trunk_type_t trunktype; - uint32_t last_suInstId; - ftdm_mutex_t *mutex; - sngisdn_chan_data_t *active_spInstIds[MAX_INSTID+1]; - sngisdn_chan_data_t *active_suInstIds[MAX_INSTID+1]; -}sngisdn_cc_t; - -/* Global sngisdn data */ -typedef struct ftdm_sngisdn_data { - uint8_t gen_config_done; - uint8_t num_cc; /* 1 ent per switchtype */ - struct sngisdn_cc ccs[MAX_VARIANTS+1]; - uint8_t num_nfas; - sngisdn_nfas_data_t nfass[MAX_NFAS_GROUPS+1]; - sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */ - -#ifdef SANGOMA_ISDN_CHAN_ID_INVERT_BIT - /* Since this is a global configuration, place it here instead of sngisdn_span_data_t */ - uint8_t chan_id_invert_extend_bit; -#endif -}ftdm_sngisdn_data_t; - -typedef struct ftdm2trillium -{ - uint8_t ftdm_val; - uint8_t trillium_val; -}ftdm2trillium_t; - - -/* TODO implement these 2 functions */ -#define ISDN_FUNC_TRACE_ENTER(a) -#define ISDN_FUNC_TRACE_EXIT(a) - -/* Global Structs */ -extern ftdm_sngisdn_data_t g_sngisdn_data; - -/* Configuration functions */ -ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span); - -/* Support functions */ -uint32_t get_unique_suInstId(int16_t cc_id); -void clear_call_data(sngisdn_chan_data_t *sngisdn_info); -void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info); -ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data); -ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data); - -ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail); -ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail); -void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status); -void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status); - -ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); - - -void stack_hdr_init(Header *hdr); -void stack_pst_init(Pst *pst); - -/* Outbound Call Control functions */ -void sngisdn_snd_setup(ftdm_channel_t *ftdmchan); -void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan); -void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); -void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); -void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); -void sngisdn_snd_notify_req(ftdm_channel_t *ftdmchan); -void sngisdn_snd_connect(ftdm_channel_t *ftdmchan); -void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan); -void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare); -void sngisdn_snd_reset(ftdm_channel_t *ftdmchan); -void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan); -void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan); -void sngisdn_snd_dl_req(ftdm_channel_t *ftdmchan); -void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan); -void sngisdn_snd_restart(ftdm_channel_t *ftdmchan); -void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len); -void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event); - -/* Inbound Call Control functions */ -void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_con_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_cnst_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces); -void sngisdn_rcv_disc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt); -void sngisdn_rcv_rel_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt); -void sngisdn_rcv_dat_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt); -void sngisdn_rcv_sshl_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action); -void sngisdn_rcv_sshl_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action); -void sngisdn_rcv_rmrt_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action); -void sngisdn_rcv_rmrt_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action); -void sngisdn_rcv_flc_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt); -void sngisdn_rcv_fac_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces); -void sngisdn_rcv_sta_cfm(int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt); -void sngisdn_rcv_srv_ind(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_srv_cfm(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces); -void sngisdn_rcv_rst_cfm(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); -void sngisdn_rcv_rst_ind(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); -int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame); -int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd); - - -void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event); - -void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event); -void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event); - -void sngisdn_rcv_phy_ind(SuId suId, Reason reason); -void sngisdn_rcv_q921_ind(BdMngmt *status); - -void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); -void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); -void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); -void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); - -void sngisdn_get_memory_info(void); - -ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); -ftdm_status_t sngisdn_check_free_ids(void); - -void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf); -void sngisdn_rcv_q931_ind(InMngmt *status); -void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf); -void sngisdn_rcv_cc_ind(CcMngmt *status); -void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...); -void sngisdn_rcv_sng_assert(char *message); - -#ifdef NETBORDER_CALL_REF -ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef); -#endif -ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); -ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); -ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); -ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); -ftdm_status_t get_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt); -ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad); -ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd); -ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); -ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len); -ftdm_status_t get_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac); - -ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); -ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); -ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); -ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); -ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt); -ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad); -ftdm_status_t set_called_subaddr(ftdm_channel_t *ftdmchan, CdPtySad *cdPtySad); -ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind); -ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap); -ftdm_status_t set_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac); -ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId); -ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd); -ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); -ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len); -ftdm_status_t set_user_to_user_ie(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr); -ftdm_status_t set_cause_ie(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn); -ftdm_status_t set_not_ind_ie(ftdm_channel_t *ftdmchan, NotInd *notInd); - -ftdm_status_t sngisdn_add_var(sngisdn_chan_data_t *sngisdn_info, const char* var, const char* val); -ftdm_status_t sngisdn_add_raw_data(sngisdn_chan_data_t *sngisdn_info, uint8_t* data, ftdm_size_t data_len); -ftdm_status_t sngisdn_clear_data(sngisdn_chan_data_t *sngisdn_info); -void sngisdn_send_signal(sngisdn_chan_data_t *sngisdn_info, ftdm_signal_event_t event_id); - -uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability); -uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_prot); -ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability); -ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_stack(uint8_t layer1_prot); - -ftdm_status_t sngisdn_transfer(ftdm_channel_t *ftdmchan); -ftdm_status_t sngisdn_att_transfer_process_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf); - -static __inline__ uint32_t sngisdn_test_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag) -{ - return (uint32_t) sngisdn_info->flags & flag; -} -static __inline__ void sngisdn_clear_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag) -{ - sngisdn_info->flags &= ~flag; -} - -static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag) -{ - sngisdn_info->flags |= flag; -} - -#define sngisdn_set_trace_flag(obj, flag) ((obj)->trace_flags |= (flag)) -#define sngisdn_clear_trace_flag(obj, flag) ((obj)->trace_flags &= ~(flag)) -#define sngisdn_test_trace_flag(obj, flag) ((obj)->trace_flags & flag) - - -void handle_sng_log(uint8_t level, char *fmt,...); -void sngisdn_delayed_setup(void* p_sngisdn_info); -void sngisdn_delayed_release(void* p_sngisdn_info); -void sngisdn_delayed_release_nfas(void *p_sngisdn_info); -void sngisdn_delayed_connect(void* p_sngisdn_info); -void sngisdn_delayed_disconnect(void* p_sngisdn_info); -void sngisdn_facility_timeout(void* p_sngisdn_info); -void sngisdn_t3_timeout(void* p_sngisdn_info); -void sngisdn_restart_timeout(void* p_signal_data); -void sngisdn_delayed_dl_req(void* p_signal_data); - -/* Stack management functions */ -ftdm_status_t sngisdn_start_gen_cfg(void); -ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span); -ftdm_status_t sngisdn_stack_start(ftdm_span_t *span); -ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span); -ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span); -sngisdn_span_data_t *sngisdn_dchan(sngisdn_span_data_t *signal_data); - -ftdm_status_t sngisdn_show_l1_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span); -ftdm_status_t sngisdn_show_spans(ftdm_stream_handle_t *stream); -ftdm_status_t sngisdn_show_span(ftdm_stream_handle_t *stream, ftdm_span_t *span); - -#endif /* __FTMOD_SNG_ISDN_H__ */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c deleted file mode 100644 index 31a1a5b69f..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ - -#include "ftmod_sangoma_isdn.h" - -static ftdm_status_t parse_timer(const char* val, int32_t *target); -static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span); -static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span); -static ftdm_status_t parse_trunkgroup(const char *_trunkgroup); -static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span); -static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target); -static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span); - -extern ftdm_sngisdn_data_t g_sngisdn_data; - - -static ftdm_status_t parse_timer(const char* val, int32_t *target) -{ - *target = atoi(val); - if (*target < 0) { - *target = 0; - } - return FTDM_SUCCESS; -} - -static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target) -{ - if (ftdm_true(val)) { - *target = SNGISDN_OPT_TRUE; - } else { - *target = SNGISDN_OPT_FALSE; - } - return FTDM_SUCCESS; -} - -static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - - if (signal_data->num_local_numbers >= SNGISDN_NUM_LOCAL_NUMBERS) { - ftdm_log(FTDM_LOG_ERROR, "%s: Maximum number of local-numbers exceeded (max:%d)\n", span->name, SNGISDN_NUM_LOCAL_NUMBERS); - return FTDM_FAIL; - } - - signal_data->local_numbers[signal_data->num_local_numbers++] = ftdm_strdup(val); - return FTDM_SUCCESS; -} - -static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) -{ - unsigned i; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - //sngisdn_dchan_data_t *dchan_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - - switch(span->trunk_type) { - case FTDM_TRUNK_T1: - if (!strcasecmp(switch_name, "ni2") || - !strcasecmp(switch_name, "national")) { - signal_data->switchtype = SNGISDN_SWITCH_NI2; - } else if (!strcasecmp(switch_name, "5ess")) { - signal_data->switchtype = SNGISDN_SWITCH_5ESS; - } else if (!strcasecmp(switch_name, "4ess")) { - signal_data->switchtype = SNGISDN_SWITCH_4ESS; - } else if (!strcasecmp(switch_name, "dms100")) { - signal_data->switchtype = SNGISDN_SWITCH_DMS100; - } else if (!strcasecmp(switch_name, "qsig")) { - signal_data->switchtype = SNGISDN_SWITCH_QSIG; - } else { - ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type)); - return FTDM_FAIL; - } - break; - case FTDM_TRUNK_E1: - if (!strcasecmp(switch_name, "euroisdn") || - !strcasecmp(switch_name, "etsi")) { - signal_data->switchtype = SNGISDN_SWITCH_EUROISDN; - } else if (!strcasecmp(switch_name, "qsig")) { - signal_data->switchtype = SNGISDN_SWITCH_QSIG; - } else { - ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type)); - return FTDM_FAIL; - } - break; - case FTDM_TRUNK_BRI: - case FTDM_TRUNK_BRI_PTMP: - if (!strcasecmp(switch_name, "euroisdn") || - !strcasecmp(switch_name, "etsi")) { - signal_data->switchtype = SNGISDN_SWITCH_EUROISDN; - } else if (!strcasecmp(switch_name, "insnet") || - !strcasecmp(switch_name, "ntt")) { - signal_data->switchtype = SNGISDN_SWITCH_INSNET; - } else { - ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type)); - return FTDM_FAIL; - } - ftdm_set_flag(span, FTDM_SPAN_USE_AV_RATE); - ftdm_set_flag(span, FTDM_SPAN_PWR_SAVING); - /* can be > 1 for some BRI variants */ - break; - default: - ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunktype:%s\n", span->name, ftdm_trunk_type2str(span->trunk_type)); - return FTDM_FAIL; - } - - /* see if we have profile with this switch_type already */ - for (i = 1; i <= g_sngisdn_data.num_cc; i++) { - if (g_sngisdn_data.ccs[i].switchtype == signal_data->switchtype && - g_sngisdn_data.ccs[i].trunktype == span->trunk_type) { - break; - } - } - - /* need to create a new switch_type */ - if (i > g_sngisdn_data.num_cc) { - g_sngisdn_data.num_cc++; - g_sngisdn_data.ccs[i].switchtype = signal_data->switchtype; - g_sngisdn_data.ccs[i].trunktype = span->trunk_type; - ftdm_log(FTDM_LOG_DEBUG, "%s: New switchtype:%s cc_id:%u\n", span->name, switch_name, i); - } - - /* add this span to its ent_cc */ - signal_data->cc_id = i; - - g_sngisdn_data.spans[signal_data->link_id] = signal_data; - - ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d link_id:%d\n", span->name, signal_data->cc_id, signal_data->link_id); - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - int32_t chan_id; - ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - /* set the d-channel */ - signal_data->dchan = ftdmchan; - } else { - /* Add the channels to the span */ - chan_id = ftdmchan->physical_chan_id; - signal_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data; - signal_data->num_chans++; - } - } - ftdm_iterator_free(chaniter); - return FTDM_SUCCESS; -} - -static ftdm_status_t parse_signalling(const char *signalling, ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - if (!strcasecmp(signalling, "net") || - !strcasecmp(signalling, "pri_net")|| - !strcasecmp(signalling, "bri_net")) { - - signal_data->signalling = SNGISDN_SIGNALING_NET; - } else if (!strcasecmp(signalling, "cpe") || - !strcasecmp(signalling, "pri_cpe")|| - !strcasecmp(signalling, "bri_cpe")) { - - signal_data->signalling = SNGISDN_SIGNALING_CPE; - } else { - ftdm_log(FTDM_LOG_ERROR, "Unsupported signalling/interface %s\n", signalling); - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -static ftdm_status_t parse_spanmap(const char *_spanmap, ftdm_span_t *span) -{ - int i; - char *p, *name, *spanmap; - uint8_t logical_span_id = 0; - ftdm_status_t ret = FTDM_SUCCESS; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - - spanmap = ftdm_strdup(_spanmap); - - p = name = NULL; - - i = 0; - for (p = strtok(spanmap, ","); p; p = strtok(NULL, ",")) { - while (*p == ' ') { - p++; - } - switch(i++) { - case 0: - name = ftdm_strdup(p); - break; - case 1: - logical_span_id = atoi(p); - break; - } - } - - if (!name) { - ftdm_log(FTDM_LOG_ERROR, "Invalid spanmap syntax %s\n", _spanmap); - ret = FTDM_FAIL; - goto done; - } - - for (i = 0; i < g_sngisdn_data.num_nfas; i++) { - if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) && - !strcasecmp(g_sngisdn_data.nfass[i].name, name)) { - - signal_data->nfas.trunk = &g_sngisdn_data.nfass[i]; - break; - } - } - - if (!signal_data->nfas.trunk) { - ftdm_log(FTDM_LOG_ERROR, "Could not find trunkgroup with name %s\n", name); - ret = FTDM_FAIL; - goto done; - } - - if (signal_data->nfas.trunk->spans[logical_span_id]) { - ftdm_log(FTDM_LOG_ERROR, "trunkgroup:%s already had a span with logical span id:%d\n", name, logical_span_id); - } else { - signal_data->nfas.trunk->spans[logical_span_id] = signal_data; - signal_data->nfas.interface_id = logical_span_id; - } - - if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->dchan_span_name)) { - - signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_PRIMARY; - signal_data->nfas.trunk->dchan = signal_data; - } - - if (!strcasecmp(signal_data->ftdm_span->name, signal_data->nfas.trunk->backup_span_name)) { - - signal_data->nfas.sigchan = SNGISDN_NFAS_DCHAN_BACKUP; - signal_data->nfas.trunk->backup = signal_data; - } - -done: - ftdm_safe_free(spanmap); - ftdm_safe_free(name); - return ret; -} - -static ftdm_status_t parse_trunkgroup(const char *_trunkgroup) -{ - int i; - char *p, *name, *dchan_span, *backup_span, *trunkgroup; - uint8_t num_spans = 0; - ftdm_status_t ret = FTDM_SUCCESS; - - trunkgroup = ftdm_strdup(_trunkgroup); - - p = name = dchan_span = backup_span = NULL; - - /* format: name, num_chans, dchan_span, [backup_span] */ - - i = 0; - for (p = strtok(trunkgroup, ","); p; p = strtok(NULL, ",")) { - while (*p == ' ') { - p++; - } - switch(i++) { - case 0: - name = ftdm_strdup(p); - break; - case 1: - num_spans = atoi(p); - break; - case 2: - dchan_span = ftdm_strdup(p); - break; - case 3: - backup_span = ftdm_strdup(p); - } - } - - if (!name || !dchan_span || num_spans <= 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid parameters for trunkgroup:%s\n", _trunkgroup); - ret = FTDM_FAIL; - goto done; - } - - for (i = 0; i < g_sngisdn_data.num_nfas; i++) { - if (!ftdm_strlen_zero(g_sngisdn_data.nfass[i].name) && - !strcasecmp(g_sngisdn_data.nfass[i].name, name)) { - - /* We already configured this trunkgroup */ - goto done; - } - } - - /* Trunk group was not found, need to configure it */ - strncpy(g_sngisdn_data.nfass[i].name, name, sizeof(g_sngisdn_data.nfass[i].name)); - g_sngisdn_data.nfass[i].num_spans = num_spans; - strncpy(g_sngisdn_data.nfass[i].dchan_span_name, dchan_span, sizeof(g_sngisdn_data.nfass[i].dchan_span_name)); - - if (backup_span) { - strncpy(g_sngisdn_data.nfass[i].backup_span_name, backup_span, sizeof(g_sngisdn_data.nfass[i].backup_span_name)); - } - - - g_sngisdn_data.num_nfas++; -done: - ftdm_safe_free(trunkgroup); - ftdm_safe_free(name); - ftdm_safe_free(dchan_span); - ftdm_safe_free(backup_span); - return ret; -} - -static ftdm_status_t parse_early_media(const char* opt, ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - if (!strcasecmp(opt, "on-proceed")) { - signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROCEED; - } else if (!strcasecmp(opt, "on-progress")) { - signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROGRESS; - } else if (!strcasecmp(opt, "on-alert")) { - signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_ALERT; - } else { - ftdm_log(FTDM_LOG_ERROR, "Unsupported early-media option %s\n", opt); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "Early media opt:0x%x\n", signal_data->early_media_flags); - return FTDM_SUCCESS; -} - - -static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - switch(signal_data->switchtype) { - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_4ESS: - case SNGISDN_SWITCH_DMS100: - if (span->default_caller_data.dnis.plan >= FTDM_NPI_INVALID) { - ftdm_set_npi("isdn", &span->default_caller_data.dnis.plan); - } - if (span->default_caller_data.dnis.type >= FTDM_TON_INVALID) { - ftdm_set_ton("national", &span->default_caller_data.dnis.type); - } - if (span->default_caller_data.cid_num.plan >= FTDM_NPI_INVALID) { - ftdm_set_npi("isdn", &span->default_caller_data.cid_num.plan); - } - if (span->default_caller_data.cid_num.type >= FTDM_TON_INVALID) { - ftdm_set_ton("national", &span->default_caller_data.cid_num.type); - } - if (span->default_caller_data.rdnis.plan >= FTDM_NPI_INVALID) { - ftdm_set_npi("isdn", &span->default_caller_data.rdnis.plan); - } - if (span->default_caller_data.rdnis.type >= FTDM_TON_INVALID) { - ftdm_set_ton("national", &span->default_caller_data.rdnis.type); - } - break; - case SNGISDN_SWITCH_EUROISDN: - case SNGISDN_SWITCH_QSIG: - case SNGISDN_SWITCH_INSNET: - if (span->default_caller_data.dnis.plan >= FTDM_NPI_INVALID) { - ftdm_set_npi("unknown", &span->default_caller_data.dnis.plan); - } - if (span->default_caller_data.dnis.type >= FTDM_TON_INVALID) { - ftdm_set_ton("unknown", &span->default_caller_data.dnis.type); - } - if (span->default_caller_data.cid_num.plan >= FTDM_NPI_INVALID) { - ftdm_set_npi("unknown", &span->default_caller_data.cid_num.plan); - } - if (span->default_caller_data.cid_num.type >= FTDM_TON_INVALID) { - ftdm_set_ton("unknown", &span->default_caller_data.cid_num.type); - } - if (span->default_caller_data.rdnis.plan >= FTDM_NPI_INVALID) { - ftdm_set_npi("unknown", &span->default_caller_data.rdnis.plan); - } - if (span->default_caller_data.rdnis.type >= FTDM_TON_INVALID) { - ftdm_set_ton("unknown", &span->default_caller_data.rdnis.type); - } - break; - case SNGISDN_SWITCH_INVALID: - default: - ftdm_log(FTDM_LOG_ERROR, "Unsupported switchtype[%d]\n", signal_data->switchtype); - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - - -ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) -{ - unsigned paramindex; - const char *var, *val; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; - /* Set defaults here */ - signal_data->tei = 0; - signal_data->min_digits = 8; - signal_data->overlap_dial = SNGISDN_OPT_DEFAULT; - signal_data->setup_arb = SNGISDN_OPT_DEFAULT; - signal_data->facility_ie_decode = SNGISDN_OPT_DEFAULT; - signal_data->ignore_cause_value = SNGISDN_OPT_DEFAULT; - signal_data->timer_t3 = 8; - signal_data->restart_opt = SNGISDN_OPT_DEFAULT; - signal_data->link_id = span->span_id; - signal_data->transfer_timeout = 20000; - signal_data->att_remove_dtmf = SNGISDN_OPT_DEFAULT; - signal_data->force_sending_complete = SNGISDN_OPT_DEFAULT; - - signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO; - signal_data->send_cid_name = SNGISDN_OPT_DEFAULT; - signal_data->send_connect_ack = SNGISDN_OPT_DEFAULT; - - span->default_caller_data.dnis.plan = FTDM_NPI_INVALID; - span->default_caller_data.dnis.type = FTDM_TON_INVALID; - span->default_caller_data.cid_num.plan = FTDM_NPI_INVALID; - span->default_caller_data.cid_num.type = FTDM_TON_INVALID; - span->default_caller_data.rdnis.plan = FTDM_NPI_INVALID; - span->default_caller_data.rdnis.type = FTDM_TON_INVALID; - - span->default_caller_data.bearer_capability = IN_ITC_SPEECH; - /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */ - span->default_caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM; - - /* Find out if NFAS is enabled first */ - for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { - ftdm_log(FTDM_LOG_DEBUG, "Sangoma ISDN key=value, %s=%s\n", ftdm_parameters[paramindex].var, ftdm_parameters[paramindex].val); - var = ftdm_parameters[paramindex].var; - val = ftdm_parameters[paramindex].val; - - if (!strcasecmp(var, "trunkgroup")) { - if (parse_trunkgroup(val) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } - } - - for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { - ftdm_log(FTDM_LOG_DEBUG, "Sangoma ISDN key=value, %s=%s\n", ftdm_parameters[paramindex].var, ftdm_parameters[paramindex].val); - var = ftdm_parameters[paramindex].var; - val = ftdm_parameters[paramindex].val; - - if (!strcasecmp(var, "switchtype")) { - if (parse_switchtype(val, span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - if (set_switchtype_defaults(span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "signalling") || - !strcasecmp(var, "interface")) { - if (parse_signalling(val, span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "spanmap")) { - if (parse_spanmap(val, span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "tei")) { - uint8_t tei = atoi(val); - if (tei > 127) { - ftdm_log(FTDM_LOG_ERROR, "Invalid TEI %d, valid values are (0-127)", tei); - return FTDM_FAIL; - } - signal_data->tei = tei; - } else if (!strcasecmp(var, "overlap")) { - if (!strcasecmp(val, "yes")) { - signal_data->overlap_dial = SNGISDN_OPT_TRUE; - } else if (!strcasecmp(val, "no")) { - signal_data->overlap_dial = SNGISDN_OPT_FALSE; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val); - } - } else if (!strcasecmp(var, "setup-arbitration")) { - parse_yesno(var, val, &signal_data->setup_arb); - } else if (!strcasecmp(var, "facility")) { - parse_yesno(var, val, &signal_data->facility); - } else if (!strcasecmp(var, "min-digits") || - !strcasecmp(var, "min_digits")) { - signal_data->min_digits = atoi(val); - } else if (!strcasecmp(var, "outbound-called-ton")) { - ftdm_set_ton(val, &span->default_caller_data.dnis.type); - } else if (!strcasecmp(var, "outbound-called-npi")) { - ftdm_set_npi(val, &span->default_caller_data.dnis.plan); - } else if (!strcasecmp(var, "outbound-calling-ton")) { - ftdm_set_ton(val, &span->default_caller_data.cid_num.type); - } else if (!strcasecmp(var, "outbound-calling-npi")) { - ftdm_set_npi(val, &span->default_caller_data.cid_num.plan); - } else if (!strcasecmp(var, "outbound-rdnis-ton")) { - ftdm_set_ton(val, &span->default_caller_data.rdnis.type); - } else if (!strcasecmp(var, "outbound-rdnis-npi")) { - ftdm_set_npi(val, &span->default_caller_data.rdnis.plan); - } else if (!strcasecmp(var, "outbound-bc-transfer-cap") || - !strcasecmp(var, "outbound-bearer_cap")) { - ftdm_set_bearer_capability(val, (uint8_t*)&span->default_caller_data.bearer_capability); - } else if (!strcasecmp(var, "outbound-bc-user-layer1") || - !strcasecmp(var, "outbound-bearer_layer1")) { - ftdm_set_bearer_layer1(val, (uint8_t*)&span->default_caller_data.bearer_layer1); - } else if (!strcasecmp(var, "channel-restart-on-link-up")) { - parse_yesno(var, val, &signal_data->restart_opt); - } else if (!strcasecmp(var, "channel-restart-timeout")) { - signal_data->restart_timeout = atoi(val); - } else if (!strcasecmp(var, "local-number")) { - if (add_local_number(val, span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "facility-timeout")) { - parse_timer(val, &signal_data->facility_timeout); - } else if (!strcasecmp(var, "transfer-timeout")) { - parse_timer(val, &signal_data->transfer_timeout); - } else if (!strcasecmp(var, "att-remove-dtmf")) { - parse_yesno(var, val, &signal_data->att_remove_dtmf); - } else if (!strcasecmp(var, "facility-ie-decode")) { - parse_yesno(var, val, &signal_data->facility_ie_decode); - } else if (!strcasecmp(var, "ignore-cause-value")) { - parse_yesno(var, val, &signal_data->ignore_cause_value); - } else if (!strcasecmp(var, "q931-trace")) { - parse_yesno(var, val, &signal_data->trace_q931); - } else if (!strcasecmp(var, "q921-trace")) { - parse_yesno(var, val, &signal_data->trace_q921); - } else if (!strcasecmp(var, "q931-raw-trace")) { - parse_yesno(var, val, &signal_data->raw_trace_q931); - } else if (!strcasecmp(var, "q921-raw-trace")) { - parse_yesno(var, val, &signal_data->raw_trace_q921); - } else if (!strcasecmp(var, "force-sending-complete")) { - parse_yesno(var, val, &signal_data->force_sending_complete); - } else if (!strcasecmp(var, "early-media-override")) { - if (parse_early_media(val, span) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else if (!strcasecmp(var, "chan-id-invert-extend-bit")) { -#ifdef SANGOMA_ISDN_CHAN_ID_INVERT_BIT - parse_yesno(var, val, &g_sngisdn_data.chan_id_invert_extend_bit); -#else - ftdm_log(FTDM_LOG_WARNING, "chan-id-invert-extend-bit is not supported in your version of libsng_isdn\n"); -#endif - } else if (!strcasecmp(var, "cid-name-transmit-method")) { - if (!strcasecmp(val, "display-ie")) { - signal_data->cid_name_method = SNGISDN_CID_NAME_DISPLAY_IE; - } else if (!strcasecmp(val, "user-user-ie")) { - signal_data->cid_name_method = SNGISDN_CID_NAME_USR_USR_IE; - } else if (!strcasecmp(val, "facility-ie")) { - signal_data->cid_name_method = SNGISDN_CID_NAME_FACILITY_IE; - } else if (!strcasecmp(val, "auto") || !strcasecmp(val, "automatic") || !strcasecmp(val, "default")) { - signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO; - } else { - ftdm_log(FTDM_LOG_WARNING, "Invalid option %s for parameter %s\n", val, var); - signal_data->cid_name_method = SNGISDN_CID_NAME_AUTO; - } - } else if (!strcasecmp(var, "send-cid-name")) { - if (!strcasecmp(val, "yes")) { - signal_data->send_cid_name = SNGISDN_OPT_TRUE; - } else if (!strcasecmp(val, "no")) { - signal_data->send_cid_name = SNGISDN_OPT_FALSE; - } else if (!strcasecmp(val, "auto") || !strcasecmp(val, "automatic") || !strcasecmp(val, "default")) { - signal_data->send_cid_name = SNGISDN_OPT_DEFAULT; - } else { - ftdm_log(FTDM_LOG_WARNING, "Invalid option %s for parameter %s\n", val, var); - signal_data->send_cid_name = SNGISDN_OPT_DEFAULT; - } - } else if (!strcasecmp(var, "timer-t301")) { - parse_timer(val, &signal_data->timer_t301); - } else if (!strcasecmp(var, "timer-t302")) { - parse_timer(val, &signal_data->timer_t302); - } else if (!strcasecmp(var, "timer-t303")) { - parse_timer(val, &signal_data->timer_t303); - } else if (!strcasecmp(var, "timer-t304")) { - parse_timer(val, &signal_data->timer_t304); - } else if (!strcasecmp(var, "timer-t305")) { - parse_timer(val, &signal_data->timer_t305); - } else if (!strcasecmp(var, "timer-t306")) { - parse_timer(val, &signal_data->timer_t306); - } else if (!strcasecmp(var, "timer-t307")) { - parse_timer(val, &signal_data->timer_t307); - } else if (!strcasecmp(var, "timer-t308")) { - parse_timer(val, &signal_data->timer_t308); - } else if (!strcasecmp(var, "timer-t310")) { - parse_timer(val, &signal_data->timer_t310); - } else if (!strcasecmp(var, "timer-t312")) { - parse_timer(val, &signal_data->timer_t312); - } else if (!strcasecmp(var, "timer-t313")) { - parse_timer(val, &signal_data->timer_t313); - } else if (!strcasecmp(var, "timer-t314")) { - parse_timer(val, &signal_data->timer_t314); - } else if (!strcasecmp(var, "timer-t316")) { - parse_timer(val, &signal_data->timer_t316); - } else if (!strcasecmp(var, "timer-t318")) { - parse_timer(val, &signal_data->timer_t318); - } else if (!strcasecmp(var, "timer-t319")) { - parse_timer(val, &signal_data->timer_t319); - } else if (!strcasecmp(var, "timer-t322")) { - parse_timer(val, &signal_data->timer_t322); - } else if (!strcasecmp(var, "trunkgroup")) { - /* Do nothing, we already parsed this parameter */ - } else if (!strcasecmp(var, "send-connect-ack")) { - parse_yesno(var, val, &signal_data->send_connect_ack); - } else { - ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); - } - } /* for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) */ - - if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) { - ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name); - return FTDM_FAIL; - } - if (signal_data->signalling == SNGISDN_SIGNALING_INVALID) { - ftdm_log(FTDM_LOG_ERROR, "%s: signalling not specified", span->name); - return FTDM_FAIL; - } - - if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) { - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || - signal_data->switchtype == SNGISDN_SWITCH_QSIG) { - span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW; - } else { - span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; - } - } - return FTDM_SUCCESS; -} - - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c deleted file mode 100644 index c0caf10ab7..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ - -#include "ftmod_sangoma_isdn.h" - -void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status); - -void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -{ - ftdm_sigmsg_t sig; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)ftdmchan->span->signal_data; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status)); - - memset(&sig, 0, sizeof(sig)); - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - ftdm_span_send_signal(ftdmchan->span, &sig); - - if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) { - ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); - - ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) sngisdn_info, NULL); - } - } - return; -} - -void sngisdn_set_span_sig_status(ftdm_span_t *span, ftdm_signaling_status_t status) -{ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - ((sngisdn_span_data_t*)span->signal_data)->sigstatus = status; - - if (status == FTDM_SIG_STATE_UP) { - ((sngisdn_span_data_t*)span->signal_data)->dl_request_pending = 0; - } - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - sngisdn_set_chan_sig_status(((ftdm_channel_t*)ftdm_iterator_current(curr)), status); - } - ftdm_iterator_free(chaniter); - return; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c deleted file mode 100644 index 92d401d5e0..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" - -extern ftdm_sngisdn_data_t g_sngisdn_data; - -uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype); - -ftdm_status_t sngisdn_cfg_phy(ftdm_span_t *span); -ftdm_status_t sngisdn_cfg_q921(ftdm_span_t *span); -ftdm_status_t sngisdn_cfg_q931(ftdm_span_t *span); -ftdm_status_t sngisdn_cfg_cc(ftdm_span_t *span); - -ftdm_status_t sngisdn_stack_cfg_phy_gen(void); -ftdm_status_t sngisdn_stack_cfg_q921_gen(void); -ftdm_status_t sngisdn_stack_cfg_q931_gen(void); -ftdm_status_t sngisdn_stack_cfg_cc_gen(void); - - -ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span); -ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span); -ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management); -ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span); -ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span); -ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span); - -ftdm_status_t sngisdn_stack_cfg_cc_sap(ftdm_span_t *span); - -ftdm_status_t sngisdn_start_gen_cfg(void) -{ - if (!g_sngisdn_data.gen_config_done) { - g_sngisdn_data.gen_config_done = 1; - ftdm_log(FTDM_LOG_DEBUG, "Starting general stack configuration\n"); - if(sngisdn_stack_cfg_phy_gen()!= FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed general physical configuration\n"); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "General stack physical done\n"); - - if(sngisdn_stack_cfg_q921_gen()!= FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n"); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "General stack q921 done\n"); - - if(sngisdn_stack_cfg_q931_gen()!= FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed general q921 configuration\n"); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "General stack q931 done\n"); - - if(sngisdn_stack_cfg_cc_gen()!= FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed general CC configuration\n"); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "General stack CC done\n"); - ftdm_log(FTDM_LOG_INFO, "General stack configuration done\n"); - } - return FTDM_SUCCESS; -} - - -ftdm_status_t sngisdn_stack_cfg(ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - ftdm_log(FTDM_LOG_DEBUG, "Starting stack configuration for span:%s\n", span->name); - - if (signal_data->dchan) { - if (sngisdn_stack_cfg_phy_psap(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:phy_psap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:phy_psap configuration done\n", span->name); - - if (sngisdn_stack_cfg_q921_msap(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q921_msap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q921_msap configuration done\n", span->name); - - if (sngisdn_stack_cfg_q921_dlsap(span, 0) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap configuration done\n", span->name); - - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - if (sngisdn_stack_cfg_q921_dlsap(span, 1) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q921_dlsap management configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q921_dlsap management configuration done\n", span->name); - } - } - - if (sngisdn_stack_cfg_q931_dlsap(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q931_dlsap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q931_dlsap configuration done\n", span->name); - - if (signal_data->dchan) { - if (sngisdn_stack_cfg_q931_lce(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q931_lce configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q931_lce configuration done\n", span->name); - } - - if (!g_sngisdn_data.ccs[signal_data->cc_id].config_done) { - g_sngisdn_data.ccs[signal_data->cc_id].config_done = 1; - /* if BRI, need to configure dlsap_mgmt */ - if (sngisdn_stack_cfg_q931_tsap(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:q931_tsap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:q931_tsap configuration done\n", span->name); - - if (sngisdn_stack_cfg_cc_sap(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "%s:cc_sap configuration failed\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:cc_sap configuration done\n", span->name); - } - - ftdm_log(FTDM_LOG_INFO, "%s:stack configuration done\n", span->name); - return FTDM_SUCCESS; -} - - - -ftdm_status_t sngisdn_stack_cfg_phy_gen(void) -{ - /*local variables*/ - L1Mngmt cfg; /*configuration structure*/ - Pst pst; /*post structure*/ - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTL1; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTL1; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - stack_pst_init(&cfg.t.cfg.s.l1Gen.sm ); - cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1; - cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM; - - cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS; - cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */ - cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ - - if (sng_isdn_phy_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) -{ - L1Mngmt cfg; - Pst pst; - - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTL1; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTL1; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STPSAP; - - cfg.hdr.elmId.elmntInst1 = signal_data->link_id; - - if (!signal_data->dchan) { - ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name); - return FTDM_FAIL; - } - - cfg.t.cfg.s.l1PSAP.sockfd = (int32_t)signal_data->dchan->sockfd; - - switch(span->trunk_type) { - case FTDM_TRUNK_E1: - cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI; - break; - case FTDM_TRUNK_T1: - case FTDM_TRUNK_J1: - cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI; - break; - case FTDM_TRUNK_BRI: - case FTDM_TRUNK_BRI_PTMP: - cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_BRI; - break; - default: - ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type); - return FTDM_FAIL; - } - - cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id; - - if (sng_isdn_phy_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - - -ftdm_status_t sngisdn_stack_cfg_q921_gen(void) -{ - BdMngmt cfg; - Pst pst; - - /* initalize the post structure */ - stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTLD; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTLD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - /* fill in the Gen Conf structures internal pst struct */ - - stack_pst_init(&cfg.t.cfg.s.bdGen.sm); - - cfg.t.cfg.s.bdGen.sm.dstEnt = ENTSM; /* entity */ - - cfg.t.cfg.s.bdGen.nmbPLnks = MAX_L1_LINKS+1; - cfg.t.cfg.s.bdGen.nmbLDLnks = MAX_L1_LINKS+1; /* Not used in LAPD */ - cfg.t.cfg.s.bdGen.nmbDLCs = MAX_L1_LINKS+1; - cfg.t.cfg.s.bdGen.nmbDLCs = MAX_TEIS_PER_LINK*(MAX_L1_LINKS+1); - cfg.t.cfg.s.bdGen.nmbASPLnks = MAX_L1_LINKS+1; - -#ifdef LAPD_3_4 - cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */ -#endif - cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */ - cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */ - - if (sng_isdn_q921_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span) -{ - BdMngmt cfg; - Pst pst; - - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTLD; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTLD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STMSAP; - - cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id; - - cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */ - cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */ - cfg.t.cfg.s.bdMSAP.tQLowerTrs = 24; /* Tx Queue Lower Threshold */ - cfg.t.cfg.s.bdMSAP.selector = 0; /* Selector 0 */ - /* TODO: check if bdMSAP parameters can be initialized by calling stack_pst_init */ - cfg.t.cfg.s.bdMSAP.mem.region = S_REG; /* Memory region */ - cfg.t.cfg.s.bdMSAP.mem.pool = S_POOL; /* Memory pool */ - cfg.t.cfg.s.bdMSAP.prior = PRIOR0; /* Priority */ - cfg.t.cfg.s.bdMSAP.route = RTESPEC; /* Route */ - cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */ - cfg.t.cfg.s.bdMSAP.dstEnt = ENTL1; /* entity */ - cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */ - cfg.t.cfg.s.bdMSAP.t201Tmr = 1; /* T201 - should be equal to t200Tmr */ - cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */ - cfg.t.cfg.s.bdMSAP.bndRetryCnt = 2; /* bind retry counter */ - cfg.t.cfg.s.bdMSAP.tIntTmr = 200; /* bind retry timer */ - cfg.t.cfg.s.bdMSAP.n202 = 3; /* N202 */ - cfg.t.cfg.s.bdMSAP.lowTei = 64; /* Lowest dynamic TEI */ - - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && - signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.bdMSAP.kpL1Up = FALSE; /* flag to keep l1 up or not */ - } else { - cfg.t.cfg.s.bdMSAP.kpL1Up = TRUE; /* flag to keep l1 up or not */ - } - - switch(signal_data->switchtype) { - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_4ESS: - case SNGISDN_SWITCH_DMS100: - cfg.t.cfg.s.bdMSAP.type = SW_NI2; - break; - case SNGISDN_SWITCH_INSNET: - cfg.t.cfg.s.bdMSAP.type = SW_CCITT; - break; - case SNGISDN_SWITCH_EUROISDN: - case SNGISDN_SWITCH_QSIG: - cfg.t.cfg.s.bdMSAP.type = SW_ETSI; - break; - } - - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - cfg.t.cfg.s.bdMSAP.teiChkTmr = 20; /* Tei check timer */ - } else { - cfg.t.cfg.s.bdMSAP.teiChkTmr = 0; /* Tei check timer */ - } - - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.bdMSAP.logInt = 1; /* logical interface = 0 = user, 1= network */ - cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE; /* set up arbitration */ - } else { - cfg.t.cfg.s.bdMSAP.logInt = 0; /* logical interface = 0 = user, 1= network */ - cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE; /* set up arbitration */ - } - - /* Overwrite setUpArb value if user forced it */ - if (signal_data->setup_arb == SNGISDN_OPT_TRUE) { - cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE; - } else if (signal_data->setup_arb == SNGISDN_OPT_FALSE) { - cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE; - } - - if (sng_isdn_q921_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management) -{ - BdMngmt cfg; - Pst pst; - - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); - /* insert the destination Entity */ - pst.dstEnt = ENTLD; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTLD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLSAP; - - cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id; - - cfg.t.cfg.s.bdDLSAP.n201 = 1028; /* n201 */ - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || - span->trunk_type == FTDM_TRUNK_BRI) { - - cfg.t.cfg.s.bdDLSAP.k = 1; /* Based on q.921 recommendations */ - } else { - cfg.t.cfg.s.bdDLSAP.k = 7; /* k */ - } - - cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */ - cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */ - cfg.t.cfg.s.bdDLSAP.t200Tmr = 3; /* t1 changed from 25 */ - cfg.t.cfg.s.bdDLSAP.t203Tmr = 10; /* t3 changed from 50 */ - cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */ - cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */ - cfg.t.cfg.s.bdDLSAP.mem.region = S_REG; /* Memory region */ - cfg.t.cfg.s.bdDLSAP.mem.pool = S_POOL; /* Memory pool */ - cfg.t.cfg.s.bdDLSAP.prior = PRIOR0; /* Priority */ - cfg.t.cfg.s.bdDLSAP.route = RTESPEC; /* Route */ - - if (management) { - cfg.t.cfg.s.bdDLSAP.sapi = MNGMT_SAPI; - cfg.t.cfg.s.bdDLSAP.teiAss = NON_AUTOMATIC; /* static tei assignment */ - cfg.t.cfg.s.bdDLSAP.noOfDlc = 1; - cfg.t.cfg.s.bdDLSAP.tei[0] = 0x7f; - } else { - cfg.t.cfg.s.bdDLSAP.sapi = Q930_SAPI; - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.bdDLSAP.teiAss = AUTOMATIC; - cfg.t.cfg.s.bdDLSAP.noOfDlc = 8; - - cfg.t.cfg.s.bdDLSAP.tei[0] = 64; - cfg.t.cfg.s.bdDLSAP.tei[1] = 65; - cfg.t.cfg.s.bdDLSAP.tei[2] = 66; - cfg.t.cfg.s.bdDLSAP.tei[3] = 67; - cfg.t.cfg.s.bdDLSAP.tei[4] = 68; - cfg.t.cfg.s.bdDLSAP.tei[5] = 69; - cfg.t.cfg.s.bdDLSAP.tei[6] = 70; - cfg.t.cfg.s.bdDLSAP.tei[7] = 71; - } else { - cfg.t.cfg.s.bdDLSAP.teiAss = AUTOMATIC; - cfg.t.cfg.s.bdDLSAP.noOfDlc = 1; - } - } else { - /* Point to point configs */ - cfg.t.cfg.s.bdDLSAP.teiAss = NON_AUTOMATIC; - cfg.t.cfg.s.bdDLSAP.noOfDlc = 1; - cfg.t.cfg.s.bdDLSAP.tei[0] = signal_data->tei; - } - } - - if (sng_isdn_q921_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_stack_cfg_q931_gen(void) -{ - InMngmt cfg; - Pst pst; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTIN; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - /* fill in the Gen Conf structures internal pst struct */ - stack_pst_init(&cfg.t.cfg.s.inGen.sm); - - cfg.t.cfg.s.inGen.nmbSaps = MAX_VARIANTS+1; /* Total number of variants supported */ - - cfg.t.cfg.s.inGen.nmbLnks = MAX_L1_LINKS+1; /* number of Data Link SAPs */ - cfg.t.cfg.s.inGen.nmbSigLnks = MAX_L1_LINKS+1; - - /* number of CESs */ - cfg.t.cfg.s.inGen.nmbCes = (MAX_L1_LINKS+1)*MAX_NUM_CES_PER_LINK; - /* number of global Call References can have 2 per channel when using HOLD/RESUME */ - cfg.t.cfg.s.inGen.nmbCalRef = MAX_NUM_CALLS; - /* number of bearer channels */ - cfg.t.cfg.s.inGen.nmbBearer = NUM_E1_CHANNELS_PER_SPAN*(MAX_L1_LINKS+1); - /* maximum number of routing entries */ - cfg.t.cfg.s.inGen.nmbRouts = 0; - /* number of profiles */ - cfg.t.cfg.s.inGen.nmbProfiles = 0; - /* upper pool threshold */ - cfg.t.cfg.s.inGen.poolTrUpper = INGEN_POOL_UP_TR; - /* time resolution */ - cfg.t.cfg.s.inGen.timeRes = 100; /* timer resolution = 1 sec */ - - cfg.t.cfg.s.inGen.sm.dstEnt = ENTSM; - - if (sng_isdn_q931_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -/* Link between CC and q931 */ -ftdm_status_t sngisdn_stack_cfg_q931_tsap(ftdm_span_t *span) -{ - InMngmt cfg; - Pst pst; - unsigned i; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTIN; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STTSAP; - - cfg.t.cfg.s.inTSAP.sapId = signal_data->cc_id; - - cfg.t.cfg.s.inTSAP.prior = PRIOR0; - cfg.t.cfg.s.inTSAP.route = RTESPEC; - - cfg.t.cfg.s.inTSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); - cfg.t.cfg.s.inTSAP.useSubAdr = 0; /* call routing on subaddress */ - cfg.t.cfg.s.inTSAP.adrPref = 0; /* use of prefix for int'l calls */ - cfg.t.cfg.s.inTSAP.nmbPrefDig = 0; /* number of digits used for prefix */ - - for (i = 0; i < IN_MAXPREFDIG; i++) - cfg.t.cfg.s.inTSAP.prefix[i] = 0; /* address prefix */ - - cfg.t.cfg.s.inTSAP.keyPad = 0; - cfg.t.cfg.s.inTSAP.wcRout = 0; - - for (i = 0; i < ADRLEN; i++) - cfg.t.cfg.s.inTSAP.wcMask[i] = 0; /* address prefix */ - - cfg.t.cfg.s.inTSAP.sidIns = FALSE; /* SID insertion Flag */ - cfg.t.cfg.s.inTSAP.sid.length = 0; /* SID */ - cfg.t.cfg.s.inTSAP.sidTon = 0; /* SID Type of Number */ - cfg.t.cfg.s.inTSAP.sidNPlan = 0; /* SID Numbering Plan */ - cfg.t.cfg.s.inTSAP.callId.len = 0; /* Default Call Identity */ - cfg.t.cfg.s.inTSAP.minAdrDig = 0; /* Minimum number of address digits */ - cfg.t.cfg.s.inTSAP.comptChck = FALSE; /* Validate compatibility */ - cfg.t.cfg.s.inTSAP.nmbApplProf = 0; /* Number of application profiles */ - cfg.t.cfg.s.inTSAP.profNmb[0] = 0; /* Application profiles */ - cfg.t.cfg.s.inTSAP.mem.region = S_REG; - cfg.t.cfg.s.inTSAP.mem.pool = S_POOL; - cfg.t.cfg.s.inTSAP.selector = 0; - - - if (sng_isdn_q931_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) -{ - InMngmt cfg; - Pst pst; - - unsigned i; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTIN; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLSAP; - - cfg.hdr.response.selector=0; - - cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id; - cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id; - - cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); - - cfg.t.cfg.s.inDLSAP.n201 = 1024; - cfg.t.cfg.s.inDLSAP.nmbRst = 2; - cfg.t.cfg.s.inDLSAP.tCbCfg = TRUE; - - cfg.t.cfg.s.inDLSAP.tCbId = signal_data->cc_id; - - if (signal_data->facility == SNGISDN_OPT_TRUE) { - cfg.t.cfg.s.inDLSAP.facilityHandling = IN_FACILITY_STANDRD; - } else { - cfg.t.cfg.s.inDLSAP.facilityHandling = 0; - } - - if (!signal_data->nfas.trunk) { - cfg.t.cfg.s.inDLSAP.nfasInt = FALSE; - cfg.t.cfg.s.inDLSAP.intId = 0; - cfg.t.cfg.s.inDLSAP.sigInt = 0; - cfg.t.cfg.s.inDLSAP.bupInt = 0; - cfg.t.cfg.s.inDLSAP.nmbNfasInt = 0; - cfg.t.cfg.s.inDLSAP.buIntPr = FALSE; - - for (i = 0; i < IN_MAX_NMB_INTRFS; i++) - cfg.t.cfg.s.inDLSAP.ctldInt[i] = IN_INT_NOT_CFGD; - - } else { - cfg.t.cfg.s.inDLSAP.nfasInt = TRUE; - cfg.t.cfg.s.inDLSAP.intId = signal_data->nfas.interface_id; - - for (i = 0; i < IN_MAX_NMB_INTRFS; i++) - cfg.t.cfg.s.inDLSAP.ctldInt[i] = IN_INT_NOT_CFGD; - - switch (signal_data->nfas.sigchan) { - case SNGISDN_NFAS_DCHAN_PRIMARY: - cfg.t.cfg.s.inDLSAP.sigInt = signal_data->nfas.trunk->dchan->link_id; - cfg.t.cfg.s.inDLSAP.nmbNfasInt = signal_data->nfas.trunk->num_spans; - - if (signal_data->nfas.trunk->backup) { - cfg.t.cfg.s.inDLSAP.buIntPr = TRUE; - cfg.t.cfg.s.inDLSAP.bupInt = signal_data->nfas.trunk->backup->link_id; - } else { - cfg.t.cfg.s.inDLSAP.buIntPr = FALSE; - } - - for (i = 0; i < MAX_SPANS_PER_NFAS_LINK; i++) { - if (signal_data->nfas.trunk->spans[i]) { - cfg.t.cfg.s.inDLSAP.ctldInt[i] = signal_data->nfas.trunk->spans[i]->link_id; - } - } - - break; - case SNGISDN_NFAS_DCHAN_BACKUP: - cfg.t.cfg.s.inDLSAP.sigInt = signal_data->nfas.trunk->dchan->link_id; - cfg.t.cfg.s.inDLSAP.nmbNfasInt = signal_data->nfas.trunk->num_spans; - - if (signal_data->nfas.trunk->backup) { - cfg.t.cfg.s.inDLSAP.buIntPr = TRUE; - cfg.t.cfg.s.inDLSAP.bupInt = signal_data->nfas.trunk->backup->link_id; - } else { - cfg.t.cfg.s.inDLSAP.buIntPr = FALSE; - } - - for (i = 0; i < MAX_SPANS_PER_NFAS_LINK; i++) { - if (signal_data->nfas.trunk->spans[i]) { - cfg.t.cfg.s.inDLSAP.ctldInt[i] = signal_data->nfas.trunk->spans[i]->link_id; - } - } - - break; - case SNGISDN_NFAS_DCHAN_NONE: - cfg.t.cfg.s.inDLSAP.sigInt = signal_data->nfas.trunk->dchan->link_id; - cfg.t.cfg.s.inDLSAP.nmbNfasInt = 0; - - break; - } - } - - cfg.t.cfg.s.inDLSAP.numRstInd = 255; - cfg.t.cfg.s.inDLSAP.relOpt = TRUE; -#ifdef ISDN_SRV - cfg.t.cfg.s.inDLSAP.bcas = FALSE; - cfg.t.cfg.s.inDLSAP.maxBSrvCnt = 2; - cfg.t.cfg.s.inDLSAP.maxDSrvCnt = 2; -#endif /* ISDN_SRV */ - - if (signal_data->switchtype == SNGISDN_SWITCH_QSIG) { - cfg.t.cfg.s.inDLSAP.intType = SYM_USER; - cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ - cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; - cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; - } else { - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.inDLSAP.intType = NETWORK; - cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */ - cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE; - - if (signal_data->ftdm_span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; - } else { - cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; - } - } else { - cfg.t.cfg.s.inDLSAP.intType = USER; - cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ - cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; - cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; - } - } - - if (signal_data->switchtype == SNGISDN_SWITCH_QSIG || - signal_data->switchtype == SNGISDN_SWITCH_5ESS) { - - cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; - } else if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; - } else { - cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; - } - - if (signal_data->send_connect_ack != SNGISDN_OPT_DEFAULT) { - if (signal_data->send_connect_ack == SNGISDN_OPT_TRUE) { - cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; - } else { - cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; - } - } - - /* Override the restart options if user selected that option */ - if (signal_data->restart_opt != SNGISDN_OPT_DEFAULT) { - if (signal_data->restart_opt == SNGISDN_OPT_TRUE) { - cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; - } else { - cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; - } - } - - for (i = 0; i < IN_MAXBCHNL; i++) - { - cfg.t.cfg.s.inDLSAP.bProf[i].profNmb = 0; - cfg.t.cfg.s.inDLSAP.bProf[i].valid = FALSE; - cfg.t.cfg.s.inDLSAP.bProf[i].state = IN_PROV_AVAIL; - } - - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && - signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.inDLSAP.nmbCes = MAX_NUM_CES_PER_LINK; - } else { - cfg.t.cfg.s.inDLSAP.nmbCes=1; - } - - cfg.t.cfg.s.inDLSAP.useSubAdr = 0; /* call routing on subaddress */ -#ifdef SANGOMA_ISDN_CHAN_ID_INVERT_BIT - if (signal_data->switchtype == SNGISDN_SWITCH_DMS100 && - g_sngisdn_data.chan_id_invert_extend_bit == SNGISDN_OPT_TRUE) { - /* Since this feature is not standard, we modified Trillium to check - the useSubAdr field and remove the extended bit if this is set, this - is a global configuration and once set, applies to all spans configured - as DMS 100 */ - cfg.t.cfg.s.inDLSAP.useSubAdr = PRSNT_NODEF; - } -#endif - cfg.t.cfg.s.inDLSAP.adrPref = 0; /* use of prefix for international calls */ - cfg.t.cfg.s.inDLSAP.nmbPrefDig = 0; /* number of digits used for prefix */ - for (i = 0; i < IN_MAXPREFDIG; i++) - cfg.t.cfg.s.inDLSAP.prefix[i] = 0; /* address prefix */ - cfg.t.cfg.s.inDLSAP.keyPad = 0; - cfg.t.cfg.s.inDLSAP.wcRout = 0; - for (i = 0; i < ADRLEN; i++) - cfg.t.cfg.s.inDLSAP.wcMask[i] = 0; /* address prefix */ - - cfg.t.cfg.s.inDLSAP.sidIns = FALSE; /* SID insertion flag */ - cfg.t.cfg.s.inDLSAP.sid.length = 0; /* SID */ - cfg.t.cfg.s.inDLSAP.sidTon = 0; /* SID Type of Number */ - cfg.t.cfg.s.inDLSAP.sidNPlan = 0; /* SID Numbering Plan */ - cfg.t.cfg.s.inDLSAP.sidPresInd = FALSE; /* SID Presentation Indicator */ - cfg.t.cfg.s.inDLSAP.minAdrDig = 0; /* minimum number of address digits */ - cfg.t.cfg.s.inDLSAP.srvOpt = FALSE; - cfg.t.cfg.s.inDLSAP.callId.len = 0; /* default call id */ - cfg.t.cfg.s.inDLSAP.redirSubsc = FALSE; /* subscription to call redirection */ - cfg.t.cfg.s.inDLSAP.redirAdr.eh.pres = NOTPRSNT; /* redirAdr Numbering Plan */ - cfg.t.cfg.s.inDLSAP.forwSubsc = FALSE; /* programmed forwarding subscription */ - cfg.t.cfg.s.inDLSAP.cndSubsc = TRUE; /* calling adddress delivery service subscription */ - - cfg.t.cfg.s.inDLSAP.tmr.t301.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t301.val = 180; - if (signal_data->timer_t301 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t301.val = signal_data->timer_t301; - } - - /* It looks like ETSI is the only variant that supports Overlap */ - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { - cfg.t.cfg.s.inDLSAP.tmr.t302.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t302.val = 15; - } else { - cfg.t.cfg.s.inDLSAP.tmr.t302.enb = FALSE; - cfg.t.cfg.s.inDLSAP.tmr.t302.val = 0; - } - - if (signal_data->timer_t302 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t302.val = signal_data->timer_t302; - } - - cfg.t.cfg.s.inDLSAP.tmr.t303.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t303.val = 4; - - if (signal_data->timer_t303 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t303.val = signal_data->timer_t303; - } - - cfg.t.cfg.s.inDLSAP.tmr.t304.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t304.val = 30; - - if (signal_data->timer_t304 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t304.val = signal_data->timer_t304; - } - - cfg.t.cfg.s.inDLSAP.tmr.t305.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t305.val = 30; - - if (signal_data->timer_t305 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t305.val = signal_data->timer_t305; - } - - cfg.t.cfg.s.inDLSAP.tmr.t306.enb = FALSE; - cfg.t.cfg.s.inDLSAP.tmr.t306.val = 35; - - if (signal_data->timer_t306 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t306.val = signal_data->timer_t306; - } - - cfg.t.cfg.s.inDLSAP.tmr.t307.enb = FALSE; - cfg.t.cfg.s.inDLSAP.tmr.t307.val = 35; - - if (signal_data->timer_t307 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t307.val = signal_data->timer_t307; - } - - cfg.t.cfg.s.inDLSAP.tmr.t308.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t308.val = 4; - cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t310.val = 120; - - if (signal_data->timer_t308 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t308.val = signal_data->timer_t308; - } - - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - cfg.t.cfg.s.inDLSAP.tmr.t312.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t312.val = cfg.t.cfg.s.inDLSAP.tmr.t303.val+2; - } else { - cfg.t.cfg.s.inDLSAP.tmr.t312.enb = FALSE; - } - - if (signal_data->timer_t310 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t310.val = signal_data->timer_t310; - } - - if (signal_data->timer_t312 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t312.val = signal_data->timer_t312; - } - - cfg.t.cfg.s.inDLSAP.tmr.t313.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t313.val = 4; - - if (signal_data->timer_t313 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t313.val = signal_data->timer_t313; - } - - cfg.t.cfg.s.inDLSAP.tmr.t316.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t316.val = 120; - - if (signal_data->timer_t316 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t316.val = signal_data->timer_t316; - } - - cfg.t.cfg.s.inDLSAP.tmr.t316c.enb = FALSE; - cfg.t.cfg.s.inDLSAP.tmr.t316c.val = 35; - - cfg.t.cfg.s.inDLSAP.tmr.t318.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t318.val = 4; - - if (signal_data->timer_t318 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t318.val = signal_data->timer_t318; - } - - cfg.t.cfg.s.inDLSAP.tmr.t319.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t319.val = 4; - - if (signal_data->timer_t319 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t319.val = signal_data->timer_t319; - } - - cfg.t.cfg.s.inDLSAP.tmr.t322.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t322.val = 4; - - if (signal_data->timer_t322 > 0) { - cfg.t.cfg.s.inDLSAP.tmr.t322.val = signal_data->timer_t322; - } - - cfg.t.cfg.s.inDLSAP.tmr.t332.enb = FALSE; - cfg.t.cfg.s.inDLSAP.tmr.t332.val = 35; - - cfg.t.cfg.s.inDLSAP.tmr.tRst.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.tRst.val = 8; - - cfg.t.cfg.s.inDLSAP.tmr.tAns.enb = FALSE; /* non-standard timer */ - cfg.t.cfg.s.inDLSAP.tmr.t396.enb = FALSE; /* non-standard timer */ - cfg.t.cfg.s.inDLSAP.tmr.t397.enb = TRUE; /* non-standard timer */ - cfg.t.cfg.s.inDLSAP.tmr.tProg.enb= TRUE; - cfg.t.cfg.s.inDLSAP.tmr.tProg.val= 35; -#ifdef NI2 -#ifdef NI2_TREST - cfg.t.cfg.s.inDLSAP.tmr.tRest.enb= FALSE; - cfg.t.cfg.s.inDLSAP.tmr.tRest.val= 35; /* tRest timer for NI2 */ -#endif /* NI2_TREST */ -#endif /* NI2 */ - - cfg.t.cfg.s.inDLSAP.dstEnt = ENTLD; - cfg.t.cfg.s.inDLSAP.dstInst = S_INST; - cfg.t.cfg.s.inDLSAP.dstProcId = SFndProcId(); - cfg.t.cfg.s.inDLSAP.prior = PRIOR0; - cfg.t.cfg.s.inDLSAP.route = RTESPEC; - cfg.t.cfg.s.inDLSAP.selector = 0; - cfg.t.cfg.s.inDLSAP.mem.region = S_REG; - cfg.t.cfg.s.inDLSAP.mem.pool = S_POOL; - - switch (span->trunk_type) { - case FTDM_TRUNK_E1: - cfg.t.cfg.s.inDLSAP.dChannelNum = 16; - cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_E1_CHANNELS_PER_SPAN; - cfg.t.cfg.s.inDLSAP.firstBChanNum = 0; - cfg.t.cfg.s.inDLSAP.callRefLen = 2; - cfg.t.cfg.s.inDLSAP.teiAlloc = IN_STATIC; - cfg.t.cfg.s.inDLSAP.intCfg = IN_INTCFG_PTPT; - break; - case FTDM_TRUNK_T1: - case FTDM_TRUNK_J1: - /* if NFAS, could be 0 if no signalling */ - cfg.t.cfg.s.inDLSAP.callRefLen = 2; - cfg.t.cfg.s.inDLSAP.teiAlloc = IN_STATIC; - cfg.t.cfg.s.inDLSAP.intCfg = IN_INTCFG_PTPT; - cfg.t.cfg.s.inDLSAP.firstBChanNum = 1; - - if (signal_data->nfas.trunk) { - if (signal_data->nfas.sigchan == SNGISDN_NFAS_DCHAN_PRIMARY || - signal_data->nfas.sigchan == SNGISDN_NFAS_DCHAN_BACKUP) { - - cfg.t.cfg.s.inDLSAP.dChannelNum = 24; - cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_T1_CHANNELS_PER_SPAN - 1; - } else { - cfg.t.cfg.s.inDLSAP.dChannelNum = 0; - cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_T1_CHANNELS_PER_SPAN; - } - } else { - cfg.t.cfg.s.inDLSAP.dChannelNum = 24; - cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_T1_CHANNELS_PER_SPAN; - cfg.t.cfg.s.inDLSAP.firstBChanNum = 1; - } - break; - case FTDM_TRUNK_BRI: - cfg.t.cfg.s.inDLSAP.dChannelNum = 0; /* Unused for BRI */ - cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_BRI_CHANNELS_PER_SPAN; - cfg.t.cfg.s.inDLSAP.firstBChanNum = 1; - cfg.t.cfg.s.inDLSAP.callRefLen = 1; - cfg.t.cfg.s.inDLSAP.teiAlloc = IN_STATIC; - cfg.t.cfg.s.inDLSAP.intCfg = IN_INTCFG_PTPT; - break; - case FTDM_TRUNK_BRI_PTMP: - cfg.t.cfg.s.inDLSAP.dChannelNum = 0; /* Unused for BRI */ - cfg.t.cfg.s.inDLSAP.nmbBearChan = NUM_BRI_CHANNELS_PER_SPAN; - cfg.t.cfg.s.inDLSAP.firstBChanNum = 1; - cfg.t.cfg.s.inDLSAP.callRefLen = 1; - cfg.t.cfg.s.inDLSAP.teiAlloc = IN_DYNAMIC; - cfg.t.cfg.s.inDLSAP.intCfg = IN_INTCFG_MULTI; - break; - default: - ftdm_log(FTDM_LOG_ERROR, "%s: Unsupported trunk_type\n", span->name); - return FTDM_FAIL; - } - - if (sng_isdn_q931_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) -{ - InMngmt cfg; - Pst pst; - uint8_t i; - uint8_t numCes=1; - - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP && signal_data->signalling == SNGISDN_SIGNALING_NET) { - numCes = 8; - } - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTIN; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTIN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLC; - - cfg.hdr.response.selector=0; - - cfg.t.cfg.s.inLCe.sapId = signal_data->link_id; - - if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - /* Stack will send Restart CFM's each time link is established (TEI negotiated), - and we do not want thi s event */ - cfg.t.cfg.s.inLCe.lnkUpDwnInd = FALSE; - } else { - cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE; - } - - if (FTDM_SPAN_IS_BRI(span)) { - /* tCon Timer causes unwanted hangup on BRI links - where the Q.921 link goes into disconnected - state when idle. */ - - cfg.t.cfg.s.inLCe.tCon.enb = FALSE; - cfg.t.cfg.s.inLCe.tCon.val = 0; - } else { - cfg.t.cfg.s.inLCe.tCon.enb = TRUE; - cfg.t.cfg.s.inLCe.tCon.val = 35; - } - - cfg.t.cfg.s.inLCe.tDisc.enb = TRUE; - cfg.t.cfg.s.inLCe.tDisc.val = 35; - cfg.t.cfg.s.inLCe.t314.enb = FALSE; /* if segmentation enabled, set to TRUE */ - cfg.t.cfg.s.inLCe.t314.val = 35; - - if (signal_data->nfas.trunk) { - cfg.t.cfg.s.inLCe.t332i.enb = TRUE; - cfg.t.cfg.s.inLCe.t332i.val = 35; - } else { - cfg.t.cfg.s.inLCe.t332i.enb = FALSE; - cfg.t.cfg.s.inLCe.t332i.val = 35; - } - -#if (ISDN_NI1 || ISDN_NT || ISDN_ATT) - cfg.t.cfg.s.inLCe.tSpid.enb = TRUE; - cfg.t.cfg.s.inLCe.tSpid.val = 5; - - /* In case we want to support BRI - NORTH America, we will need to configure 8 spid's per CES */ - cfg.t.cfg.s.inLCe.spid.pres = NOTPRSNT; - cfg.t.cfg.s.inLCe.spid.len = 0; -#endif - cfg.t.cfg.s.inLCe.tRstAck.enb = TRUE; - cfg.t.cfg.s.inLCe.tRstAck.val = 10; - - cfg.t.cfg.s.inLCe.usid = 0; - cfg.t.cfg.s.inLCe.tid = 0; - - for(i=0;isignal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTCC; - - /*clear the configuration structure*/ - memset(&cfg, 0, sizeof(cfg)); - - /*fill in some general sections of the header*/ - stack_hdr_init(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTCC; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STTSAP; - - cfg.t.cfg.s.ccISAP.pst.srcProcId = SFndProcId(); - cfg.t.cfg.s.ccISAP.pst.srcEnt = ENTCC; - cfg.t.cfg.s.ccISAP.pst.srcInst = S_INST; - cfg.t.cfg.s.ccISAP.pst.dstEnt = ENTIN; - cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST; - cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId(); - - cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0; - cfg.t.cfg.s.ccISAP.pst.route = RTESPEC; - cfg.t.cfg.s.ccISAP.pst.region = S_REG; - cfg.t.cfg.s.ccISAP.pst.pool = S_POOL; - cfg.t.cfg.s.ccISAP.pst.selector = 0; - - cfg.t.cfg.s.ccISAP.suId = signal_data->cc_id; - cfg.t.cfg.s.ccISAP.spId = signal_data->cc_id; - - cfg.t.cfg.s.ccISAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); - cfg.t.cfg.s.ccISAP.sapType = SNG_SAP_TYPE_ISDN; - - if (sng_isdn_cc_config(&pst, &cfg)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -/* TODO: see if we can move this to inside the library */ -void stack_pst_init(Pst *pst) -{ - memset(pst, 0, sizeof(Pst)); - /*fill in the post structure*/ - pst->dstProcId = SFndProcId(); - pst->dstInst = S_INST; - - pst->srcProcId = SFndProcId(); - pst->srcEnt = ENTSM; - pst->srcInst = S_INST; - - pst->prior = PRIOR0; - pst->route = RTESPEC; - pst->region = S_REG; - pst->pool = S_POOL; - pst->selector = 0; - return; -} - - - -void stack_hdr_init(Header *hdr) -{ - hdr->msgType = 0; - hdr->msgLen = 0; - hdr->entId.ent = 0; - hdr->entId.inst = 0; - hdr->elmId.elmnt = 0; - hdr->elmId.elmntInst1 = 0; - hdr->elmId.elmntInst2 = 0; - hdr->elmId.elmntInst3 = 0; - hdr->seqNmb = 0; - hdr->version = 0; - hdr->response.prior = PRIOR0; - hdr->response.route = RTESPEC; - hdr->response.mem.region = S_REG; - hdr->response.mem.pool = S_POOL; - hdr->transId = 0; - hdr->response.selector = 0; - return; -} - -uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype) -{ - switch (switchtype) { - case SNGISDN_SWITCH_NI2: - return SW_NI2; - case SNGISDN_SWITCH_5ESS: - return SW_ATT5EP; - case SNGISDN_SWITCH_4ESS: - return SW_ATT4E; - case SNGISDN_SWITCH_DMS100: - return SW_NTDMS100P; - case SNGISDN_SWITCH_EUROISDN: - return SW_ETSI; - case SNGISDN_SWITCH_QSIG: - return SW_QSIG; - case SNGISDN_SWITCH_INSNET: - return SW_INSNET; - case SNGISDN_SWITCH_INVALID: - ftdm_log(FTDM_LOG_ERROR, "Invalid switchtype: %d\n", switchtype); - break; - } - return 0; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c deleted file mode 100644 index 6a944e28bb..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" - -void stack_resp_hdr_init(Header *hdr); - -ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span); -ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span); - -ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span); - -ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction); -ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction); - - -extern ftdm_sngisdn_data_t g_sngisdn_data; - -ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span); - - -ftdm_status_t sngisdn_stack_start(ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - if (signal_data->dchan) { - if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name); - } - - /* Try to find an alternative for this */ - /* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1, - so we need to give some time before activating q931, as q931 will send a - LdUiDatConReq when activated, and this requires the Mac SAP to be already - bound first */ - ftdm_sleep(500); - - if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) { - g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1; - if (sngisdn_activate_cc(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack CC\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:Stack CC activated\n", span->name); - } - - if (sngisdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name); - return FTDM_FAIL; - } - ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q931 activated\n", span->name); - - ftdm_log(FTDM_LOG_INFO, "%s:Stack activated\n",span->name); - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - /* Stop L1 first, so we do not receive any more frames */ - if (!signal_data->dchan) { - return FTDM_SUCCESS; - } - if (sngisdn_deactivate_phy(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name); - return FTDM_FAIL; - } - - if (sngisdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name); - return FTDM_FAIL; - } - - if (sngisdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name); - return FTDM_FAIL; - } - - ftdm_log(FTDM_LOG_INFO, "%s:Signalling stopped\n", span->name); - return FTDM_SUCCESS; -} - - -ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span) -{ - - /* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */ - - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span) -{ - L1Mngmt cntrl; - Pst pst; - - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTL1; - - /* initalize the control structure */ - memset(&cntrl, 0, sizeof(cntrl)); - - /* initalize the control header */ - stack_hdr_init(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* configuration */ - cntrl.hdr.entId.ent = ENTL1; /* entity */ - cntrl.hdr.entId.inst = S_INST; /* instance */ - cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */ - - cntrl.t.cntrl.action = AUBND_DIS; - cntrl.t.cntrl.subAction = SAELMNT; - - cntrl.t.cntrl.sapId = signal_data->link_id; - - if (sng_isdn_phy_cntrl(&pst, &cntrl)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span) -{ - L1Mngmt cntrl; - Pst pst; - - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTL1; - - /* initalize the control structure */ - memset(&cntrl, 0, sizeof(cntrl)); - - /* initalize the control header */ - stack_hdr_init(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* configuration */ - cntrl.hdr.entId.ent = ENTL1; /* entity */ - cntrl.hdr.entId.inst = S_INST; /* instance */ - cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */ - - cntrl.t.cntrl.action = AENA; - cntrl.t.cntrl.subAction = SAELMNT; - - cntrl.t.cntrl.sapId = signal_data->link_id; - - if (sng_isdn_phy_cntrl(&pst, &cntrl)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span) -{ - CcMngmt cntrl; - Pst pst; - - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTCC; - - /* initalize the control structure */ - memset(&cntrl, 0, sizeof(cntrl)); - - /* initalize the control header */ - stack_hdr_init(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* configuration */ - cntrl.hdr.entId.ent = ENTCC; /* entity */ - cntrl.hdr.entId.inst = S_INST; /* instance */ - cntrl.hdr.elmId.elmnt = STTSAP; /* physical sap */ - - cntrl.t.cntrl.action = ABND_ENA; - cntrl.t.cntrl.subAction = SAELMNT; - - cntrl.t.cntrl.sapId = signal_data->cc_id; - if (sng_isdn_cc_cntrl(&pst, &cntrl)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt) -{ - sngisdn_span_data_t *signal_data = sngisdn_dchan((sngisdn_span_data_t*)span->signal_data); - - if (!signal_data) { - ftdm_log(FTDM_LOG_ERROR, "%s:Span is not used by signalling module\n", span->name); - return FTDM_FAIL; - } - - switch (trace_opt) { - case SNGISDN_TRACE_DISABLE: - if (sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q921)) { - ftdm_log(FTDM_LOG_INFO, "%s:Disabling q921 trace\n", signal_data->ftdm_span->name); - sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921); - - if (sngisdn_cntrl_q921(signal_data->ftdm_span, ADISIMM, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_INFO, "%s:Failed to disable q921 trace\n", signal_data->ftdm_span->name); - } - } - if (sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q931)) { - ftdm_log(FTDM_LOG_INFO, "%s:Disabling q921 trace\n", signal_data->ftdm_span->name); - sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q931); - - if (sngisdn_cntrl_q931(signal_data->ftdm_span, ADISIMM, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_INFO, "%s:Failed to disable q921 trace\n", signal_data->ftdm_span->name); - } - } - break; - case SNGISDN_TRACE_Q921: - if (!sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q921)) { - ftdm_log(FTDM_LOG_INFO, "%s:Enabling q921 trace\n", signal_data->ftdm_span->name); - sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q921); - - if (sngisdn_cntrl_q921(signal_data->ftdm_span, AENA, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_INFO, "%s:Failed to enable q921 trace\n", signal_data->ftdm_span->name); - } - } - break; - case SNGISDN_TRACE_Q931: - if (!sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q931)) { - ftdm_log(FTDM_LOG_INFO, "s%d Enabling q931 trace\n", signal_data->link_id); - sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q931); - - if (sngisdn_cntrl_q931(signal_data->ftdm_span, AENA, SATRC) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_INFO, "%s:Failed to enable q931 trace\n", signal_data->ftdm_span->name); - } - } - break; - } - return FTDM_SUCCESS; -} - - -ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction) -{ - InMngmt cntrl; - Pst pst; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTIN; - - /* initalize the control structure */ - memset(&cntrl, 0, sizeof(cntrl)); - - /* initalize the control header */ - stack_hdr_init(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* configuration */ - cntrl.hdr.entId.ent = ENTIN; /* entity */ - cntrl.hdr.entId.inst = S_INST; /* instance */ - cntrl.hdr.elmId.elmnt = STDLSAP; /* physical sap */ - - cntrl.t.cntrl.action = action; - cntrl.t.cntrl.subAction = subaction; - - if (action == AENA && subaction == SATRC) { - cntrl.t.cntrl.trcLen = -1; /* Trace the entire message buffer */ - } - - cntrl.t.cntrl.sapId = signal_data->link_id; - cntrl.t.cntrl.ces = 0; - - if(sng_isdn_q931_cntrl(&pst, &cntrl)) { - return FTDM_FAIL; - } - return FTDM_SUCCESS; - -} - -ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction) -{ - BdMngmt cntrl; - Pst pst; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - - /* initalize the post structure */ - stack_pst_init(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTLD; - - /* initalize the control structure */ - memset(&cntrl, 0, sizeof(cntrl)); - - /* initalize the control header */ - stack_hdr_init(&cntrl.hdr); - /* build control request */ - cntrl.hdr.msgType = TCNTRL; - cntrl.hdr.entId.ent = ENTLD; - cntrl.hdr.entId.inst = S_INST; - -#if (SMBD_LMINT3 || BD_LMINT3) - stack_resp_hdr_init(&cntrl.hdr); -#endif /* _LMINT3 */ - - cntrl.hdr.elmId.elmnt = STMSAP; - cntrl.t.cntrl.action = action; - cntrl.t.cntrl.subAction = subaction; - -#if (SMBD_LMINT3 || BD_LMINT3) - cntrl.t.cntrl.lnkNmb = signal_data->link_id; - cntrl.t.cntrl.sapi = NOTUSED; - cntrl.t.cntrl.tei = NOTUSED; -#else /* _LMINT3 */ - cntrl.hdr.elmId.elmntInst1 = signal_data->link_id; - cntrl.hdr.elmId.elmntInst2 = NOTUSED; - cntrl.hdr.elmId.elmntInst3 = NOTUSED; -#endif /* _LMINT3 */ - - cntrl.t.cntrl.logInt = NOTUSED; - cntrl.t.cntrl.trcLen = NOTUSED; - if (action == AENA && subaction == SATRC) { - cntrl.t.cntrl.trcLen = -1; /* Trace the entire message buffer */ - } - - SGetDateTime(&(cntrl.t.cntrl.dt)); - if(sng_isdn_q921_cntrl(&pst, &cntrl)) { - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - - -void stack_resp_hdr_init(Header *hdr) -{ - hdr->response.selector = 0; - hdr->response.mem.region = RTESPEC; - hdr->response.mem.pool = S_POOL; - hdr->response.prior = PRIOR0; - hdr->response.route = RTESPEC; - - return; -} - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c deleted file mode 100644 index 688c083adb..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" -static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn); -static ftdm_status_t sngisdn_bring_down(ftdm_channel_t *ftdmchan); - -/* Remote side transmit a SETUP */ -void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) -{ - unsigned i; - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - int16_t dChan = sngisdn_event->dChan; - uint8_t ces = sngisdn_event->ces; - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - ConEvnt *conEvnt = &sngisdn_event->event.conEvnt; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_DOWN: /* Proper state to receive a SETUP */ - if (signal_data->nfas.trunk) { - ftdm_alarm_flag_t alarmflag = 0; - - ftdm_channel_get_alarms(ftdmchan, &alarmflag); - if (alarmflag) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received SETUP but channel has physical layer alarm - rejecting\n"); - - ftdmchan->caller_data.hangup_cause = 0x2C; /* Channel requested not available */ - ftdm_sched_timer(signal_data->sched, "delayed_release", 1, sngisdn_delayed_release, (void*) sngisdn_info, NULL); - break; - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) || - ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received SETUP but channel is in USE, saving call for later processing\n"); - /* the flag the channel as having a collision */ - sngisdn_set_flag(sngisdn_info, FLAG_GLARE); - - /* save the SETUP for processing once the channel has gone to DOWN */ - memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt)); - sngisdn_info->glare.suId = suId; - sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */ - sngisdn_info->glare.spInstId = spInstId; - sngisdn_info->glare.dChan = dChan; - sngisdn_info->glare.ces = ces; - break; - } - - sngisdn_info->suInstId = get_unique_suInstId(suId); - sngisdn_info->spInstId = spInstId; - - if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) { - uint8_t local_number_matched = 0; - for (i = 0 ; i < signal_data->num_local_numbers ; i++) { - if (!strcmp(signal_data->local_numbers[i], (char*)conEvnt->cdPtyNmb.nmbDigits.val)) { - local_number_matched++; - break; - } - } - if (!local_number_matched) { - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP, but local-number %s does not match - ignoring\n", conEvnt->cdPtyNmb.nmbDigits.val); - /* Special case to tell the stack to clear all internal resources about this call. We will no receive any event for this call after sending disconnect request */ - ftdmchan->caller_data.hangup_cause = IN_CCNORTTODEST; - ftdm_sched_timer(signal_data->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL); - return; - } - } - - /* If this is a glared call that was previously saved, we moved - all the info to the current call, so clear the glared saved data */ - if (sngisdn_info->glare.spInstId == spInstId) { - clear_call_glare_data(sngisdn_info); - } - - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - sngisdn_info->ces = ces; - } - } - - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); - - /* try to open the channel */ - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to open channel"); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_REL); - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - break; - } - - /* Fill in call information */ -#ifdef NETBORDER_CALL_REF - get_callref(ftdmchan, &conEvnt->callRef); -#endif - get_calling_num(ftdmchan, &conEvnt->cgPtyNmb); - get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2); - get_called_num(ftdmchan, &conEvnt->cdPtyNmb); - get_redir_num(ftdmchan, &conEvnt->redirNmb); - get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad); - get_prog_ind_ie(ftdmchan, &conEvnt->progInd); - get_facility_ie(ftdmchan, &conEvnt->facilityStr); - get_calling_name(ftdmchan, conEvnt); - get_network_specific_fac(ftdmchan, &conEvnt->netFac[0]); - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits); - - if (conEvnt->bearCap[0].eh.pres) { - ftdmchan->caller_data.bearer_layer1 = sngisdn_get_usrInfoLyr1Prot_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val); - ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val); - } - - if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) { - if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) { - uint8_t encoding = (conEvnt->ni2OctStr.str.val[2] >> 5); - if (encoding == 0 || encoding == 1) { - /* BCD even or BCD odd */ - uint8_t value = (conEvnt->ni2OctStr.str.val[3] & 0x0F)*10 + ((conEvnt->ni2OctStr.str.val[3] >> 4) & 0x0F); - snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", value); - } else if (encoding == 2) { - /* IA 5 */ - snprintf(ftdmchan->caller_data.aniII, 5, "%c", conEvnt->ni2OctStr.str.val[3]); - } - } - } - -#if 1 - /* this section will not be needed once asn decoding function with key-value pairs is implemented */ - if (signal_data->facility == SNGISDN_OPT_TRUE && - signal_data->facility_ie_decode != SNGISDN_OPT_FALSE && - conEvnt->facilityStr.eh.pres) { - - /* Verify whether the Caller Name will come in a subsequent FACILITY message */ - uint16_t ret_val; - char retrieved_str[255]; - - ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); - /* - return values for "sng_isdn_retrieve_facility_information_following": - If there will be no information following, or fails to decode IE, returns -1 - If there will be no information following, but current FACILITY IE contains a caller name, returns 0 - If there will be information following, returns 1 - */ - - if (ret_val == 1) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID); - /* Launch timer in case we never get a FACILITY msg */ - if (signal_data->facility_timeout) { - ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, - sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_CHAN_TIMER_FACILITY]); - } - break; - } else if (ret_val == 0) { - strcpy(ftdmchan->caller_data.cid_name, retrieved_str); - } - } -#endif - if (signal_data->overlap_dial == SNGISDN_OPT_TRUE) { - ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits; - ftdm_size_t num_digits; - - num_digits = strlen(ftdmchan->caller_data.dnis.digits); - - if (conEvnt->sndCmplt.eh.pres || num_digits >= min_digits) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } else { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - } - } else { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - break; - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in %s state, saving SETUP info for later processing\n", ftdm_channel_state2str(ftdmchan->state)); - ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare\n"); - - sngisdn_set_flag(sngisdn_info, FLAG_GLARE); - - /* save the SETUP for processing once the channel has gone to DOWN */ - memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt)); - sngisdn_info->glare.suId = suId; - sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */ - sngisdn_info->glare.spInstId = spInstId; - sngisdn_info->glare.dChan = dChan; - sngisdn_info->glare.ces = ces; - - break; - case FTDM_CHANNEL_STATE_DIALING: /* glare */ - if (signal_data->signalling == SNGISDN_SIGNALING_NET) { - /* Save inbound call info so we can send a RELEASE when this channel goes to a different state */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP in DIALING state, rejecting inbound call\n"); - sngisdn_set_flag(sngisdn_info, FLAG_DELAYED_REL); - - sngisdn_info->glare.suId = suId; - sngisdn_info->glare.suInstId = get_unique_suInstId(suId); - sngisdn_info->glare.spInstId = spInstId; - - sngisdn_info->glare.dChan = dChan; - sngisdn_info->glare.ces = ces; - ftdmchan->caller_data.hangup_cause = 0x2C; /* Channel requested not available */ - ftdm_sched_timer(signal_data->sched, "delayed_release", 1, sngisdn_delayed_release, (void*) sngisdn_info, NULL); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in DIALING state, saving SETUP info for later processing\n"); - - /* the flag the channel as having a collision */ - ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare"); - sngisdn_set_flag(sngisdn_info, FLAG_GLARE); - - /* save the SETUP for processing once the channel has gone to DOWN */ - memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt)); - sngisdn_info->glare.suId = suId; - sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */ - sngisdn_info->glare.spInstId = spInstId; - sngisdn_info->glare.dChan = dChan; - sngisdn_info->glare.ces = ces; - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); - break; - } - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -/* Remote side transmit a CONNECT or CONNECT ACK */ -void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - uint8_t ces = sngisdn_event->ces; - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces); - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP && - ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->signalling == SNGISDN_SIGNALING_NET) { - - if(sngisdn_info->ces == CES_MNGMNT) { - /* We assign the call to the first TE */ - sngisdn_info->ces = ces; - } else { - /* We already assigned this call, do nothing */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call already assigned, ignoring connect\n"); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_DIALING: -#ifdef NETBORDER_CALL_REF - get_callref(ftdmchan, &cnStEvnt->callRef); -#endif - get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd); - get_facility_ie(ftdmchan, &cnStEvnt->facilityStr); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - case FTDM_CHANNEL_STATE_HANGUP: - /* Race condition, we just hung up the call - ignore this message */ - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); - - /* Start the disconnect procedure */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - } - } else { - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_TRANSFER: - case FTDM_CHANNEL_STATE_UP: - /* These are the only valid states we should get a CONNECT ACK on */ - /* do nothing */ - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */ - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); - - /* Start the disconnect procedure */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - } - } - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - uint8_t ces = sngisdn_event->ces; - uint8_t evntType = sngisdn_event->evntType; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n", - (evntType == MI_ALERTING)?"ALERT": - (evntType == MI_CALLPROC)?"PROCEED": - (evntType == MI_PROGRESS)?"PROGRESS": - (evntType == MI_SETUPACK)?"SETUP ACK": - (evntType == MI_NOTIFY)?"NOTIFY": - (evntType == MI_INFO)?"INFO":"UNKNOWN", - suId, suInstId, spInstId, ces); - - switch(evntType) { - case MI_CALLPROC: - case MI_PROGRESS: - case MI_ALERTING: -#ifdef NETBORDER_CALL_REF - get_callref(ftdmchan, &cnStEvnt->callRef); -#endif - get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd); - get_facility_ie(ftdmchan, &cnStEvnt->facilityStr); - - if (sngisdn_cause_val_requires_disconnect(ftdmchan, &cnStEvnt->causeDgn[0]) == FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val); - ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val; - - sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - goto sngisdn_process_cnst_ind_end; - } - - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_DIALING: - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_RINGING: - if ((cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) || - (cnStEvnt->progInd1.eh.pres && cnStEvnt->progInd1.progDesc.val == IN_PD_IBAVAIL) || - (cnStEvnt->progInd2.eh.pres && cnStEvnt->progInd2.progDesc.val == IN_PD_IBAVAIL) || - (cnStEvnt->progInd3.eh.pres && cnStEvnt->progInd3.progDesc.val == IN_PD_IBAVAIL)) { - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n"); - sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media not available\n"); - } - switch (evntType) { - case MI_CALLPROC: - if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && - (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROCEED)) { - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on proceed\n"); - sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); - } - if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED); - } - break; - case MI_ALERTING: - if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && - (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_ALERT)) { - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on alert\n"); - sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); - } - if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING); - } - break; - case MI_PROGRESS: - if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && - (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROGRESS)) { - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on progress\n"); - sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); - } - if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } - break; - default: - /* We should never reach this section !*/ - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType); - } - break; - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - /* We are already in progress media, we can't go to any higher state except up */ - /* Do nothing */ - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring ALERT/PROCEED/PROGRESS because channel is in RESET state\n"); - break; - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* Ignore this message as we already started the hangup process */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring ALERT/PROCEED/PROGRESS because we are already hanging up\n"); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); - - /* Start the disconnect procedure */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - } - break; - case MI_SETUPACK: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP_ACK, but overlap sending not implemented (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - break; - case MI_INFO: - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing INFO (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - if (cnStEvnt->cdPtyNmb.eh.pres) { - switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_COLLECT: - { - ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits; - ftdm_size_t num_digits; - - get_called_num(ftdmchan, &cnStEvnt->cdPtyNmb); - num_digits = strlen(ftdmchan->caller_data.dnis.digits); - - if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "received %"FTDM_SIZE_FMT" of %"FTDM_SIZE_FMT" digits\n", num_digits, min_digits); - } - } - break; - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_UP: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val); - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled INFO (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - break; - } - } - break; - case MI_NOTIFY: - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing NOTIFY (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - /* Do nothing */ - break; - default: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unhandled STATUS event\n"); - break; - } - -sngisdn_process_cnst_ind_end: - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_DIALING: - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_UP: - get_facility_ie(ftdmchan, &discEvnt->facilityStr); - - if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) { - ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "DISCONNECT did not have a cause code\n"); - ftdmchan->caller_data.hangup_cause = 0; - } - sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_REL); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - case FTDM_CHANNEL_STATE_COLLECT: - case FTDM_CHANNEL_STATE_GET_CALLERID: - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - break; - case FTDM_CHANNEL_STATE_DOWN: - /* somehow we are in down, nothing we can do locally */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT but we are in DOWN state\n"); - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* This is a race condition. We just sent a DISCONNECT, on this channel */ - /* Do nothing */ - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n", - ftdm_channel_state2str(ftdmchan->state)); - /* start reset procedure */ - - /* Start the release procedure */ - ftdm_set_flag(sngisdn_info, FLAG_REMOTE_REL); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - } - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - RelEvnt *relEvnt = &sngisdn_event->event.relEvnt; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); - - if ((suInstId && (sngisdn_info->glare.suInstId == suInstId)) || - (spInstId && (sngisdn_info->glare.spInstId == spInstId))) { - - /* This hangup is for a glared saved call */ - ftdm_clear_flag(sngisdn_info, FLAG_DELAYED_REL); - clear_call_glare_data(sngisdn_info); - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* go to DOWN */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - case FTDM_CHANNEL_STATE_DOWN: - /* do nothing, just drop the message */ - break; - case FTDM_CHANNEL_STATE_DIALING: - /* Remote side rejected our SETUP message on outbound call */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); - } - /* fall-through */ - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_UP: - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_RINGING: - /* If we previously had a glare on this channel, - this RELEASE could be for the previous call. Confirm whether call_data has - not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */ - if (((sngisdn_chan_data_t*)ftdmchan->call_data)->suInstId == suInstId || - ((sngisdn_chan_data_t*)ftdmchan->call_data)->spInstId == spInstId) { - - get_facility_ie(ftdmchan, &relEvnt->facilityStr); - - if (relEvnt->causeDgn[0].eh.pres && relEvnt->causeDgn[0].causeVal.pres) { - ftdmchan->caller_data.hangup_cause = relEvnt->causeDgn[0].causeVal.val; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "RELEASE COMPLETE did not have a cause code\n"); - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL; - } - - sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "RELEASE was for previous call (suInstId:%u spInstId:%u)\n", suInstId, spInstId); - } - break; - case FTDM_CHANNEL_STATE_COLLECT: - case FTDM_CHANNEL_STATE_GET_CALLERID: - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - break; - case FTDM_CHANNEL_STATE_TERMINATING: - if (sngisdn_test_flag(sngisdn_info, FLAG_GLARE) && - sngisdn_info->glare.suInstId != suInstId) { - /* This release if for the outbound call that we already started clearing */ - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Received RELEASE for local glared call\n"); - sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received release before we could clear local call\n"); - /* FS core took too long to respond to the SIG STOP event */ - sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); - /* set abort flag so that we do not transmit another release complete on this channel once FS core is done */ - } - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing RELEASE but channel in RESET state, ignoring\n"); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n", - ftdm_channel_state2str(ftdmchan->state)); - break; - } - - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from infoEvnt struct for now */ - /* InfoEvnt *infoEvnt = &sngisdn_event->event.infoEvnt; */ - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DATA IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */ - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */ - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */ - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */ - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /* StaEvnt *staEvnt = &sngisdn_event->event.staEvnt; */ - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - FacEvnt *facEvnt = &sngisdn_event->event.facEvnt; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - /* If Facility decoding is disabled, we do not care about current call state, just pass event up to user */ - if (facEvnt->facElmt.facStr.pres) { - get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2); - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_FACILITY); - } - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_GET_CALLERID: - /* Update the caller ID Name */ - - if (facEvnt->facElmt.facStr.pres) { - char retrieved_str[255]; - - /* return values for "sng_isdn_retrieve_facility_information_following": - If there will be no information following, or fails to decode IE, returns -1 - If there will be no information following, but current FACILITY IE contains a caller name, returns 0 - If there will be information following, returns 1 - */ - - if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) { - strcpy(ftdmchan->caller_data.cid_name, retrieved_str); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Failed to retrieve Caller Name from Facility IE\n"); - } - if (signal_data->facility_timeout) { - /* Cancel facility timeout */ - ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_CHAN_TIMER_FACILITY]); - } - } - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - break; - case FTDM_CHANNEL_STATE_RING: - /* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n"); - break; - case FTDM_CHANNEL_STATE_UP: - { - ftdm_sigmsg_t sigev; - if (facEvnt->facElmt.facStr.pres) { - get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2); - } - memset(&sigev, 0, sizeof(sigev)); - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - - sigev.event_id = FTDM_SIGEVENT_FACILITY; - ftdm_span_send_signal(ftdmchan->span, &sigev); - } - break; - default: - /* We do not support other FACILITY types for now, so do nothing */ - break; - } - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - uint32_t suInstId = sngisdn_event->suInstId; - uint32_t spInstId = sngisdn_event->spInstId; - sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - StaEvnt *staEvnt = &sngisdn_event->event.staEvnt; - - uint8_t call_state = 0; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!suInstId && !spInstId) { - /* We already cleared this call */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dropping STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - return; - } - - if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) { - call_state = staEvnt->callSte.callGlblSte.val; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); - - if (staEvnt->causeDgn[0].eh.pres && staEvnt->causeDgn[0].causeVal.pres) { - if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) { - call_state = staEvnt->callSte.callGlblSte.val; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received STATUS without call state\n"); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - switch (staEvnt->causeDgn[0].causeVal.val) { - case FTDM_CAUSE_RESPONSE_TO_STATUS_ENQUIRY: - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Status Check OK:%d", call_state); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - case FTDM_CAUSE_WRONG_CALL_STATE: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Message incompatible with call state (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId); - break; - case FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Recovery on timer expire (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "STATUS CONFIRM (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId); - break; - } - - /* Section 4.3.30 from INT Interface - Service Definition */ - ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val; - - switch(call_state) { - /* Sere ITU-T Q931 for definition of call states */ - case 0: /* Remote switch thinks there are no calls on this channel */ - if (sngisdn_bring_down(ftdmchan) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - } - break; - case 1: - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_UP: - /* Remote side is still waiting for our CONNECT message */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL); - break; - } - /* Fall-through */ - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; - case 2: /* overlap sending */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_COLLECT: - /* T302 Timeout reached */ - /* Send the call to user, and see if they accept it */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - break; - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n"); - sngisdn_snd_disconnect(ftdmchan); - break; - case FTDM_CHANNEL_STATE_DOWN: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* We hung up locally, but remote switch doesn't know send disconnect again*/ - sngisdn_snd_disconnect(ftdmchan); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; - case 3: - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_RINGING: - /* T310 timer has expired */ - ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val; - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n"); - sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - break; - case FTDM_CHANNEL_STATE_UP: - /* Remote side is still waiting for our CONNECT message */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL); - break; - } - /* Fall-through */ - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; - case 8: /* Remote switch is in "Connect Request state" */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_UP: - /* This is ok. We sent a Connect, and we are waiting for a connect ack */ - /* Do nothing */ - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* We hung up locally, but remote switch doesn't know send disconnect again*/ - sngisdn_snd_disconnect(ftdmchan); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; - case 9: /* Remote switch is in "Incoming call proceeding" state */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_GET_CALLERID: - /* Do nothing */ - break; - case FTDM_CHANNEL_STATE_UP: - /* Remote switch missed our CONNECT message, re-send */ - ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; - case 10: /* Remote switch is in active state */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_UP: - /* This is ok, they are in active state and we are in active state */ - /* Do nothing */ - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* We sent a disconnect message, but remote side missed it ? */ - ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; - case 12: /* We received a disconnect indication */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_TERMINATING: - /* We are already waiting for user app to handle the disconnect, do nothing */ - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; - case 22: - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_UP: - /* Stack is in the process of clearing the call*/ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* Do nothing as we will get a RELEASE COMPLETE */ - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - } - break; - case 25: /* Overlap receiving */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_COLLECT: - /* T302 Timeout reached */ - /* Send the call to user, and see if they accept it */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - } - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - } - } - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - - -void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - int16_t dChan = sngisdn_event->dChan; - uint8_t ces = sngisdn_event->ces; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/ - - ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE IND (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event) -{ - int16_t suId = sngisdn_event->suId; - int16_t dChan = sngisdn_event->dChan; - uint8_t ces = sngisdn_event->ces; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/ - - ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE CFM (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -static ftdm_status_t sngisdn_bring_down(ftdm_channel_t *ftdmchan) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; - ftdm_status_t status = FTDM_SUCCESS; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Bringing channel to DOWN state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_DOWN: - /* Do nothing */ - break; - case FTDM_CHANNEL_STATE_RESET: - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - case FTDM_CHANNEL_STATE_COLLECT: - case FTDM_CHANNEL_STATE_DIALING: - case FTDM_CHANNEL_STATE_UP: - sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - case FTDM_CHANNEL_STATE_TERMINATING: - /* We are already waiting for usr to respond to SIGEVENT stop. - FreeTDM already scheduled a timout in case the User does respond to - SIGEVENT_STOP, no need to do anything here */ - break; - case FTDM_CHANNEL_STATE_HANGUP: - /* This cannot happen, state_advance always sets - ftdmchan to STATE_HANGUP_COMPLETE when in STATE_HANGUP - and we called check_for_state_change earlier so something is very wrong here!!! */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "How can we we in FTDM_CHANNEL_STATE_HANGUP after checking for state change?\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* We were waiting for remote switch to send RELEASE COMPLETE - but this will not happen, so just clear local state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - default: - status = FTDM_FAIL; - - } - return status; -} - -void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) -{ - ftdm_signaling_status_t sigstatus; - int16_t suId = sngisdn_event->suId; - int16_t dChan = sngisdn_event->dChan; - uint8_t ces = sngisdn_event->ces; - uint8_t evntType = sngisdn_event->evntType; - uint8_t chan_no = 0; - Rst *rstEvnt = &sngisdn_event->event.rstEvnt; - - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[dChan]; - if (!signal_data) { - ftdm_log(FTDM_LOG_CRIT, "Received RESTART CFM on unconfigured span (suId:%d)\n", suId); - return; - } - - ftdm_log(FTDM_LOG_DEBUG, "%s: Processing RESTART CFM (suId:%u dChan:%d ces:%d %s(%d))\n", - signal_data->ftdm_span->name, - suId, dChan, ces, - (evntType == IN_LNK_DWN)?"LNK_DOWN": - (evntType == IN_LNK_UP)?"LNK_UP": - (evntType == IN_INDCHAN)?"b-channel": - (evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures": - (evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown", evntType); - - if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) { - switch(rstEvnt->rstInd.rstClass.val) { - case IN_CL_INDCHAN: /* Indicated b-channel */ - if (rstEvnt->chanId.eh.pres) { - if (rstEvnt->chanId.intType.val == IN_IT_BASIC) { - if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) { - chan_no = rstEvnt->chanId.infoChanSel.val; - } - } else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) { - if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) { - chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0]; - } - } - - if (signal_data->nfas.trunk) { - if (!rstEvnt->chanId.intIdent.pres) { - ftdm_log(FTDM_LOG_CRIT, "Failed to determine interface from RESTART\n"); - return; - } else if (signal_data->nfas.interface_id != rstEvnt->chanId.intIdent.val) { - /* This RESTART is for another interface */ - return; - } - } - } - if (!chan_no) { - ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n"); - return; - } - break; - case IN_CL_SNGINT: /* Single interface */ - case IN_CL_ALLINT: /* All interfaces */ - /* In case restart class indicates all interfaces, we will duplicate - this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm, - so treat it as a single interface anyway */ - chan_no = 0; - break; - default: - ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val); - return; - } - } - - ftdm_span_get_sig_status(signal_data->ftdm_span, &sigstatus); - if (sigstatus == FTDM_SIG_STATE_DOWN) { - if (chan_no) { /* For a single channel */ - if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) { - ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no); - } else { - ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no); - sngisdn_bring_down(ftdmchan); - } - } else { /* for all channels */ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - sngisdn_bring_down((ftdm_channel_t*)ftdm_iterator_current(curr)); - } - ftdm_iterator_free(chaniter); - } - } - - ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - - -/* The remote side sent us a RESTART Msg. Trillium automatically acks with RESTART ACK, but - we need to clear our call states if there is a call on this channel */ -void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event) -{ - uint8_t chan_no = 0; - int16_t suId = sngisdn_event->suId; - int16_t dChan = sngisdn_event->dChan; - uint8_t ces = sngisdn_event->ces; - uint8_t evntType = sngisdn_event->evntType; - Rst *rstEvnt = NULL; - sngisdn_span_data_t *signal_data = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - rstEvnt = &sngisdn_event->event.rstEvnt; - - signal_data = g_sngisdn_data.spans[dChan]; - - if (!signal_data) { - ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on unconfigured span (suId:%d)\n", suId); - return; - } - - if (signal_data->restart_timeout) { - ftdm_sched_cancel_timer(signal_data->sched, signal_data->timers[SNGISDN_SPAN_TIMER_RESTART]); - } - - ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART IND (suId:%u dChan:%d ces:%d %s(%d))\n", suId, dChan, ces, - (evntType == IN_LNK_DWN)?"LNK_DOWN": - (evntType == IN_LNK_UP)?"LNK_UP": - (evntType == IN_INDCHAN)?"b-channel": - (evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures": - (evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown", evntType); - - if (rstEvnt->rstInd.eh.pres == PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres == PRSNT_NODEF) { - switch(rstEvnt->rstInd.rstClass.val) { - case IN_CL_INDCHAN: /* Indicated b-channel */ - if (rstEvnt->chanId.eh.pres) { - if (rstEvnt->chanId.intType.val == IN_IT_BASIC) { - if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) { - chan_no = rstEvnt->chanId.infoChanSel.val; - } - } else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) { - if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) { - chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0]; - } - } - - if (signal_data->nfas.trunk) { - if (!rstEvnt->chanId.intIdent.pres) { - ftdm_log(FTDM_LOG_CRIT, "Failed to determine interface from RESTART\n"); - return; - } else if (signal_data->nfas.interface_id != rstEvnt->chanId.intIdent.val) { - /* This RESTART is for another interface */ - return; - } - } - } - if (!chan_no) { - ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n"); - return; - } - break; - case IN_CL_SNGINT: /* Single interface */ - case IN_CL_ALLINT: /* All interfaces */ - /* In case restart class indicates all interfaces, we will duplicated - this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm, - so treat it as a single interface anyway */ - chan_no = 0; - break; - default: - ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val); - return; - } - } - - if (chan_no) { /* For a single channel */ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - if (sngisdn_info->ces == ces && ftdmchan->physical_chan_id == chan_no) { - sngisdn_bring_down(ftdmchan); - } - } - ftdm_iterator_free(chaniter); - } else { /* for all channels */ - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - if (sngisdn_info->ces == ces) { - sngisdn_bring_down(ftdmchan); - } - } - ftdm_iterator_free(chaniter); - } - - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (signal_data->ignore_cause_value == SNGISDN_OPT_TRUE) { - return FTDM_FAIL; - } - - /* By default, we only evaluate cause value on 5ESS switches */ - if (signal_data->ignore_cause_value == SNGISDN_OPT_DEFAULT && - signal_data->switchtype != SNGISDN_SWITCH_5ESS) { - - return FTDM_FAIL; - } - - /* ignore_cause_value = SNGISDN_OPT_FALSE or switchtype == 5ESS */ - switch(causeDgn->causeVal.val) { - case 17: /* User Busy */ - case 18: /* No User responding */ - case 19: /* User alerting, no answer */ - case 21: /* Call rejected, the called party does not with to accept this call */ - case 27: /* Destination out of order */ - case 31: /* Normal, unspecified */ - case 34: /* Circuit/Channel congestion */ - case 41: /* Temporary failure */ - case 42: /* Switching equipment is experiencing a period of high traffic */ - case 47: /* Resource unavailable */ - case 58: /* Bearer Capability not available */ - case 63: /* Service or option not available */ - case 65: /* Bearer Cap not implemented, not supported */ - case 79: /* Service or option not implemented, unspecified */ - return FTDM_SUCCESS; - } - return FTDM_FAIL; -} diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c deleted file mode 100644 index 9fc8ad1d82..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" - -void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) -{ - ConEvnt conEvnt; - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; - - ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n"); - - sngisdn_info->suInstId = get_unique_suInstId(signal_data->cc_id); - sngisdn_info->spInstId = 0; - - ftdm_mutex_lock(g_sngisdn_data.ccs[signal_data->cc_id].mutex); - g_sngisdn_data.ccs[signal_data->cc_id].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex); - - memset(&conEvnt, 0, sizeof(conEvnt)); - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || signal_data->force_sending_complete == SNGISDN_OPT_TRUE) { - conEvnt.sndCmplt.eh.pres = PRSNT_NODEF; - } - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP && - signal_data->signalling == SNGISDN_SIGNALING_NET) { - sngisdn_info->ces = CES_MNGMNT; - } - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits); - - set_chan_id_ie(ftdmchan, &conEvnt.chanId); - set_bear_cap_ie(ftdmchan, &conEvnt.bearCap[0]); - set_called_num(ftdmchan, &conEvnt.cdPtyNmb); - set_calling_num(ftdmchan, &conEvnt.cgPtyNmb); - set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2); - set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad); - set_called_subaddr(ftdmchan, &conEvnt.cdPtySad); - set_redir_num(ftdmchan, &conEvnt.redirNmb); - set_calling_name(ftdmchan, &conEvnt); - set_network_specific_fac(ftdmchan, &conEvnt.netFac[0]); - - /* set_facility_ie will overwrite Calling Name for NI-2 if user specifies custom Facility IE */ - set_facility_ie(ftdmchan, &conEvnt.facilityStr); - set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP request\n"); - } - - return; -} - -/* Unsed only for overlap receive */ -void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan) -{ - CnStEvnt cnStEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending SETUP ACK , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - return; - } - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_SETUPACK, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP ACK request\n"); - } - return; -} - - -/* Used only for BRI PTMP - This function is used when the NT side makes a call out, - and one or multiple TE's reply, then NT assigns the call by sending a con_complete*/ -void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan) -{ - CnStEvnt cnStEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT COMPL , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - return; - } - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - /* Indicate channel ID only in first response */ - if (!ftdm_test_flag(sngisdn_info, FLAG_SENT_CHAN_ID)) { - set_chan_id_ie(ftdmchan, &cnStEvnt.chanId); - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if(sng_isdn_con_comp(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT ACK request\n"); - } - return; -} - - -void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind) -{ - CnStEvnt cnStEvnt; - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { - return; - } - sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - return; - } - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - /* Indicate channel ID only in first response */ - if (!ftdm_test_flag(sngisdn_info, FLAG_SENT_CHAN_ID)) { - set_chan_id_ie(ftdmchan, &cnStEvnt.chanId); - } - set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); - set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_CALLPROC, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused PROCEED request\n"); - } - return; -} - -void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind) -{ - CnStEvnt cnStEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - return; - } - - if (signal_data->switchtype == SNGISDN_SWITCH_INSNET) { - /* Trillium Q931 layer complains of invalid event when receiving PROGRESS in - INSNET variant, so PROGRESS event is probably invalid */ - return; - } - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); - set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused PROGRESS request\n"); - } - return; -} - -void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind) -{ - CnStEvnt cnStEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - return; - } - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); - set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_ALERTING, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused ALERT request\n"); - } - return; -} - -void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) -{ - CnStEvnt cnStEvnt; - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; - - if (sngisdn_test_flag(sngisdn_info, FLAG_SENT_CONNECT)) { - return; - } - sngisdn_set_flag(sngisdn_info, FLAG_SENT_CONNECT); - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - return; - } - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - /* Indicate channel ID only in first response */ - if (!ftdm_test_flag(sngisdn_info, FLAG_SENT_CHAN_ID)) { - set_chan_id_ie(ftdmchan, &cnStEvnt.chanId); - } - set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); - set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT request\n"); - } - return; -} - -void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan) -{ - FacEvnt facEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending FACILITY, but no call data, ignoring (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - return; - } - - memset(&facEvnt, 0, sizeof(facEvnt)); - - if (set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (uint8_t*)&facEvnt.facElmt.facStr.len) != FTDM_SUCCESS) { - /* No point in sending a FACILITY message if there is no Facility IE to transmit */ - return; - } - - facEvnt.facElmt.eh.pres = PRSNT_NODEF; - facEvnt.facElmt.facStr.pres = PRSNT_NODEF; - facEvnt.facElmt.facStr.val[0] = 0x1C; - facEvnt.facElmt.facStr.val[1] = (uint8_t)facEvnt.facElmt.facStr.len; - facEvnt.facElmt.facStr.len +=2; /* Need to include the size of identifier + len */ - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused FACILITY request\n"); - } - return; -} - -/* This is used to request Q.921 to initiate link establishment */ -void sngisdn_snd_dl_req(ftdm_channel_t *ftdmchan) -{ - CnStEvnt cnStEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Requesting Link establishment (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Link establishment\n"); - } - return; -} - -void sngisdn_snd_notify_req(ftdm_channel_t *ftdmchan) -{ - CnStEvnt cnStEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending NOTIFY, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - return; - } - - memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - set_not_ind_ie(ftdmchan, &cnStEvnt.notInd); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending NOTIFY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - - if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_NOTIFY, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused NOTIFY request\n"); - } - return; -} - - -void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan) -{ - StaEvnt staEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - //ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending STATUS ENQ\n"); - - memset(&staEvnt, 0, sizeof(StaEvnt)); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_dchan(signal_data)->link_id, sngisdn_info->ces); - if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Status ENQ request\n"); - } - return; -} - - -void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan) -{ - DiscEvnt discEvnt; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - return; - } - - memset(&discEvnt, 0, sizeof(discEvnt)); - - set_cause_ie(ftdmchan, &discEvnt.causeDgn[0]); - set_facility_ie(ftdmchan, &discEvnt.facilityStr); - set_user_to_user_ie(ftdmchan, &discEvnt.usrUsr); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n"); - } - return; -} - -void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) -{ - RelEvnt relEvnt; - uint32_t suInstId, spInstId; - - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (!sngisdn_info->suInstId) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending RELEASE, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - return; - } - - memset(&relEvnt, 0, sizeof(relEvnt)); - - /* Fill relEvnt here */ - relEvnt.causeDgn[0].eh.pres = PRSNT_NODEF; - relEvnt.causeDgn[0].location.pres = PRSNT_NODEF; - relEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU; - relEvnt.causeDgn[0].codeStand3.pres = PRSNT_NODEF; - relEvnt.causeDgn[0].codeStand3.val = IN_CSTD_CCITT; - - relEvnt.causeDgn[0].causeVal.pres = PRSNT_NODEF; - relEvnt.causeDgn[0].causeVal.val = ftdmchan->caller_data.hangup_cause; - relEvnt.causeDgn[0].recommend.pres = NOTPRSNT; - relEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT; - - if (glare) { - suInstId = sngisdn_info->glare.suInstId; - spInstId = sngisdn_info->glare.spInstId; - } else { - suInstId = sngisdn_info->suInstId; - spInstId = sngisdn_info->spInstId; - } - - set_facility_ie(ftdmchan, &relEvnt.facilityStr); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId); - - if (glare) { - if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n"); - } - } else { - if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n"); - } - } - return; -} - -void sngisdn_snd_restart(ftdm_channel_t *ftdmchan) -{ - Rst rstEvnt; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - memset(&rstEvnt, 0, sizeof(rstEvnt)); - - set_chan_id_ie(ftdmchan, &rstEvnt.chanId); - set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_dchan(signal_data)->link_id, CES_MNGMNT); - - if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, sngisdn_dchan(signal_data)->link_id, CES_MNGMNT, IN_SND_RST)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n"); - } - return; -} - - -/* We received an incoming frame on the d-channel, send data to the stack */ -void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len) -{ - sng_l1_frame_t l1_frame; - ftdm_alarm_flag_t alarmbits = 0; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data; - - ftdm_channel_get_alarms(dchan, &alarmbits); - - if (alarmbits) { - ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Dropping incoming data due to L1 alarm\n"); - return; - } - - if (len > sizeof(l1_frame.data)) { - ftdm_log_chan(dchan, FTDM_LOG_ERROR, "Received frame of %"FTDM_SIZE_FMT" bytes, exceeding max size of %"FTDM_SIZE_FMT" bytes\n", - len, sizeof(l1_frame.data)); - return; - } - if (len <= 2) { - return; - } - - memset(&l1_frame, 0, sizeof(l1_frame)); - l1_frame.len = len; - - memcpy(&l1_frame.data, data, len); - - if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC)) { - l1_frame.flags |= SNG_L1FRAME_ERROR_CRC; - } - - if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME)) { - l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME; - } - - if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT)) { - l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT; - } - - if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO)) { - l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO; - } - - if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA)) { - l1_frame.flags |= SNG_L1FRAME_ERROR_DMA; - } - - if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) { - /* Should we trigger congestion here? */ - l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES; - } - - if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) { - /* Should we trigger congestion here? */ - l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL; - } -#if 0 - if (1) { - int i; - char string [2000]; - unsigned string_len = 0; - for (i = 0; i < l1_frame.len; i++) { - string_len += sprintf(&string[string_len], "0x%02x ", l1_frame.data[i]); - } - - ftdm_log_chan(dchan, FTDM_LOG_CRIT, "\nL1 RX [%s] flags:%x\n", string, l1_frame.flags); - } -#endif - sng_isdn_data_ind(signal_data->link_id, &l1_frame); -} - -void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event) -{ - sng_l1_event_t l1_event; - - if (!signal_data->dchan) { - return; - } - memset(&l1_event, 0, sizeof(l1_event)); - - switch(event) { - case FTDM_OOB_ALARM_CLEAR: - l1_event.type = SNG_L1EVENT_ALARM_OFF; - sng_isdn_event_ind(signal_data->link_id, &l1_event); - - if (!signal_data->dl_request_pending) { - signal_data->dl_request_pending = 1; - ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 8000, sngisdn_delayed_dl_req, (void*) signal_data, NULL); - } - break; - case FTDM_OOB_ALARM_TRAP: - l1_event.type = SNG_L1EVENT_ALARM_ON; - sng_isdn_event_ind(signal_data->link_id, &l1_event); - break; - default: - /* We do not care about the other OOB events for now */ - return; - } - return; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c deleted file mode 100644 index e5bebb1c8b..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ /dev/null @@ -1,1134 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" -//static void sngisdn_rcv_q931_ind_span(sngisdn_span_data_t *signal_data, InMngmt *status); - -void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces) -{ - uint8_t bchan_no = 0; - int8_t interface_id = -1; /* Specifies which interface for NFAS */ - sngisdn_chan_data_t *sngisdn_info = NULL; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Ind on unconfigured cc\n"); - ftdm_assert(g_sngisdn_data.spans[dChan], "Con Ind on unconfigured dchan\n"); - - if (conEvnt->chanId.eh.pres != PRSNT_NODEF) { - /* TODO: Implement me */ - ftdm_log(FTDM_LOG_ERROR, "Incoming call without Channel Id not supported yet\n"); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - if (conEvnt->chanId.chanNmbSlotMap.pres) { - bchan_no = conEvnt->chanId.chanNmbSlotMap.val[0]; - } else if (conEvnt->chanId.infoChanSel.pres) { - bchan_no = conEvnt->chanId.infoChanSel.val; - } - - if (conEvnt->chanId.intIdent.pres) { - interface_id = conEvnt->chanId.intIdent.val; - } - - if (!bchan_no) { - ftdm_log(FTDM_LOG_ERROR, "Failed to obtain b-channel number from SETUP message\n"); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - if (g_sngisdn_data.spans[dChan]->nfas.trunk) { - if (interface_id < 0) { - ftdm_log(FTDM_LOG_ERROR, "Interface ID not present on NFAS interface\n"); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } else if (!g_sngisdn_data.spans[dChan]->nfas.trunk->spans[interface_id]) { - ftdm_log(FTDM_LOG_ERROR, "NFAS group:%s does not have logical interface %d\n", g_sngisdn_data.spans[dChan]->nfas.trunk->name, interface_id); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } else { - sngisdn_info = g_sngisdn_data.spans[dChan]->nfas.trunk->spans[interface_id]->channels[bchan_no]; - } - } else { - if (g_sngisdn_data.spans[dChan]->channels[bchan_no] == NULL) { - ftdm_log(FTDM_LOG_ERROR, "Incoming call on unconfigured b-channel:%d\n", bchan_no); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - sngisdn_info = g_sngisdn_data.spans[dChan]->channels[bchan_no]; - } - - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_CON_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - - memcpy(&sngisdn_event->event.conEvnt, conEvnt, sizeof(*conEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces) -{ - sngisdn_chan_data_t *sngisdn_info = NULL; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Cfm on unconfigured cc\n"); - ftdm_assert(g_sngisdn_data.spans[dChan] != 0, "Con Cfm on unconfigured dchan\n"); - - if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } - - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_CON_CFM; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces) -{ - sngisdn_chan_data_t *sngisdn_info = NULL; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Cnst Ind on unconfigured cc\n"); - ftdm_assert(g_sngisdn_data.spans[dChan] != 0, "Cnst Ind on unconfigured dchan\n"); - - if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n", - (evntType == MI_ALERTING)?"ALERT": - (evntType == MI_CALLPROC)?"PROCEED": - (evntType == MI_PROGRESS)?"PROGRESS": - (evntType == MI_SETUPACK)?"SETUP ACK": - (evntType == MI_NOTIFY)?"NOTIFY": - (evntType == MI_INFO)?"INFO":"UNKNOWN", - suId, suInstId, spInstId, ces); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_CNST_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->evntType = evntType; - - memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt) -{ - sngisdn_chan_data_t *sngisdn_info = NULL; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id"); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_DISC_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - - memcpy(&sngisdn_event->event.discEvnt, discEvnt, sizeof(*discEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt) -{ - sngisdn_chan_data_t *sngisdn_info = NULL; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - /* It seems that Trillium has a bug where they sometimes send release twice on a call, so do not crash on these for now */ - /* ftdm_assert(0, "Inconsistent call states\n"); */ - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_REL_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - - memcpy(&sngisdn_event->event.relEvnt, relEvnt, sizeof(*relEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DATA IND suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_DAT_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - - memcpy(&sngisdn_event->event.infoEvnt, infoEvnt, sizeof(*infoEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_SSHL_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->action = action; - - memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_SSHL_CFM; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->action = action; - - memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} -void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RMRT IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_RMRT_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->action = action; - - memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_RMRT_CFM; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->action = action; - - memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_FLC_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - - memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - - -void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_FAC_IND; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - sngisdn_event->evntType = evntType; - - memcpy(&sngisdn_event->event.facEvnt, facEvnt, sizeof(*facEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - - -void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt) -{ - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - if (!suInstId && !spInstId) { - /* This is a response to a sngisdn_snd_info_req - * that was sent to attempt to re-establish DL link */ - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* We sometimes receive a STA CFM after receiving a RELEASE/RELEASE COMPLETE, so we need to lock - here in case we are calling clear_call_data at the same time this function is called */ - - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && - !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { - - ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - return; - } - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - - sngisdn_event->event_id = SNGISDN_EVENT_STA_CFM; - sngisdn_event->sngisdn_info = sngisdn_info; - sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; - sngisdn_event->spInstId = spInstId; - - memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt)); - - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces) -{ - - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces); - - signal_data = g_sngisdn_data.spans[dChan]; - - if (signal_data->nfas.trunk) { - unsigned i; - for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { - sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - sngisdn_event->event_id = SNGISDN_EVENT_SRV_IND; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->signal_data = my_signal_data; - memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); - ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); - } - } else { - ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); - } - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - - -void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces) -{ - sngisdn_span_data_t *signal_data = NULL; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces); - - signal_data = g_sngisdn_data.spans[dChan]; - - if (signal_data->nfas.trunk) { - unsigned i; - for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { - sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - sngisdn_event->event_id = SNGISDN_EVENT_SRV_CFM; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->signal_data = my_signal_data; - memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); - ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); - } - } else { - ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); - } - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType) -{ - sngisdn_span_data_t *signal_data = NULL; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_log(FTDM_LOG_INFO, "Received RESTART IND (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); - - signal_data = g_sngisdn_data.spans[dChan]; - - if (signal_data->nfas.trunk) { - unsigned i; - for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { - sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - sngisdn_event->event_id = SNGISDN_EVENT_RST_IND; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->signal_data = my_signal_data; - memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt)); - ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); - } - } else { - ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); - } - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType) -{ - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event = NULL; - - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - - ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); - - signal_data = g_sngisdn_data.spans[dChan]; - - if (signal_data->nfas.trunk) { - unsigned i; - for (i = 0; i < signal_data->nfas.trunk->num_spans; i++) { - sngisdn_span_data_t *my_signal_data = signal_data->nfas.trunk->spans[i]; - - sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); - memset(sngisdn_event, 0, sizeof(*sngisdn_event)); - sngisdn_event->event_id = SNGISDN_EVENT_RST_CFM; - sngisdn_event->suId = suId; - sngisdn_event->dChan = dChan; - sngisdn_event->ces = ces; - sngisdn_event->signal_data = my_signal_data; - memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt)); - ftdm_queue_enqueue(my_signal_data->event_queue, sngisdn_event); - } - } else { - ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event); - } - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - - -void sngisdn_rcv_phy_ind(SuId suId, Reason reason) -{ - if (reason != LL1_REASON_CON_REQ_FAIL) { - ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason)); - } - return; -} - -void sngisdn_rcv_q921_ind(BdMngmt *status) -{ - ftdm_span_t *ftdmspan; - - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.lnkNmb]; - - if (!signal_data) { - ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); - return; - } - ftdmspan = signal_data->ftdm_span; - - if (!ftdmspan) { - ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); - return; - } - - switch (status->t.usta.alarm.category) { - case (LCM_CATEGORY_PROTOCOL): - ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n", - ftdmspan->name, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LLD_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LLD_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - if (FTDM_SPAN_IS_BRI(ftdmspan) && (status->t.usta.alarm.event == PROT_ST_DN)) { - /* Q.921 link is down - This is a line where the Q.921 stops transmitting - after the line goes idle. - - Do not drop current calls, but set sigstatus do down so that we - can try to re-initialize link before trying new outbound calls */ - - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); - sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); - } - break; - default: - ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n", - ftdmspan->name, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LLD_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LLD_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - switch (status->t.usta.alarm.event) { - case ENTR_CONG: /* Entering Congestion */ - ftdm_log(FTDM_LOG_WARNING, "s%d: Entering Congestion\n", ftdmspan->span_id); - ftdm_set_flag(ftdmspan, FTDM_SPAN_SUSPENDED); - break; - case EXIT_CONG: /* Exiting Congestion */ - ftdm_log(FTDM_LOG_WARNING, "s%d: Exiting Congestion\n", ftdmspan->span_id); - ftdm_clear_flag(ftdmspan, FTDM_SPAN_SUSPENDED); - break; - } - break; - } - return; -} - -#if 0 -static void sngisdn_rcv_q931_ind_span(sngisdn_span_data_t *signal_data, InMngmt *status) -{ - ftdm_span_t *ftdmspan = signal_data->ftdm_span; - uint32_t chan_no = status->t.usta.evntParm[2]; - - if (!signal_data) { - ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); - return; - } - - ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - if (chan_no) { - ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no); - if (ftdmchan) { - sngisdn_set_chan_sig_status(ftdmchan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN); - sngisdn_set_chan_avail_rate(ftdmchan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? SNGISDN_AVAIL_UP: SNGISDN_AVAIL_PWR_SAVING); - } else { - ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no); - } - } else { - sngisdn_set_span_sig_status(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN); - sngisdn_set_span_avail_rate(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? SNGISDN_AVAIL_UP: SNGISDN_AVAIL_PWR_SAVING); - } -} -#endif - -void sngisdn_rcv_q931_ind(InMngmt *status) -{ - sngisdn_span_data_t *signal_data = NULL; - ftdm_span_t *ftdmspan = NULL; -#ifndef WIN32 - if (status->t.usta.alarm.cause == 287) { - sngisdn_get_memory_info(); - return; - } -#endif - - signal_data = g_sngisdn_data.spans[status->t.usta.suId]; - if (!signal_data) { - ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); - return; - } - - ftdmspan = signal_data->ftdm_span; - - switch (status->t.usta.alarm.event) { - case LCM_EVENT_UP: - case LCM_EVENT_DOWN: - { - int i; - sngisdn_nfas_data_t *nfas_data = NULL; - ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - nfas_data = signal_data->nfas.trunk; - - if (nfas_data && status->t.usta.alarm.event == LCM_EVENT_UP) { - for (i = 0; i < ftdm_array_len(nfas_data->spans); i++) { - if (nfas_data->spans[i] && nfas_data->spans[i]->nfas.sigchan == SNGISDN_NFAS_DCHAN_NONE) { - - sngisdn_set_span_sig_status(nfas_data->spans[i]->ftdm_span, FTDM_SIG_STATE_UP); - sngisdn_set_span_avail_rate(nfas_data->spans[i]->ftdm_span, SNGISDN_AVAIL_UP); - } - } - } - - sngisdn_set_span_sig_status(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? FTDM_SIG_STATE_UP : FTDM_SIG_STATE_DOWN); - sngisdn_set_span_avail_rate(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP) ? SNGISDN_AVAIL_UP: SNGISDN_AVAIL_PWR_SAVING); - - if (nfas_data && status->t.usta.alarm.event == LCM_EVENT_DOWN) { - if (nfas_data->dchan->sigstatus == FTDM_SIG_STATE_DOWN && - ((nfas_data->backup && nfas_data->backup->sigstatus == FTDM_SIG_STATE_DOWN) || !nfas_data->backup)) { - - for (i = 0; i < ftdm_array_len(nfas_data->spans); i++) { - if (nfas_data->spans[i] && nfas_data->spans[i]->nfas.sigchan == SNGISDN_NFAS_DCHAN_NONE) { - - sngisdn_set_span_sig_status(nfas_data->spans[i]->ftdm_span, FTDM_SIG_STATE_DOWN); - sngisdn_set_span_avail_rate(nfas_data->spans[i]->ftdm_span, SNGISDN_AVAIL_PWR_SAVING); - } - } - } - } - } - break; - default: - ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - } - - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_rcv_cc_ind(CcMngmt *status) -{ - ISDN_FUNC_TRACE_ENTER(__FTDM_FUNC__); - ftdm_log(FTDM_LOG_INFO, "RECEIVED %s\n", __FTDM_FUNC__); - ISDN_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - -void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) -{ - MsgLen mlen; - int16_t j; - Buffer *tmp; - Data *cptr; - uint8_t data; - ftdm_trace_dir_t dir; - uint8_t tdata[1000]; - - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.suId]; - - ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer"); - mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len; - - if (trc->t.trc.evnt == TL3PKTTX) { - dir = FTDM_TRACE_DIR_OUTGOING; - } else { - dir = FTDM_TRACE_DIR_INCOMING; - } - - if (mlen) { - tmp = mBuf->b_cont; - cptr = tmp->b_rptr; - data = *cptr++; - - for(j=0;jb_wptr) { - tmp = tmp->b_cont; - if (tmp) cptr = tmp->b_rptr; - } - data = *cptr++; - } - if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) { - sngisdn_trace_raw_q931(signal_data, dir, tdata, mlen); - } else { - sngisdn_trace_interpreted_q931(signal_data, dir, tdata, mlen); - } - } - return; -} - - -void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf) -{ - MsgLen mlen; - Buffer *tmp; - MsgLen i; - int16_t j; - Data *cptr; - uint8_t data; - ftdm_trace_dir_t dir; - uint8_t tdata[1000]; - - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.lnkNmb]; - - if (trc->t.trc.evnt == TL2TMR) { - return; - } - - if (trc->t.trc.evnt == TL2FRMTX) { - dir = FTDM_TRACE_DIR_OUTGOING; - } else { - dir = FTDM_TRACE_DIR_INCOMING; - } - - ftdm_assert(mBuf != NULLP, "Received a Q921 trace with no buffer"); - mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len; - if (mlen != 0) { - tmp = mBuf->b_cont; - cptr = tmp->b_rptr; - data = *cptr++; - i = 0; - while (i < mlen) { - j = 0; - for(j=0;j<16;j++) { - if (ib_wptr) { - tmp = tmp->b_cont; - if (tmp) cptr = tmp->b_rptr; - } - i++; - if (iraw_trace_q921 == SNGISDN_OPT_TRUE) { - sngisdn_trace_raw_q921(signal_data, dir, tdata, mlen); - } else { - sngisdn_trace_interpreted_q921(signal_data, dir, tdata, mlen); - } - } - return; -} - -/* The stacks is wants to transmit a frame */ -int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame) -{ - ftdm_status_t status; - ftdm_wait_flag_t flags = FTDM_WRITE; - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; - ftdm_size_t length = l1_frame->len; - - ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); - - do { - flags = FTDM_WRITE; - status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 1000); - switch(status) { - case FTDM_SUCCESS: - break; - case FTDM_TIMEOUT: - continue; - case FTDM_FAIL: - default: - ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "failed to poll for channel\n"); - return -1; - } - - - /* status = FTDM_SUCCESS */ - if ((flags & FTDM_WRITE)) { -#if 0 - int i; - char string [2000]; - unsigned string_len = 0; - for (i = 0; i < length; i++) { - string_len += sprintf(&string[string_len], "0x%02x ", l1_frame->data[i]); - } - - ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "\nL1 TX [%s]\n", string); -#endif - - status = signal_data->dchan->fio->write(signal_data->dchan, l1_frame->data, (ftdm_size_t*)&length); - if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n"); - return -1; - } - break; - /* On WIN32, it is possible for poll to return without FTDM_WRITE flag set, so we try to retransmit */ -#ifndef WIN32 - } else { - ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_WARNING, "Failed to poll for d-channel\n"); - return -1; -#endif - } - } while(1); - return 0; -} - -int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd) -{ - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; - ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); - - switch(l1_cmd->type) { - case SNG_L1CMD_SET_LINK_STATUS: - { - ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED; - ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_SET_LINK_STATUS, &status); - } - break; - case SNG_L1CMD_GET_LINK_STATUS: - { - ftdm_channel_hw_link_status_t status = 0; - ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_GET_LINK_STATUS, &status); - if (status == FTDM_HW_LINK_CONNECTED) { - l1_cmd->cmd.status = 1; - } else if (status == FTDM_HW_LINK_DISCONNECTED) { - l1_cmd->cmd.status = 0; - } else { - ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Invalid link status reported %d\n", status); - l1_cmd->cmd.status = 0; - } - } - break; - case SNG_L1CMD_FLUSH_STATS: - ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL); - break; - case SNG_L1CMD_FLUSH_BUFFERS: - ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_BUFFERS, NULL); - break; - default: - ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Unsupported channel command:%d\n", l1_cmd->type); - return -1; - } - return 0; -} - -void sngisdn_rcv_sng_assert(char *message) -{ - ftdm_assert(0, message); -} - -void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...) -{ - char *data; - int ret; - va_list ap; - - va_start(ap, fmt); - ret = ftdm_vasprintf(&data, fmt, ap); - if (ret == -1) { - return; - } - - switch (level) { - case SNG_LOGLEVEL_DEBUG: - ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s", data); - break; - case SNG_LOGLEVEL_WARN: - if ( strncmp(data, "Invalid Q.921/Q.931 frame", 25) ) { - ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data); - } - break; - case SNG_LOGLEVEL_INFO: - ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data); - break; - case SNG_LOGLEVEL_STATS: - ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data); - break; - case SNG_LOGLEVEL_ERROR: - ftdm_log(FTDM_LOG_ERROR, "sng_isdn->%s\n", data); - /*ftdm_assert(0, "Got an error from stack");*/ - break; - case SNG_LOGLEVEL_CRIT: - ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s\n", data); - /* ftdm_assert(0, "Got an error from stack"); */ - break; - default: - ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s\n", data); - break; - } - ftdm_safe_free(data); - return; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c deleted file mode 100644 index 83dd070387..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ /dev/null @@ -1,1643 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" -#define SNGISDN_Q931_FACILITY_IE_ID 0x1C - -/* ftmod_sangoma_isdn specific enum look-up functions */ - -SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_STRINGS) -SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t, SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_INVALID) - -SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS) -SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID) - -SNGISDN_ENUM_NAMES(SNGISDN_NETSPECFAC_TYPE_NAMES, SNGISDN_NETSPECFAC_TYPE_STRINGS) -SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_netspecfac_type, ftdm_sngisdn_netspecfac_type2str, ftdm_sngisdn_netspecfac_type_t, SNGISDN_NETSPECFAC_TYPE_NAMES, SNGISDN_NETSPECFAC_TYPE_INVALID) - -SNGISDN_ENUM_NAMES(SNGISDN_NETSPECFAC_PLAN_NAMES, SNGISDN_NETSPECFAC_PLAN_STRINGS) -SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_netspecfac_plan, ftdm_sngisdn_netspecfac_plan2str, ftdm_sngisdn_netspecfac_plan_t, SNGISDN_NETSPECFAC_PLAN_NAMES, SNGISDN_NETSPECFAC_PLAN_INVALID) - -SNGISDN_ENUM_NAMES(SNGISDN_NETSPECFAC_SPEC_NAMES, SNGISDN_NETSPECFAC_SPEC_STRINGS) -SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_netspecfac_spec, ftdm_sngisdn_netspecfac_spec2str, ftdm_sngisdn_netspecfac_spec_t, SNGISDN_NETSPECFAC_SPEC_NAMES, SNGISDN_NETSPECFAC_SPEC_INVALID) - -static uint8_t _get_trillium_val(ftdm2trillium_t *vals, unsigned int num_vals, uint8_t ftdm_val, uint8_t default_val); -static uint8_t _get_ftdm_val(ftdm2trillium_t *vals, unsigned int num_vals, uint8_t trillium_val, uint8_t default_val); - -#define get_trillium_val(vals, ftdm_val, default_val) _get_trillium_val(vals, ftdm_array_len(vals), ftdm_val, default_val) -#define get_ftdm_val(vals, trillium_val, default_val) _get_ftdm_val(vals, ftdm_array_len(vals), trillium_val, default_val) - -ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr); -ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display); -ftdm_status_t get_calling_name_from_ntDisplay(ftdm_channel_t *ftdmchan, NtDisplay *display); - -extern ftdm_sngisdn_data_t g_sngisdn_data; - -ftdm2trillium_t npi_codes[] = { - {FTDM_NPI_UNKNOWN, IN_NP_UNK}, - {FTDM_NPI_ISDN, IN_NP_ISDN}, - {FTDM_NPI_DATA, IN_NP_DATA}, - {FTDM_NPI_TELEX, IN_NP_TELEX}, - {FTDM_NPI_NATIONAL, IN_NP_NATIONAL}, - {FTDM_NPI_PRIVATE, IN_NP_PRIVATE}, - {FTDM_NPI_RESERVED, IN_NP_EXT}, -}; - -ftdm2trillium_t ton_codes[] = { - {FTDM_TON_UNKNOWN, IN_TON_UNK}, - {FTDM_TON_INTERNATIONAL, IN_TON_INT}, - {FTDM_TON_NATIONAL, IN_TON_NAT}, - {FTDM_TON_NETWORK_SPECIFIC, IN_TON_NETSPEC}, - {FTDM_TON_SUBSCRIBER_NUMBER, IN_TON_SUB}, - {FTDM_TON_ABBREVIATED_NUMBER, IN_TON_ABB}, - {FTDM_TON_RESERVED, IN_TON_EXT}, -}; - -ftdm2trillium_t nsf_spec_codes[] = { - {SNGISDN_NETSPECFAC_SPEC_ACCUNET, 0xe6}, - {SNGISDN_NETSPECFAC_SPEC_MEGACOM, 0xe3}, - {SNGISDN_NETSPECFAC_SPEC_MEGACOM_800, 0xe2}, - {SNGISDN_NETSPECFAC_SPEC_SDDN, 0xe1}, - {SNGISDN_NETSPECFAC_SPEC_INVALID, 0x00}, -}; - -ftdm2trillium_t nsf_type_codes[] = { - {SNGISDN_NETSPECFAC_TYPE_USER_SPEC, 0x00}, - {SNGISDN_NETSPECFAC_TYPE_NATIONAL_NETWORK_IDENT, 0x02}, - {SNGISDN_NETSPECFAC_TYPE_INTERNATIONAL_NETWORK_IDENT, 0x03}, - {SNGISDN_NETSPECFAC_TYPE_INVALID, 0x00}, -}; - -ftdm2trillium_t nsf_plan_codes[] = { - {SNGISDN_NETSPECFAC_PLAN_UNKNOWN, 0x00}, - {SNGISDN_NETSPECFAC_PLAN_CARRIER_IDENT, 0x01}, - {SNGISDN_NETSPECFAC_PLAN_DATA_NETWORK_IDENT, 0x03}, - {SNGISDN_NETSPECFAC_PLAN_INVALID, 0x00}, -}; - -static uint8_t _get_trillium_val(ftdm2trillium_t *vals, unsigned int num_vals, uint8_t ftdm_val, uint8_t default_val) -{ - int i; - for (i = 0; i < num_vals; i++) { - if (vals[i].ftdm_val == ftdm_val) { - return vals[i].trillium_val; - } - } - - return default_val; -} - -static uint8_t _get_ftdm_val(ftdm2trillium_t *vals, unsigned int num_vals, uint8_t trillium_val, uint8_t default_val) -{ - int i; - for (i = 0; i < num_vals; i++) { - if (vals[i].trillium_val == trillium_val) { - return vals[i].ftdm_val; - } - } - return default_val; -} - -void clear_call_data(sngisdn_chan_data_t *sngisdn_info) -{ - uint32_t cc_id = ((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->cc_id; - - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing call data (suId:%u suInstId:%u spInstId:%u)\n", cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); - ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex); - g_sngisdn_data.ccs[cc_id].active_spInstIds[sngisdn_info->spInstId]=NULL; - g_sngisdn_data.ccs[cc_id].active_suInstIds[sngisdn_info->suInstId]=NULL; - - sngisdn_info->suInstId = 0; - sngisdn_info->spInstId = 0; - sngisdn_info->globalFlg = 0; - sngisdn_info->flags = 0; - sngisdn_info->transfer_data.type = SNGISDN_TRANSFER_NONE; - - ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex); - return; -} - -void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info) -{ - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing glare data (suId:%d suInstId:%u spInstId:%u actv-suInstId:%u actv-spInstId:%u)\n", - sngisdn_info->glare.suId, - sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId, - sngisdn_info->suInstId, sngisdn_info->spInstId); - - ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); - if (sngisdn_info->glare.spInstId != sngisdn_info->spInstId) { - g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL; - } - g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_suInstIds[sngisdn_info->glare.suInstId]=NULL; - ftdm_mutex_unlock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); - - ftdm_clear_flag(sngisdn_info, FLAG_GLARE); - memset(&sngisdn_info->glare.setup, 0, sizeof(ConEvnt)); - sngisdn_info->glare.suId = 0; - sngisdn_info->glare.suInstId = 0; - sngisdn_info->glare.spInstId = 0; - sngisdn_info->glare.dChan = 0; - sngisdn_info->glare.ces = 0; - return; -} - - -uint32_t get_unique_suInstId(int16_t cc_id) -{ - uint32_t suInstId; - ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n"); - ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex); - suInstId = g_sngisdn_data.ccs[cc_id].last_suInstId; - - while(1) { - if (++suInstId == MAX_INSTID) { - suInstId = 1; - } - if (g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId] == NULL) { - g_sngisdn_data.ccs[cc_id].last_suInstId = suInstId; - ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex); - return suInstId; - } - } - /* Should never reach here */ - ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex); - return 0; -} - -ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data) -{ - ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n"); - ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n"); - - if (g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId] == NULL) { - return FTDM_FAIL; - } - *sngisdn_data = g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId]; - return FTDM_SUCCESS; -} - -ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data) -{ - ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n"); - ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n"); - - if (g_sngisdn_data.ccs[cc_id].active_spInstIds[spInstId] == NULL) { - return FTDM_FAIL; - } - *sngisdn_data = g_sngisdn_data.ccs[cc_id].active_spInstIds[spInstId]; - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail) -{ - if (FTDM_SPAN_IS_BRI(chan->span)) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); - chan->availability_rate = avail; - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) -{ - if (FTDM_SPAN_IS_BRI(span)) { - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); - sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail); - } - ftdm_iterator_free(chaniter); - } - return FTDM_SUCCESS; -} - -#ifdef NETBORDER_CALL_REF -ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - - if (signal_data->raw_trace_q931) { - if (callRef->eh.pres != PRSNT_NODEF || callRef->reference.pres != PRSNT_NODEF) { - /* Netborder only supports BRI, so we only care for BRI for now */ - if (FTDM_SPAN_IS_BRI(ftdmchan->span) && !sngisdn_info->call_ref) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to obtain call reference\n"); - } - return FTDM_FAIL; - } - if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { - sngisdn_info->call_ref = 0x7F & callRef->reference.val; - } else { - sngisdn_info->call_ref = 0x7FFF & callRef->reference.val; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call reference:%04x\n", sngisdn_info->call_ref); - } - return FTDM_SUCCESS; -} -#endif - -ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - if (cgPtyNmb->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) { - caller_data->screen = cgPtyNmb->screenInd.val; - } - - if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) { - caller_data->pres = cgPtyNmb->presInd0.val; - } - - if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) { - caller_data->cid_num.plan = cgPtyNmb->nmbPlanId.val; - } - - if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) { - caller_data->cid_num.type = cgPtyNmb->typeNmb1.val; - } - - if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) { - ftdm_copy_string(caller_data->cid_num.digits, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len+1); - } - memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani)); - return FTDM_SUCCESS; -} - -ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - if (cgPtyNmb->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) { - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.cg_pty2.screen_ind", ftdm_screening2str(cgPtyNmb->screenInd.val)); - } - - if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) { - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.cg_pty2.presentation_ind", ftdm_presentation2str(cgPtyNmb->presInd0.val)); - } - - if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) { - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.cg_pty2.npi", ftdm_npi2str(cgPtyNmb->nmbPlanId.val)); - } - - if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) { - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.cg_pty2.ton", ftdm_ton2str(cgPtyNmb->typeNmb1.val)); - } - - if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) { - char digits_string [32]; - memcpy(digits_string, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len); - digits_string[cgPtyNmb->nmbDigits.len] = '\0'; - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.cg_pty2.digits", digits_string); - } - memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani)); - return FTDM_SUCCESS; -} - -ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - if (cdPtyNmb->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) { - caller_data->dnis.plan = get_ftdm_val(npi_codes, cdPtyNmb->nmbPlanId.val, IN_NP_UNK); - } - - if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) { - caller_data->dnis.type = get_ftdm_val(ton_codes, cdPtyNmb->typeNmb0.val, IN_TON_UNK); - } - - if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) { - /* In overlap receive mode, append the new digits to the existing dnis */ - unsigned i = strlen(caller_data->dnis.digits); - - ftdm_copy_string(&caller_data->dnis.digits[i], (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1); - } - return FTDM_SUCCESS; -} - -ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - if (redirNmb->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - if (redirNmb->nmbPlanId.pres == PRSNT_NODEF) { - caller_data->rdnis.plan = get_ftdm_val(npi_codes, redirNmb->nmbPlanId.val, IN_NP_UNK); - } - - if (redirNmb->typeNmb.pres == PRSNT_NODEF) { - caller_data->rdnis.type = get_ftdm_val(ton_codes, redirNmb->typeNmb.val, IN_TON_UNK); - } - - if (redirNmb->nmbDigits.pres == PRSNT_NODEF) { - ftdm_copy_string(caller_data->rdnis.digits, (const char*)redirNmb->nmbDigits.val, redirNmb->nmbDigits.len+1); - } - return FTDM_SUCCESS; -} - -ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - if (display->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - if (display->dispInfo.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - ftdm_copy_string(caller_data->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1); - return FTDM_SUCCESS; -} - -ftdm_status_t get_calling_name_from_ntDisplay(ftdm_channel_t *ftdmchan, NtDisplay *display) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - if (display->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - if (display->dispInfo.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - ftdm_copy_string(caller_data->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1); - return FTDM_SUCCESS; -} - -ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - if (usrUsr->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - if (usrUsr->protocolDisc.val != PD_IA5) { - return FTDM_FAIL; - } - - if (usrUsr->usrInfo.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - - ftdm_copy_string(caller_data->cid_name, (const char*)usrUsr->usrInfo.val, usrUsr->usrInfo.len+1); - return FTDM_SUCCESS; -} - -ftdm_status_t get_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt) -{ - ftdm_status_t status = FTDM_FAIL; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (signal_data->switchtype == SNGISDN_SWITCH_DMS100) { - status = get_calling_name_from_ntDisplay(ftdmchan, &conEvnt->ntDisplay[0]); - } else { - status = get_calling_name_from_display(ftdmchan, &conEvnt->display); - - } - if (status != FTDM_SUCCESS) { - status = get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr); - } - return status; -} - - -ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) -{ - char subaddress[100]; - - if (cgPtySad->eh.pres != PRSNT_NODEF) { - return FTDM_FAIL; - } - memset(subaddress, 0, sizeof(subaddress)); - if(cgPtySad->sadInfo.len >= sizeof(subaddress)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Calling Party Subaddress exceeds local size limit (len:%d max:%"FTDM_SIZE_FMT")\n", cgPtySad->sadInfo.len, sizeof(subaddress)); - cgPtySad->sadInfo.len = sizeof(subaddress)-1; - } - - memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len); - subaddress[cgPtySad->sadInfo.len] = '\0'; - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.calling_subaddr", subaddress); - return FTDM_SUCCESS; -} - -ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr) -{ - if (!facilityStr->eh.pres) { - return FTDM_FAIL; - } - - return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len); -} - -ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - /* Max size of Facility IE is 255 */ - uint8_t my_data [255]; - - /* Always include Facility IE identifier + len so this can be used as a sanity check by the user */ - my_data[0] = SNGISDN_Q931_FACILITY_IE_ID; - my_data[1] = data_len; - memcpy(&my_data[2], data, data_len); - - sngisdn_add_raw_data((sngisdn_chan_data_t*)ftdmchan->call_data, my_data, data_len+2); - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Raw Facility IE copied available\n"); - } else { - /* Call libsng_isdn to process facility IE's here */ - } - return FTDM_SUCCESS; -} - -ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd) -{ - uint8_t val; - - if (!progInd->eh.pres) { - return FTDM_FAIL; - } - - if (progInd->progDesc.pres) { - /* TODO: use get_ftdm_val function and table here */ - switch (progInd->progDesc.val) { - case IN_PD_NOTETEISDN: - val = SNGISDN_PROGIND_DESCR_NETE_ISDN; - break; - case IN_PD_DSTNOTISDN: - val = SNGISDN_PROGIND_DESCR_DEST_NISDN; - break; - case IN_PD_ORGNOTISDN: - val = SNGISDN_PROGIND_DESCR_ORIG_NISDN; - break; - case IN_PD_CALLRET: - val = SNGISDN_PROGIND_DESCR_RET_ISDN; - break; - case IN_PD_DELRESP: - val = SNGISDN_PROGIND_DESCR_SERV_CHANGE; - break; - case IN_PD_IBAVAIL: - val = SNGISDN_PROGIND_DESCR_IB_AVAIL; - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Description (%d)\n", progInd->progDesc.val); - val = SNGISDN_PROGIND_DESCR_INVALID; - break; - } - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val)); - } - - if (progInd->location.pres) { - switch (progInd->location.val) { - case IN_LOC_USER: - val = SNGISDN_PROGIND_LOC_USER; - break; - case IN_LOC_PRIVNETLU: - val = SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR; - break; - case IN_LOC_PUBNETLU: - val = SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR; - break; - case IN_LOC_TRANNET: - val = SNGISDN_PROGIND_LOC_TRANSIT_NET; - break; - case IN_LOC_PUBNETRU: - val = SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR; - break; - case IN_LOC_PRIVNETRU: - val = SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR; - break; - case IN_LOC_NETINTER: - val = SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW; - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Location (%d)", progInd->location.val); - val = SNGISDN_PROGIND_LOC_INVALID; - break; - } - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val)); - } - return FTDM_SUCCESS; -} - - -ftdm_status_t get_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac) -{ - if (!netFac->eh.pres) { - return FTDM_FAIL; - } - - if (netFac->netFacSpec.pres == PRSNT_NODEF) { - char digits_string [32]; - memcpy(digits_string, (const char*)netFac->netFacSpec.val, netFac->netFacSpec.len); - digits_string[netFac->netFacSpec.len] = '\0'; - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.netFac.spec", digits_string); - } - - if (netFac->typeNetId.pres == PRSNT_NODEF) { - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.netFac.type", ftdm_sngisdn_netspecfac_type2str(get_ftdm_val(nsf_type_codes, netFac->typeNetId.val, 0x00))); - } - - if (netFac->netIdPlan.pres == PRSNT_NODEF) { - sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.netFac.plan", ftdm_sngisdn_netspecfac_type2str(get_ftdm_val(nsf_plan_codes, netFac->netIdPlan.val, 0x00))); - } - return FTDM_SUCCESS; -} - -ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - uint8_t len = strlen(caller_data->cid_num.digits); - if (!len) { - return FTDM_SUCCESS; - } - - if (!strncasecmp(caller_data->cid_num.digits, "0000000000", strlen("0000000000"))) { - return FTDM_SUCCESS; - } - - cgPtyNmb->eh.pres = PRSNT_NODEF; - - cgPtyNmb->screenInd.pres = PRSNT_NODEF; - cgPtyNmb->screenInd.val = caller_data->screen; - - cgPtyNmb->presInd0.pres = PRSNT_NODEF; - cgPtyNmb->presInd0.val = caller_data->pres; - - cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF; - cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->cid_num.plan, IN_NP_UNK); - - cgPtyNmb->typeNmb1.pres = PRSNT_NODEF; - - cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, caller_data->cid_num.type, IN_TON_UNK); - - cgPtyNmb->nmbDigits.pres = PRSNT_NODEF; - cgPtyNmb->nmbDigits.len = len; - - memcpy(cgPtyNmb->nmbDigits.val, caller_data->cid_num.digits, len); - - return FTDM_SUCCESS; -} - -ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) -{ - const char* string = NULL; - uint8_t len,val; - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.digits"); - if (ftdm_strlen_zero(string)) { - return FTDM_FAIL; - } - - cgPtyNmb->eh.pres = PRSNT_NODEF; - - len = strlen(string); - cgPtyNmb->nmbDigits.len = len; - - cgPtyNmb->nmbDigits.pres = PRSNT_NODEF; - memcpy(cgPtyNmb->nmbDigits.val, string, len); - - /* Screening Indicator */ - cgPtyNmb->screenInd.pres = PRSNT_NODEF; - - val = FTDM_SCREENING_INVALID; - string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.screening_ind"); - if (!ftdm_strlen_zero(string)) { - val = ftdm_str2ftdm_screening(string); - } - - /* isdn.cg_pty2.screen_ind does not exist or we could not parse its value */ - if (val == FTDM_SCREENING_INVALID) { - /* default to caller data screening ind */ - cgPtyNmb->screenInd.val = caller_data->screen; - } else { - cgPtyNmb->screenInd.val = val; - } - - /* Presentation Indicator */ - cgPtyNmb->presInd0.pres = PRSNT_NODEF; - - val = FTDM_PRES_INVALID; - string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.presentation_ind"); - if (!ftdm_strlen_zero(string)) { - val = ftdm_str2ftdm_presentation(string); - } - - if (val == FTDM_PRES_INVALID) { - cgPtyNmb->presInd0.val = caller_data->pres; - } else { - cgPtyNmb->presInd0.val = val; - } - - /* Numbering Plan Indicator */ - cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF; - - val = FTDM_NPI_INVALID; - string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.npi"); - if (!ftdm_strlen_zero(string)) { - val = ftdm_str2ftdm_npi(string); - } - - if (val == FTDM_NPI_INVALID) { - cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan; - } else { - cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, val, IN_NP_UNK); - } - - cgPtyNmb->typeNmb1.pres = PRSNT_NODEF; - - /* Type of Number */ - val = FTDM_TON_INVALID; - string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.ton"); - if (!ftdm_strlen_zero(string)) { - val = ftdm_str2ftdm_ton(string); - } - - if (val == FTDM_TON_INVALID) { - cgPtyNmb->typeNmb1.val = caller_data->cid_num.type; - } else { - cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, val, IN_TON_UNK); - } - return FTDM_SUCCESS; -} - -ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - uint8_t len = strlen(caller_data->dnis.digits); - - if (!len) { - return FTDM_SUCCESS; - } - - cdPtyNmb->eh.pres = PRSNT_NODEF; - - cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF; - cdPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->dnis.plan, IN_NP_UNK); - - cdPtyNmb->typeNmb0.pres = PRSNT_NODEF; - cdPtyNmb->typeNmb0.val = get_trillium_val(ton_codes, caller_data->dnis.type, IN_TON_UNK); - - cdPtyNmb->nmbDigits.pres = PRSNT_NODEF; - cdPtyNmb->nmbDigits.len = len; - - - memcpy(cdPtyNmb->nmbDigits.val, caller_data->dnis.digits, len); - return FTDM_SUCCESS; -} - -ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - uint8_t len = strlen(caller_data->rdnis.digits); - if (!len) { - return FTDM_SUCCESS; - } - - redirNmb->eh.pres = PRSNT_NODEF; - - redirNmb->nmbPlanId.pres = PRSNT_NODEF; - redirNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->rdnis.plan, IN_NP_UNK); - - redirNmb->typeNmb.pres = PRSNT_NODEF; - redirNmb->typeNmb.val = get_trillium_val(ton_codes, caller_data->rdnis.type, IN_TON_UNK); - - redirNmb->nmbDigits.pres = PRSNT_NODEF; - redirNmb->nmbDigits.len = len; - - memcpy(redirNmb->nmbDigits.val, caller_data->rdnis.digits, len); - - return FTDM_SUCCESS; -} - - -ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt) -{ - uint8_t len; - const char *string = NULL; - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - ftdm_bool_t force_send_cid_name = FTDM_FALSE; - - len = strlen(caller_data->cid_name); - if (!len) { - return FTDM_SUCCESS; - } - - string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.send_cid_name"); - if (!ftdm_strlen_zero(string)) { - if (!strcasecmp(string, "no")) { - return FTDM_SUCCESS; - } else if (!strcasecmp(string, "yes")) { - force_send_cid_name = FTDM_TRUE; - } - } - - if (force_send_cid_name == FTDM_FALSE && signal_data->send_cid_name == SNGISDN_OPT_FALSE) { - return FTDM_SUCCESS; - } - - switch(signal_data->cid_name_method) { - case SNGISDN_CID_NAME_FACILITY_IE: -#ifdef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY - /* Note: The Facility IE will be overwritten if user chose to transmit a Raw Facility IE */ - sng_isdn_encode_facility_caller_name(caller_data->cid_name, conEvnt->facilityStr.facilityStr.val, &conEvnt->facilityStr.facilityStr.len); - conEvnt->facilityStr.eh.pres = PRSNT_NODEF; - conEvnt->facilityStr.facilityStr.pres = PRSNT_NODEF; -#endif - break; - case SNGISDN_CID_NAME_USR_USR_IE: - conEvnt->usrUsr.eh.pres = PRSNT_NODEF; - conEvnt->usrUsr.protocolDisc.pres = PRSNT_NODEF; - conEvnt->usrUsr.protocolDisc.val = PD_IA5; /* IA5 chars */ - conEvnt->usrUsr.usrInfo.pres = PRSNT_NODEF; - conEvnt->usrUsr.usrInfo.len = len; - /* in sangoma_brid we used to send usr-usr info as !, - change to previous style if current one does not work */ - memcpy(conEvnt->usrUsr.usrInfo.val, caller_data->cid_name, len); - break; - case SNGISDN_CID_NAME_DISPLAY_IE: - if (signal_data->switchtype == SNGISDN_SWITCH_DMS100) { - conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF; - conEvnt->ntDisplay[0].dispTypeNt.pres = PRSNT_NODEF; - conEvnt->ntDisplay[0].dispTypeNt.val = 0x01; /* Calling Party Name */ - conEvnt->ntDisplay[0].assocInfo.pres = PRSNT_NODEF; - conEvnt->ntDisplay[0].assocInfo.val = 0x03; /* Included */ - conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF; - conEvnt->ntDisplay[0].eh.pres = PRSNT_NODEF; - conEvnt->ntDisplay[0].dispInfo.pres = PRSNT_NODEF; - conEvnt->ntDisplay[0].dispInfo.len = len; - memcpy(conEvnt->ntDisplay[0].dispInfo.val, caller_data->cid_name, len); - } else { - conEvnt->display.eh.pres = PRSNT_NODEF; - conEvnt->display.dispInfo.pres = PRSNT_NODEF; - conEvnt->display.dispInfo.len = len; - memcpy(conEvnt->display.dispInfo.val, caller_data->cid_name, len); - } - break; - default: - break; - } - - return FTDM_SUCCESS; -} - -ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) -{ - const char* clg_subaddr = NULL; - clg_subaddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.calling_subaddr"); - if (!ftdm_strlen_zero(clg_subaddr)) { - unsigned len = strlen (clg_subaddr); - cgPtySad->eh.pres = PRSNT_NODEF; - cgPtySad->typeSad.pres = 1; - cgPtySad->typeSad.val = 0; /* NSAP */ - cgPtySad->oddEvenInd.pres = 1; - cgPtySad->oddEvenInd.val = 0; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Calling Party Subaddress:%s\n", clg_subaddr); - cgPtySad->sadInfo.pres = 1; - cgPtySad->sadInfo.len = len; - memcpy(cgPtySad->sadInfo.val, clg_subaddr, len); - } - return FTDM_SUCCESS; -} - -ftdm_status_t set_called_subaddr(ftdm_channel_t *ftdmchan, CdPtySad *cdPtySad) -{ - const char* cld_subaddr = NULL; - cld_subaddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.called_subaddr"); - if (!ftdm_strlen_zero(cld_subaddr)) { - unsigned len = strlen (cld_subaddr); - cdPtySad->eh.pres = PRSNT_NODEF; - cdPtySad->typeSad.pres = 1; - cdPtySad->typeSad.val = 0; /* NSAP */ - cdPtySad->oddEvenInd.pres = 1; - cdPtySad->oddEvenInd.val = 0; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Called Party Subaddress:%s\n", cld_subaddr); - cdPtySad->sadInfo.pres = 1; - cdPtySad->sadInfo.len = len; - memcpy(cdPtySad->sadInfo.val, cld_subaddr, len); - } - return FTDM_SUCCESS; -} - -ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr) -{ - ftdm_status_t status; - status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (uint8_t*)&(facilityStr->facilityStr.len)); - if (status == FTDM_SUCCESS) { - facilityStr->eh.pres = PRSNT_NODEF; - facilityStr->facilityStr.pres = PRSNT_NODEF; - } - return status; -} - -ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len) -{ - ftdm_size_t len; - uint8_t *mydata; - void *vdata; - - if (ftdm_usrmsg_get_raw_data(ftdmchan->usrmsg, &vdata, &len) == FTDM_SUCCESS) { - mydata = vdata; - if (len > 2 && mydata[0] == SNGISDN_Q931_FACILITY_IE_ID) { - len = mydata[1]; - memcpy(data, &mydata[2], len); - *data_len = len; - return FTDM_SUCCESS; - } - } - return FTDM_FAIL; -} - -ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind) -{ - const char *str = NULL; - int descr = prog_ind.descr; - int loc = prog_ind.loc; - - str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.descr"); - if (!ftdm_strlen_zero(str)) { - /* User wants to override progress indicator */ - descr = ftdm_str2ftdm_sngisdn_progind_descr(str); - } - - if (descr == SNGISDN_PROGIND_DESCR_INVALID) { - /* User does not want to send progress indicator */ - return FTDM_SUCCESS; - } - - str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.loc"); - if (!ftdm_strlen_zero(str)) { - loc = ftdm_str2ftdm_sngisdn_progind_loc(str); - } - if (loc == SNGISDN_PROGIND_LOC_INVALID) { - loc = SNGISDN_PROGIND_LOC_USER; - } - - progInd->eh.pres = PRSNT_NODEF; - progInd->codeStand0.pres = PRSNT_NODEF; - progInd->codeStand0.val = IN_CSTD_CCITT; - - progInd->progDesc.pres = PRSNT_NODEF; - switch(descr) { - case SNGISDN_PROGIND_DESCR_NETE_ISDN: - progInd->progDesc.val = IN_PD_NOTETEISDN; - break; - case SNGISDN_PROGIND_DESCR_DEST_NISDN: - progInd->progDesc.val = IN_PD_DSTNOTISDN; - break; - case SNGISDN_PROGIND_DESCR_ORIG_NISDN: - progInd->progDesc.val = IN_PD_ORGNOTISDN; - break; - case SNGISDN_PROGIND_DESCR_RET_ISDN: - progInd->progDesc.val = IN_PD_CALLRET; - break; - case SNGISDN_PROGIND_DESCR_SERV_CHANGE: - /* Trillium defines do not match ITU-T Q931 Progress descriptions, - indicate a delayed response for now */ - progInd->progDesc.val = IN_PD_DELRESP; - break; - case SNGISDN_PROGIND_DESCR_IB_AVAIL: - progInd->progDesc.val = IN_PD_IBAVAIL; - break; - default: - ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind description:%d\n", descr); - progInd->progDesc.val = IN_PD_NOTETEISDN; - break; - } - - progInd->location.pres = PRSNT_NODEF; - switch (loc) { - case SNGISDN_PROGIND_LOC_USER: - progInd->location.val = IN_LOC_USER; - break; - case SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR: - progInd->location.val = IN_LOC_PRIVNETLU; - break; - case SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR: - progInd->location.val = IN_LOC_PUBNETLU; - break; - case SNGISDN_PROGIND_LOC_TRANSIT_NET: - progInd->location.val = IN_LOC_TRANNET; - break; - case SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR: - progInd->location.val = IN_LOC_PUBNETRU; - break; - case SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR: - progInd->location.val = IN_LOC_PRIVNETRU; - break; - case SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW: - progInd->location.val = IN_LOC_NETINTER; - break; - default: - ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind location:%d\n", loc); - progInd->location.val = IN_LOC_USER; - } - return FTDM_SUCCESS; -} - -ftdm_status_t set_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac) -{ - const char *str = NULL; - - str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.spec"); - if (ftdm_strlen_zero(str)) { - /* Network-specific facility specification is mandatory, cannot send IE - without it */ - return FTDM_SUCCESS; - } else { - ftdm_sngisdn_netspecfac_spec_t spec = ftdm_str2ftdm_sngisdn_netspecfac_spec(str); - - netFac->eh.pres = PRSNT_NODEF; - netFac->netFacSpec.pres = PRSNT_NODEF; - - if (spec == SNGISDN_NETSPECFAC_SPEC_INVALID) { - int byte = 0; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Non-standard NSF specified:%s\n", str); - - if (sscanf(str, "%x", &byte) == 1) { - netFac->netFacSpec.val[0] = byte & 0xFF; - } - - netFac->netFacSpec.len = 1; - } else { - /* User is using one of the pre-specified NSF's */ - netFac->netFacSpec.val[0] = get_trillium_val(nsf_spec_codes, spec, 0x00); - netFac->netFacSpec.len = 1; - } - } - - netFac->lenNetId.pres = PRSNT_NODEF; - netFac->lenNetId.val = 0; - - str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.type"); - if (!ftdm_strlen_zero(str)) { - netFac->typeNetId.pres = PRSNT_NODEF; - netFac->typeNetId.val = ftdm_str2ftdm_sngisdn_netspecfac_type(str); - } - - str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.plan"); - if (!ftdm_strlen_zero(str)) { - netFac->netIdPlan.pres = PRSNT_NODEF; - netFac->netIdPlan.val = ftdm_str2ftdm_sngisdn_netspecfac_plan(str); - } - - if (netFac->netIdPlan.pres == PRSNT_NODEF || netFac->typeNetId.pres == PRSNT_NODEF) { - netFac->lenNetId.val++; - } - - str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.ident"); - if (!ftdm_strlen_zero(str)) { - netFac->lenNetId.val++; - - netFac->netId.pres = PRSNT_NODEF; - memcpy(netFac->netId.val, str, strlen(str)); - } - - return FTDM_SUCCESS; -} - -ftdm_status_t set_user_to_user_ie(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr) -{ - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - - if (sngisdn_info->transfer_data.type == SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA) { - usrUsr->eh.pres = PRSNT_NODEF; - - usrUsr->protocolDisc.pres = PRSNT_NODEF; - usrUsr->protocolDisc.val = 0x08; - usrUsr->usrInfo.pres = PRSNT_NODEF; - usrUsr->usrInfo.len = strlen(sngisdn_info->transfer_data.tdata.att_courtesy_vru.data); - memcpy(usrUsr->usrInfo.val, sngisdn_info->transfer_data.tdata.att_courtesy_vru.data, usrUsr->usrInfo.len); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending AT&T Transfer data len:%d\n", usrUsr->usrInfo.len); - - return FTDM_SUCCESS; - } - - return FTDM_SUCCESS; -} - -ftdm_status_t set_cause_ie(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn) -{ - - causeDgn->eh.pres = PRSNT_NODEF; - causeDgn->location.pres = PRSNT_NODEF; - causeDgn->location.val = IN_LOC_PRIVNETLU; - causeDgn->codeStand3.pres = PRSNT_NODEF; - causeDgn->codeStand3.val = IN_CSTD_CCITT; - causeDgn->causeVal.pres = PRSNT_NODEF; - causeDgn->causeVal.val = ftdmchan->caller_data.hangup_cause; - causeDgn->recommend.pres = NOTPRSNT; - causeDgn->dgnVal.pres = NOTPRSNT; - return FTDM_SUCCESS; -} - -ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; - if (!ftdmchan) { - return FTDM_SUCCESS; - } - - ftdm_set_flag(sngisdn_info, FLAG_SENT_CHAN_ID); - - chanId->eh.pres = PRSNT_NODEF; - chanId->prefExc.pres = PRSNT_NODEF; - chanId->prefExc.val = IN_PE_EXCLSVE; - chanId->dChanInd.pres = PRSNT_NODEF; - chanId->dChanInd.val = IN_DSI_NOTDCHAN; - chanId->intIdentPres.pres = PRSNT_NODEF; - chanId->intIdentPres.val = IN_IIP_IMPLICIT; - - if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { - - /* BRI only params */ - chanId->intType.pres = PRSNT_NODEF; - chanId->intType.val = IN_IT_BASIC; - chanId->infoChanSel.pres = PRSNT_NODEF; - chanId->infoChanSel.val = ftdmchan->physical_chan_id; - } else { - if (signal_data->nfas.trunk) { - chanId->intIdentPres.val = IN_IIP_EXPLICIT; - chanId->intIdent.pres = PRSNT_NODEF; - chanId->intIdent.val = signal_data->nfas.interface_id; - } - - chanId->intType.pres = PRSNT_NODEF; - chanId->intType.val = IN_IT_OTHER; - chanId->infoChanSel.pres = PRSNT_NODEF; - chanId->infoChanSel.val = IN_ICS_B1CHAN; - chanId->chanMapType.pres = PRSNT_NODEF; - chanId->chanMapType.val = IN_CMT_BCHAN; - chanId->nmbMap.pres = PRSNT_NODEF; - chanId->nmbMap.val = IN_NM_CHNNMB; - chanId->codeStand1.pres = PRSNT_NODEF; - chanId->codeStand1.val = IN_CSTD_CCITT; - chanId->chanNmbSlotMap.pres = PRSNT_NODEF; - chanId->chanNmbSlotMap.len = 1; - chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; - } - - return FTDM_SUCCESS; -} - -ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - bearCap->eh.pres = PRSNT_NODEF; - bearCap->infoTranCap.pres = PRSNT_NODEF; - bearCap->infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability); - - bearCap->codeStand0.pres = PRSNT_NODEF; - bearCap->codeStand0.val = IN_CSTD_CCITT; - bearCap->infoTranRate0.pres = PRSNT_NODEF; - bearCap->infoTranRate0.val = IN_ITR_64KBIT; - bearCap->tranMode.pres = PRSNT_NODEF; - bearCap->tranMode.val = IN_TM_CIRCUIT; - - bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; - bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - - switch (signal_data->switchtype) { - case SNGISDN_SWITCH_NI2: - case SNGISDN_SWITCH_4ESS: - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_DMS100: - case SNGISDN_SWITCH_INSNET: - if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to u-law\n"); - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; - } - break; - case SNGISDN_SWITCH_EUROISDN: - case SNGISDN_SWITCH_QSIG: - if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to a-law\n"); - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; - } - break; - } - - bearCap->lyr1Ident.pres = PRSNT_NODEF; - bearCap->lyr1Ident.val = IN_L1_IDENT; - - return FTDM_SUCCESS; -} - -ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd) -{ - rstInd->eh.pres = PRSNT_NODEF; - rstInd->rstClass.pres = PRSNT_NODEF; - rstInd->rstClass.val = IN_CL_INDCHAN; - return FTDM_SUCCESS; -} - -ftdm_status_t set_not_ind_ie(ftdm_channel_t *ftdmchan, NotInd *notInd) -{ - notInd->eh.pres = PRSNT_NODEF; - notInd->notDesc.pres = PRSNT_NODEF; - notInd->notDesc.val = 0x71; /* Call information event */ - return FTDM_SUCCESS; -} - -void sngisdn_t3_timeout(void *p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Timer T3 expired (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); - ftdm_mutex_lock(ftdmchan->mutex); - if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)){ - /* PHY layer timed-out, need to clear the call */ - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Failed to Wake-Up line (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); - - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NO_ROUTE_DESTINATION; - ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); - ftdm_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } - ftdm_mutex_unlock(ftdmchan->mutex); -} - - -void sngisdn_delayed_dl_req(void *p_signal_data) -{ - ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data; - ftdm_span_t *span = signal_data->ftdm_span; - - if (!signal_data->dl_request_pending) { - return; - } - - ftdm_span_get_sig_status(span, &sigstatus); - if (sigstatus == FTDM_SIG_STATE_UP) { - signal_data->dl_request_pending = 0; - return; - } - - sngisdn_snd_dl_req(span->channels[1]); - ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 4000, sngisdn_delayed_dl_req, (void*) signal_data, NULL); - - return; -} - -void sngisdn_restart_timeout(void *p_signal_data) -{ - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data; - ftdm_span_t *span = signal_data->ftdm_span; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - - ftdm_log(FTDM_LOG_DEBUG, "s%s:Did not receive a RESTART from remote switch in %d ms - restarting\n", span->name, signal_data->restart_timeout); - - chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - ftdm_mutex_lock(ftdmchan->mutex); - if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESET); - } - ftdm_mutex_unlock(ftdmchan->mutex); - } - } - return; -} - -void sngisdn_delayed_setup(void *p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - ftdm_mutex_lock(ftdmchan->mutex); - sngisdn_snd_setup(ftdmchan); - ftdm_mutex_unlock(ftdmchan->mutex); - return; -} - -void sngisdn_delayed_release_nfas(void *p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - ftdm_mutex_lock(ftdmchan->mutex); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed RELEASE (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId); - - sngisdn_snd_release(ftdmchan, 0); - - ftdm_mutex_unlock(ftdmchan->mutex); - return; -} - -void sngisdn_delayed_release(void *p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - ftdm_mutex_lock(ftdmchan->mutex); - - if (ftdm_test_flag(sngisdn_info, FLAG_DELAYED_REL)) { - ftdm_clear_flag(sngisdn_info, FLAG_DELAYED_REL); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed RELEASE (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); - - sngisdn_snd_release(ftdmchan, 1); - clear_call_glare_data(sngisdn_info); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call was already released (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); - } - ftdm_mutex_unlock(ftdmchan->mutex); - return; -} - -void sngisdn_delayed_connect(void *p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - ftdm_mutex_lock(ftdmchan->mutex); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed CONNECT (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); - - sngisdn_snd_connect(ftdmchan); - ftdm_mutex_unlock(ftdmchan->mutex); - return; -} - -void sngisdn_delayed_disconnect(void *p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - ftdm_mutex_lock(ftdmchan->mutex); - if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST || ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); - - sngisdn_snd_disconnect(ftdmchan); - if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST) { - ftdm_channel_t *close_chan = ftdmchan; - ftdm_channel_close(&close_chan); - } - } - - ftdm_mutex_unlock(ftdmchan->mutex); - return; -} - -void sngisdn_facility_timeout(void *p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - ftdm_mutex_lock(ftdmchan->mutex); - if (ftdmchan->state == FTDM_CHANNEL_STATE_GET_CALLERID) { - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Facility timeout reached proceeding with call (suId:%d suInstId:%u spInstId:%u)\n", - signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId); - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - - ftdm_mutex_unlock(ftdmchan->mutex); - return; -} - -ftdm_status_t sngisdn_check_free_ids(void) -{ - unsigned i; - unsigned j; - ftdm_log(FTDM_LOG_INFO, "Checking suInstId's\n"); - for(j=1;j<=MAX_VARIANTS;j++) { - if (g_sngisdn_data.ccs[j].config_done) { - for(i=1;isignal_data; - - memset(&sts, 0, sizeof(sts)); - sng_isdn_phy_stats(sngisdn_dchan(signal_data)->link_id , &sts); - - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, " Span:%s", span->name); - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, " Performance Counters"); - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, "RX Packets:\t%u\tTX Packets:\t%u\tEvents:%u\n", sts.t.sts.rx_packets, sts.t.sts.tx_packets, sts.t.sts.rx_events); - stream->write_function(stream, "RX Bytes:\t%u\tTX Bytes:\t%u\n\n", sts.t.sts.rx_bytes, sts.t.sts.tx_bytes); - stream->write_function(stream, "TX Queue:\t%u/%u\tRX Queue:\t%u/%u\tEvents Queue:\t%u/%u\n", - sts.t.sts.num_frames_in_tx_queue,sts.t.sts.tx_queue_len, - sts.t.sts.num_frames_in_rx_queue, sts.t.sts.rx_queue_len, - sts.t.sts.rx_events_in_queue, sts.t.sts.event_queue_len); - - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, " Errors"); - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, "RX Errors:\t%u\tTX Errors:\t%u\n", sts.t.sts.rx_errors, sts.t.sts.tx_errors); - stream->write_function(stream, "RX Dropped:\t%u\tTX Dropped:\t%u\tEvents Dropped:\t%u\n", sts.t.sts.rx_dropped, sts.t.sts.tx_dropped,sts.t.sts.rx_events_dropped); - - - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, " RX Errors Details"); - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, "CRC:\t\t%u\tFrame:\t\t%u\tOverruns:\t%u\n", sts.t.sts.rx_crc_errors, sts.t.sts.rx_frame_errors, sts.t.sts.rx_over_errors); - stream->write_function(stream, "Fifo:\t\t%u\tAborts:\t\t%u\tMissed:\t\t%u\n", sts.t.sts.rx_fifo_errors, sts.t.sts.rx_hdlc_abort_counter, sts.t.sts.rx_missed_errors); - stream->write_function(stream, "Length:\t\t%u\n", sts.t.sts.rx_length_errors); - - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, " TX Errors Details"); - stream->write_function(stream, "\n---------------------------------------------------------------------\n"); - stream->write_function(stream, "Aborted:\t%u\tFifo:\t\t%u\tCarrier:\t%u\n", sts.t.sts.tx_aborted_errors, sts.t.sts.tx_fifo_errors, sts.t.sts.tx_carrier_errors); - return FTDM_SUCCESS; -} - - -ftdm_status_t sngisdn_show_span(ftdm_stream_handle_t *stream, ftdm_span_t *span) -{ - ftdm_signaling_status_t sigstatus; - ftdm_alarm_flag_t alarmbits; - ftdm_channel_t *fchan; - alarmbits = FTDM_ALARM_NONE; - fchan = ftdm_span_get_channel(span, 1); - if (fchan) { - ftdm_channel_get_alarms(fchan, &alarmbits); - } - - ftdm_span_get_sig_status(span, &sigstatus); - stream->write_function(stream, "span:%s physical:%s signalling:%s\n", - span->name, alarmbits ? "ALARMED" : "OK", - ftdm_signaling_status2str(sigstatus)); - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_show_spans(ftdm_stream_handle_t *stream) -{ - int i; - for(i=1;i<=MAX_L1_LINKS;i++) { - if (g_sngisdn_data.spans[i]) { - sngisdn_show_span(stream, g_sngisdn_data.spans[i]->ftdm_span); - } - } - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_add_var(sngisdn_chan_data_t *sngisdn_info, const char* var, const char* val) -{ - char *t_name = 0, *t_val = 0; - if (!var || !val) { - return FTDM_FAIL; - } - if (!sngisdn_info->variables) { - /* initialize on first use */ - sngisdn_info->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - ftdm_assert_return(sngisdn_info->variables, FTDM_FAIL, "Failed to create hash table\n"); - } - t_name = ftdm_strdup(var); - t_val = ftdm_strdup(val); - hashtable_insert(sngisdn_info->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); - return FTDM_SUCCESS; -} - -ftdm_status_t sngisdn_add_raw_data(sngisdn_chan_data_t *sngisdn_info, uint8_t* data, ftdm_size_t data_len) -{ - ftdm_assert_return(!sngisdn_info->raw_data, FTDM_FAIL, "Overwriting existing raw data\n"); - - sngisdn_info->raw_data = ftdm_calloc(1, data_len); - ftdm_assert_return(sngisdn_info->raw_data, FTDM_FAIL, "Failed to allocate raw data\n"); - - memcpy(sngisdn_info->raw_data, data, data_len); - sngisdn_info->raw_data_len = data_len; - return FTDM_SUCCESS; -} - -void sngisdn_send_signal(sngisdn_chan_data_t *sngisdn_info, ftdm_signal_event_t event_id) -{ - ftdm_sigmsg_t sigev; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - - memset(&sigev, 0, sizeof(sigev)); - - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - sigev.event_id = event_id; - - if (sngisdn_info->variables) { - /* - * variables now belongs to the ftdm core, and - * will be cleared after sigev is processed by user. Set - * local pointer to NULL so we do not attempt to - * destroy it */ - sigev.variables = sngisdn_info->variables; - sngisdn_info->variables = NULL; - } - - if (sngisdn_info->raw_data) { - /* - * raw_data now belongs to the ftdm core, and - * will be cleared after sigev is processed by user. Set - * local pointer to NULL so we do not attempt to - * destroy it */ - - sigev.raw.data = sngisdn_info->raw_data; - sigev.raw.len = sngisdn_info->raw_data_len; - - sngisdn_info->raw_data = NULL; - sngisdn_info->raw_data_len = 0; - } - if (event_id == FTDM_SIGEVENT_TRANSFER_COMPLETED) { - sigev.ev_data.transfer_completed.response = sngisdn_info->transfer_data.response; - } - ftdm_span_send_signal(ftdmchan->span, &sigev); -} - -sngisdn_span_data_t *sngisdn_dchan(sngisdn_span_data_t *signal_data) -{ - if (!signal_data) { - return NULL; - } - - if (!signal_data->nfas.trunk) { - return signal_data; - } - return signal_data->nfas.trunk->dchan; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c deleted file mode 100644 index 56797fbf9c..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c +++ /dev/null @@ -1,996 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" -#include "ftmod_sangoma_isdn_trace.h" - -#define OCTET(x) (ieData[x-1] & 0xFF) -#define MAX_DECODE_STR_LEN 2000 - -typedef struct sngisdn_trace_info -{ - uint8_t call_ref_flag; - uint16_t call_ref; - uint8_t msgtype; - uint8_t bchan_no; - ftdm_trace_dir_t dir; -} sngisdn_frame_info_t; - -void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end); -uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start); -static ftdm_status_t sngisdn_map_call(sngisdn_span_data_t *signal_data, sngisdn_frame_info_t frame_info, ftdm_channel_t **found); -static ftdm_status_t sngisdn_get_frame_info(uint8_t *data, uint32_t data_len, ftdm_trace_dir_t dir, sngisdn_frame_info_t *frame_info); - -uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi); -char* get_code_2_str(int code, struct code2str *pCodeTable); -void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len); -void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len); - - -char* get_code_2_str(int code, struct code2str *pCodeTable) -{ - struct code2str* pCode2txt; - pCode2txt = pCodeTable; - while(pCode2txt) { - if(pCode2txt->code >= 0) { - if (pCode2txt->code == code) { - return pCode2txt->text; - } - pCode2txt++; - } else { - /* This is the default value from the table */ - return pCode2txt->text; - } - } - return (char*)"unknown"; -} - - -uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi) -{ - if (!bitLo || !bitHi) { - return 0; - } - if (bitLo > bitHi) { - return 0; - } - - bitLo--; - bitHi--; - - switch(bitHi - bitLo) { - case 0: - return (octet >> bitLo) & 0x01; - case 1: - return (octet >> bitLo) & 0x03; - case 2: - return (octet >> bitLo) & 0x07; - case 3: - return (octet >> bitLo) & 0x0F; - case 4: - return (octet >> bitLo) & 0x1F; - case 5: - return (octet >> bitLo) & 0x3F; - case 6: - return (octet >> bitLo) & 0x7F; - case 7: - return (octet >> bitLo) & 0xFF; - } - return 0; -} - -void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) -{ - char *data_str = ftdm_calloc(1,500); /* TODO Find a proper size */ - sngisdn_decode_q921(data_str, data, data_len); - ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q921] %s FRAME %s:\n%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str); - ftdm_safe_free(data_str); -} - -void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) -{ - uint8_t *raw_data; - ftdm_sigmsg_t sigev; - - memset(&sigev, 0, sizeof(sigev)); - - sigev.span_id = signal_data->ftdm_span->span_id; - sigev.chan_id = signal_data->dchan->chan_id; - sigev.channel = signal_data->dchan; - sigev.event_id = FTDM_SIGEVENT_TRACE_RAW; - - sigev.ev_data.trace.dir = dir; - sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q921; - - raw_data = ftdm_malloc(data_len); - ftdm_assert(raw_data, "Failed to malloc"); - - memcpy(raw_data, data, data_len); - sigev.raw.data = raw_data; - sigev.raw.len = data_len; - ftdm_span_send_signal(signal_data->ftdm_span, &sigev); -} - -void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len) -{ - uint32_t str_len; - uint32_t i; - uint8_t sapi, cr, ea, tei, ns, nr, pf, p, cmd; - uint8_t frame_format = 0; - - str_len = 0; - - if(data_len >= 2) { - switch ((int)data[2] & 0x03) { - case 0: case 2: - frame_format = I_FRAME; - break; - case 1: - frame_format = S_FRAME; - break; - case 3: - frame_format = U_FRAME; - break; - } - } - - str_len+= sprintf(&str[str_len], " format: %s\n", - get_code_2_str(frame_format, dcodQ921FrameFormatTable)); - - for(i=0; i < data_len; i++) { - switch(i) { - case 0: // Octet 2 - sapi = (uint8_t)((data[i]>>2) & 0x3F); - cr = (uint8_t)((data[i]>>1) & 0x1); - ea = (uint8_t)(data[i] & 0x1); - str_len+= sprintf(&str[str_len], " sapi: %03d c/r: %01d ea: %01d\n", sapi, cr, ea); - break; - case 1: - tei = (uint8_t)((data[i]>>1) & 0x7F); - ea = (uint8_t)(data[i] & 0x1); - str_len+= sprintf(&str[str_len], " tei: %03d ea: %01d\n", tei, ea); - break; - case 2: - switch(frame_format) { - case I_FRAME: - ns = (uint8_t)((data[i]>>1) & 0x7F); - nr = (uint8_t)((data[i+1]>>1) & 0x7F); - p = (uint8_t)(data[i+1] & 0x01); - str_len+= sprintf(&str[str_len], " n(s): %03d\n n(r): %03d p: %01d\n", ns, nr, p); - break; - case S_FRAME: - nr = (uint8_t)((data[i+1]>>1) & 0x7F); - pf = (uint8_t)(data[i+1] & 0x01); - str_len+= sprintf(&str[str_len], " n(r): %03d p/f: %01d\n", nr, pf); - - cmd = (uint8_t)((data[i]>>2) & 0x03); - str_len+= sprintf(&str[str_len], " cmd: %s\n", get_code_2_str(cmd, dcodQ921SupervisoryCmdTable)); - - break; - case U_FRAME: - pf = (uint8_t)((data[i]>>4) & 0x01); - str_len+= sprintf(&str[str_len], " p/f: %01d\n", pf); - - cmd = (uint8_t)((data[i]>>2) & 0x03); - cmd |= (uint8_t)((data[i]>>5) & 0x07); - - str_len+= sprintf(&str[str_len], " cmd: %s\n", get_code_2_str(cmd, dcodQ921UnnumberedCmdTable)); - break; - } - break; - } - } - - print_hex_dump(str, &str_len, (uint8_t*) data, 0, data_len); - return; -} - - -void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) -{ - char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */ - sngisdn_decode_q931(data_str, data, data_len); - ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q931] %s FRAME %s:\n%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str); - ftdm_safe_free(data_str); -} - -void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) -{ - uint8_t *raw_data; - ftdm_sigmsg_t sigev; - ftdm_channel_t *ftdmchan = NULL; - sngisdn_frame_info_t frame_info; - - memset(&sigev, 0, sizeof(sigev)); - - /* Note: Mapped raw trace assume only exclusive b-channel selection is used. i.e the b-channel selected on outgoing SETUP is always used for the call */ - - if (sngisdn_get_frame_info(data, data_len, dir, &frame_info) == FTDM_SUCCESS) { - if (sngisdn_map_call(signal_data, frame_info, &ftdmchan) == FTDM_SUCCESS) { - sigev.call_id = ftdmchan->caller_data.call_id; - sigev.span_id = ftdmchan->physical_span_id; - sigev.chan_id = ftdmchan->physical_chan_id; - sigev.channel = ftdmchan; - } else { - /* We could not map the channel, but at least set the span */ - if (signal_data->ftdm_span->channels[1]) { - sigev.span_id = signal_data->ftdm_span->channels[1]->physical_span_id; - } - } - sigev.event_id = FTDM_SIGEVENT_TRACE_RAW; - - sigev.ev_data.trace.dir = dir; - sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q931; - - raw_data = ftdm_malloc(data_len); - ftdm_assert(raw_data, "Failed to malloc"); - - memcpy(raw_data, data, data_len); - sigev.raw.data = raw_data; - sigev.raw.len = data_len; - ftdm_span_send_signal(signal_data->ftdm_span, &sigev); - } -} - -void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len) -{ - uint32_t str_len; - uint8_t prot_disc, callRefFlag; - uint16_t lenCallRef, c, i; - uint8_t current_codeset = 0; - - str_len = 0; - - /* Decode Protocol Discrimator */ - prot_disc = (uint8_t)data[0]; - str_len += sprintf(&str[str_len], " Prot Disc:%s (0x%02x)\n", get_code_2_str(prot_disc, dcodQ931ProtDiscTable), prot_disc); - - /* Decode Call Reference */ - lenCallRef = (uint8_t) (data[1] & 0x0F); - - str_len += sprintf(&str[str_len], " Call Ref:"); - c=2; - callRefFlag = get_bits(data[c], 8,8); - for(i=0; i<(2*lenCallRef);i++) { - if(i==0) { - str_len += sprintf(&str[str_len], "%s%s", - get_code_2_str((uint8_t)(data[c] & 0x70), dcodQ931CallRefHiTable), - get_code_2_str((uint8_t)(data[c] & 0x0F), dcodQ931CallRefLoTable)); - } else { - str_len += sprintf(&str[str_len], "%s%s", - get_code_2_str((uint8_t)(data[c] & 0xF0), dcodQ931CallRefHiTable), - get_code_2_str((uint8_t)(data[c] & 0x0F), dcodQ931CallRefLoTable)); - } - - i=i+1; - c=c+1; - } - str_len += sprintf(&str[str_len], " (%s side)\n", callRefFlag?"Destination":"Originating"); - - /* Decode message type */ - str_len+= sprintf(&str[str_len], " Type:%s (0x%x)\n", get_code_2_str((int)(data[2+lenCallRef] & 0xFF), dcodQ931MsgTypeTable), (int)(data[2+lenCallRef] & 0xFF)); - - /* go through rest of data and look for important info */ - for(i=3+lenCallRef; i < data_len; i++) { - switch (data[i] & 0xF8) { - case Q931_LOCKING_SHIFT: - current_codeset = (data[i] & 0x7); - str_len+= sprintf(&str[str_len], "Codeset shift to %d (locking)\n", current_codeset); - continue; - case Q931_NON_LOCKING_SHIFT: - current_codeset = (data[i] & 0x7); - str_len+= sprintf(&str[str_len], "Codeset shift to %d (non-locking)\n", current_codeset); - continue; - } - i+= sngisdn_decode_ie(str, &str_len, current_codeset, data, i); - } - print_hex_dump(str, &str_len, (uint8_t*) data, 0, data_len); - return; -} - -uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start) -{ - unsigned char* ieData; - uint8_t ieId; - uint32_t len = 0; - int index_end; - - ieData = (unsigned char*) &data[index_start]; - - ieId = OCTET(1); - len = OCTET(2); - index_end = index_start+len+1; - - *str_len += sprintf(&str[*str_len], " %s:", get_code_2_str(data[index_start], dcodQ931IEIDTable)); - switch(ieId) { - case PROT_Q931_IE_BEARER_CAP: - { - uint8_t codingStandard, infTransferCap, infTransferRate, usrL1Prot; - /*uint8_t transferMode;*/ - - codingStandard = get_bits(OCTET(3),6,7); - infTransferCap = get_bits(OCTET(3),1,5); - /*transferMode = get_bits(OCTET(4),6,7);*/ - infTransferRate = get_bits(OCTET(4),1,5); - usrL1Prot = get_bits(OCTET(5),1,5); - - *str_len+= sprintf(&str[*str_len], "Coding:%s(%d) TransferCap:%s(%d) TransferRate:%s(%d) L1Prot:%s(%d)\n", - get_code_2_str(codingStandard, dcodQ931BcCodingStandardTable), codingStandard, - get_code_2_str(infTransferCap, dcodQ931BcInfTransferCapTable), infTransferCap, - get_code_2_str(infTransferRate, dcodQ931BcInfTransferRateTable), infTransferRate, - get_code_2_str(usrL1Prot, dcodQ931BcusrL1ProtTable), usrL1Prot); - } - break; - case PROT_Q931_IE_CAUSE: - { - uint8_t codingStandard, location, cause,diagOct = 5; - codingStandard = get_bits(OCTET(3),6,7); - location = get_bits(OCTET(3),1,4); - - cause = get_bits(OCTET(4),1,7); - - *str_len+= sprintf(&str[*str_len], "coding:%s(%d) location:%s(%d) val:%s(%d)\n", - get_code_2_str(codingStandard, dcodQ931BcCodingStandardTable), codingStandard, - get_code_2_str(location,dcodQ931IelocationTable), location, - get_code_2_str(cause, dcodQ931CauseCodeTable), - cause); - switch(cause) { - case PROT_Q931_RELEASE_CAUSE_IE_NOT_EXIST: - while(diagOct++ < len) { - *str_len+= sprintf(&str[*str_len], " %d:IE %s(0x%02x)\n", - diagOct, - get_code_2_str(OCTET(diagOct), dcodQ931IEIDTable), - OCTET(diagOct)); - } - break; - case PROT_Q931_RELEASE_CAUSE_WRONG_CALL_STATE: - while(diagOct++ < len) { - *str_len+= sprintf(&str[*str_len], " %d:Message %s(0x%02x)\n", - diagOct, - get_code_2_str(OCTET(diagOct), dcodQ931MsgTypeTable), - OCTET(diagOct)); - } - break; - case PROT_Q931_RECOVERY_ON_TIMER_EXPIRE: - *str_len+= sprintf(&str[*str_len], " Timer T\n"); - while(diagOct++ < len) { - if(OCTET(diagOct) >= ' ' && OCTET(diagOct) < 0x7f) { - *str_len+= sprintf(&str[*str_len], "%c", OCTET(diagOct)); - } else { - *str_len+= sprintf(&str[*str_len], "."); - } - } - break; - default: - while(diagOct++ < len) { - *str_len+= sprintf(&str[*str_len], " %d: 0x%02x\n", - diagOct, - OCTET(diagOct)); - } - break; - } - } - break; - case PROT_Q931_IE_CHANNEL_ID: - { - uint8_t infoChannelSelection=0; - uint8_t prefExclusive=0; - uint8_t ifaceIdPresent=0; - /* uint8_t ifaceIdentifier = 0; */ /* octet_3_1 */ - uint8_t chanType=0, numberMap=0; - /* uint8_t codingStandard=0; */ - uint8_t channelNo = 0; - - infoChannelSelection = get_bits(OCTET(3),1,2); - prefExclusive = get_bits(OCTET(3),4,4); - ifaceIdPresent = get_bits(OCTET(3),7,7); - - if (ifaceIdPresent) { - /*ifaceIdentifier= get_bits(OCTET(4),1,7);*/ - chanType = get_bits(OCTET(5),1,4); - numberMap = get_bits(OCTET(5),5,5); - /*codingStandard = get_bits(OCTET(5),6,7);*/ - channelNo = get_bits(OCTET(6),1,7); - } else { - chanType = get_bits(OCTET(4),1,4); - numberMap = get_bits(OCTET(4),5,5); - /*codingStandard = get_bits(OCTET(4),6,7);*/ - channelNo = get_bits(OCTET(5),1,7); - } - - if (numberMap) { - *str_len+= sprintf(&str[*str_len], " MAP:%s ", get_code_2_str(infoChannelSelection, dcodQ931InfoChannelSelTable)); - } else { - *str_len+= sprintf(&str[*str_len], "No:%d ", channelNo); - } - - *str_len+= sprintf(&str[*str_len], "Type:%s(%d) %s ", get_code_2_str(chanType,dcodQ931ChanTypeTable), chanType, (numberMap)? "Map":""); - *str_len+= sprintf(&str[*str_len], "%s/%s \n", - (prefExclusive)? "Exclusive":"Preferred", - (ifaceIdPresent)? "Explicit":"Implicit"); - } - break; - case PROT_Q931_IE_CALLING_PARTY_NUMBER: - { - uint8_t plan, type, screening = 0, presentation = 0, callingNumOct, j; - uint8_t screeningEnabled = 0, presentationEnabled = 0; - char callingNumDigits[32]; - memset(callingNumDigits, 0, sizeof(callingNumDigits)); - - plan = get_bits(OCTET(3),1,4); - type = get_bits(OCTET(3),5,7); - - if(!get_bits(OCTET(3),8,8)) { - screening = get_bits(OCTET(4),1,2); - presentation = get_bits(OCTET(4),6,7); - screeningEnabled = 1; - presentationEnabled = 1; - callingNumOct = 4; - } else { - callingNumOct = 3; - } - if(len >= sizeof(callingNumDigits)) { - len = sizeof(callingNumDigits)-1; - } - j = 0; - while(callingNumOct++ <= len+1) { - callingNumDigits[j++]=ia5[get_bits(OCTET(callingNumOct),1,4)][get_bits(OCTET(callingNumOct),5,8)]; - } - callingNumDigits[j]='\0'; - *str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)", - - callingNumDigits, j, - get_code_2_str(plan, dcodQ931NumberingPlanTable), plan, - get_code_2_str(type, dcodQ931TypeofNumberTable), type); - - if (presentationEnabled||screeningEnabled) { - *str_len+= sprintf(&str[*str_len], "scr:%s(%d) pres:%s(%d)\n", - get_code_2_str(screening, dcodQ931ScreeningTable), screening, - get_code_2_str(presentation, dcodQ931PresentationTable), presentation); - } else { - *str_len+= sprintf(&str[*str_len], "\n"); - } - } - break; - - case PROT_Q931_IE_CALLED_PARTY_NUMBER: - { - uint8_t plan, type, calledNumOct,j; - char calledNumDigits[32]; - memset(calledNumDigits, 0, sizeof(calledNumDigits)); - plan = get_bits(OCTET(3),1,4); - type = get_bits(OCTET(3),5,7); - - if(len >= sizeof(calledNumDigits)) { - len = sizeof(calledNumDigits)-1; - } - calledNumOct = 3; - j = 0; - while(calledNumOct++ <= len+1) { - calledNumDigits[j++]=ia5[get_bits(OCTET(calledNumOct),1,4)][get_bits(OCTET(calledNumOct),5,8)]; - } - calledNumDigits[j]='\0'; - *str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)\n", - calledNumDigits, j, - get_code_2_str(plan, dcodQ931NumberingPlanTable), plan, - get_code_2_str(type, dcodQ931TypeofNumberTable), type); - } - break; - case PROT_Q931_IE_REDIRECTING_NUMBER: //rdnis - { - uint8_t plan, type, screening = 0, presentation = 0, reason = 0, rdnisOct,j; - uint8_t screeningEnabled = 0, presentationEnabled = 0, reasonEnabled = 0; - char rdnis_string[32]; - memset(rdnis_string, 0, sizeof(rdnis_string)); - rdnisOct = 5; - plan = get_bits(OCTET(3),1,4); - type = get_bits(OCTET(3),5,7); - - if(!get_bits(OCTET(3),8,8)) { //Oct 3a exists - rdnisOct++; - screening = get_bits(OCTET(4),1,2); - presentation = get_bits(OCTET(4),6,7); - screeningEnabled = 1; - presentationEnabled = 1; - if (!get_bits(OCTET(4),8,8)) { //Oct 3b exists - rdnisOct++; - reason = get_bits(OCTET(5),1,4); - reasonEnabled = 1; - } - } - - if(len >= sizeof(rdnis_string)) { - len = sizeof(rdnis_string)-1; - } - - j = 0; - while(rdnisOct++ <= len+1) { - rdnis_string[j++]=ia5[get_bits(OCTET(rdnisOct),1,4)][get_bits(OCTET(rdnisOct),5,8)]; - } - - rdnis_string[j]='\0'; - *str_len+= sprintf(&str[*str_len], "%s(l:%d) plan:%s(%d) type:%s(%d)", - rdnis_string, j, - get_code_2_str(plan, dcodQ931NumberingPlanTable), plan, - get_code_2_str(type, dcodQ931TypeofNumberTable), type); - - if(presentationEnabled || screeningEnabled) { - *str_len+= sprintf(&str[*str_len], "scr:%s(%d) pres:%s(%d)", - get_code_2_str(screening, dcodQ931ScreeningTable), screening, - get_code_2_str(presentation, dcodQ931PresentationTable), presentation); - } - - if(reasonEnabled) { - *str_len+= sprintf(&str[*str_len], "reason:%s(%d)", - get_code_2_str(reason, dcodQ931ReasonTable), reason); - } - *str_len+= sprintf(&str[*str_len], "\n"); - } - break; - case PROT_Q931_IE_USER_USER: - { - uint8_t protDiscr = 0x00, j, uui_stringOct; - char uui_string[32]; - memset(uui_string, 0, sizeof(uui_string)); - protDiscr = OCTET(3); - uui_stringOct = 3; - if (protDiscr != 0x04) { /* Non-IA5 */ - *str_len+= sprintf(&str[*str_len], "%s (0x%02x)\n", - get_code_2_str(protDiscr, dcodQ931UuiProtDiscrTable), protDiscr); - } else { - j = 0; - - if(len >= sizeof(uui_string)) { - len = sizeof(uui_string)-1; - } - while(uui_stringOct++ <= len+1) { - uui_string[j++]=ia5[get_bits(OCTET(uui_stringOct),1,4)][get_bits(OCTET(uui_stringOct),5,8)]; - } - uui_string[j]='\0'; - *str_len+= sprintf(&str[*str_len], " %s (0x%02x) <%s>\n", - get_code_2_str(protDiscr, dcodQ931UuiProtDiscrTable), protDiscr, - uui_string); - } - } - break; - case PROT_Q931_IE_DISPLAY: - { - uint8_t j; - char displayStr[82]; - uint8_t displayNtEnabled = 0; - uint8_t displayStrOct = 2; - uint8_t displayType = 0; - uint8_t assocInfo = 0; - - memset(displayStr, 0, sizeof(displayStr)); - - if(get_bits(OCTET(3),8,8)) { - displayType = get_bits(OCTET(3),1,4); - assocInfo = get_bits(OCTET(3),5,7); - - displayNtEnabled = 1; - displayStrOct++; - } - j = 0; - if(len >= sizeof(displayStr)) { - len = sizeof(displayStr)-1; - } - while(displayStrOct++ <= len+1) { - displayStr[j++]=ia5[get_bits(OCTET(displayStrOct),1,4)][get_bits(OCTET(displayStrOct),5,8)]; - } - displayStr[j]='\0'; - if (displayNtEnabled) { - *str_len+= sprintf(&str[*str_len], "%s(l:%d) type:%s(%d) info:%s(%d)\n", - displayStr, len, - get_code_2_str(displayType, dcodQ931DisplayTypeTable), displayType, - get_code_2_str(assocInfo, dcodQ931AssocInfoTable), assocInfo); - } else { - *str_len+= sprintf(&str[*str_len], "%s(l:%d)\n", - displayStr, len); - } - } - break; - case PROT_Q931_IE_RESTART_IND: - { - uint8_t indClass; - indClass = get_bits(OCTET(3),1,3); - *str_len+= sprintf(&str[*str_len], "class:%s(%d)\n", - get_code_2_str(indClass,dcodQ931RestartIndClassTable), indClass); - } - break; - case PROT_Q931_IE_PROGRESS_IND: - { - uint8_t codingStandard, location, progressDescr; - codingStandard = get_bits(OCTET(3),6,7); - location = get_bits(OCTET(3),1,4); - progressDescr = get_bits(OCTET(4),1,7); - *str_len+= sprintf(&str[*str_len], "coding:%s(%d) location:%s(%d) descr:%s(%d)\n", - get_code_2_str(codingStandard,dcodQ931BcCodingStandardTable), codingStandard, - get_code_2_str(location,dcodQ931IelocationTable), location, - get_code_2_str(progressDescr,dcodQ931IeprogressDescrTable), progressDescr); - } - break; - case PROT_Q931_IE_KEYPAD_FACILITY: - { - uint8_t keypadFacilityStrOct = 3, j; - char keypadFacilityStr[82]; - memset(keypadFacilityStr, 0, sizeof(keypadFacilityStr)); - - j = 0; - if(len >= sizeof(keypadFacilityStr)) { - len = sizeof(keypadFacilityStr)-1; - } - while(keypadFacilityStrOct++ < len+1) { - keypadFacilityStr[j++]=ia5[get_bits(OCTET(keypadFacilityStrOct),1,4)][get_bits(OCTET(keypadFacilityStrOct),5,8)]; - } - keypadFacilityStr[j]='\0'; - *str_len+= sprintf(&str[*str_len], " digits:%s(l:%d)\n", - keypadFacilityStr, len); - } - break; - case PROT_Q931_IE_FACILITY: - { - uint8_t protProfile; - protProfile = get_bits(OCTET(3),1,5); - *str_len+= sprintf(&str[*str_len], "Prot profile:%s(%d)\n", - get_code_2_str(protProfile,dcodQ931IeFacilityProtProfileTable), protProfile); - } - break; - case PROT_Q931_IE_GENERIC_DIGITS: - { - uint8_t encoding,type; - int value = 0; - - encoding = get_bits(OCTET(3),6,8); - type = get_bits(OCTET(3),1,5); - - *str_len+= sprintf(&str[*str_len], "encoding:%s(%d) type:%s(%d) ", - get_code_2_str(encoding,dcodQ931GenDigitsEncodingTable), encoding, - get_code_2_str(encoding,dcodQ931GenDigitsTypeTable), type); - - if (len > 1) { - uint32_t j=0; - - while(++j < len) { - switch(encoding) { - case 0: /* BCD even */ - case 1: /* BCD odd */ - { - uint8_t byte = OCTET(j+3); - value = (get_bits(byte,1,4)*10) + get_bits(byte,5,8) + (value*10); - } - break; - case 2: /* IA 5 */ - value = value*10 + OCTET(j+3)-'0'; - *str_len+= sprintf(&str[*str_len], "%c", OCTET(j+3)); - break; - case 3: - /* Don't know how to decode binary encoding yet */ - *str_len+= sprintf(&str[*str_len], "Binary encoded"); - break; - } - } - *str_len+= sprintf(&str[*str_len], " "); - switch(type) { - case 4: /* info digits */ - *str_len+= sprintf(&str[*str_len], "ani2:%s(%d)", get_code_2_str(value,dcodQ931LineInfoTable), value); - break; - case 5: /* Callid */ - *str_len+= sprintf(&str[*str_len], "Caller ID not implemented\n"); - break; - } - } - *str_len+= sprintf(&str[*str_len], "\n"); - print_hex_dump(str, str_len, (uint8_t*) data, index_start, index_end); - } - break; - case PROT_Q931_IE_SENDING_COMPLETE: - /* No need to decode sending complete IE, as no additional info is available except that sending is done */ - /* This is a single octet IE */ - *str_len+= sprintf(&str[*str_len], "\n"); - return 0; - break; - case PROT_Q931_IE_CALLED_PARTY_SUBADDRESS: - { - uint8_t type; - uint8_t currentOct, j=0; - char calling_subaddr_string[82]; - memset(calling_subaddr_string, 0, sizeof(calling_subaddr_string)); - type = get_bits(OCTET(3),5,7); - currentOct = 3; - while(currentOct++ <= len+1) { - calling_subaddr_string[j++]=ia5[get_bits(OCTET(currentOct),1,4)][get_bits(OCTET(currentOct),5,8)]; - } - calling_subaddr_string[j++]='\0'; - *str_len += sprintf(&str[*str_len], "%s (l:%d) type:%s(%d) \n", - calling_subaddr_string, (j-1), get_code_2_str(type, dcodQ931TypeOfSubaddressTable), type); - } - break; - case PROT_Q931_IE_NOTIFICATION_IND: - { - uint8_t desc; - - desc = get_bits(OCTET(3),1,7); - *str_len += sprintf(&str[*str_len], "%s (%d)\n", - get_code_2_str(desc, dcodQ931NotificationIndTable), desc); - } - break; - case PROT_Q931_IE_REDIRECTION_NUMBER: - case PROT_Q931_IE_DATE_TIME: - case PROT_Q931_IE_INFORMATION_REQUEST: - case PROT_Q931_IE_SIGNAL: - case PROT_Q931_IE_SWITCHOOK: - case PROT_Q931_IE_FEATURE_ACT: - case PROT_Q931_IE_FEATURE_IND: - case PROT_Q931_IE_INFORMATION_RATE: - case PROT_Q931_IE_END_TO_END_TRANSIT_DELAY: - case PROT_Q931_IE_TRANSIT_DELAY_SELECT_IND: - case PROT_Q931_IE_PACKET_LAYER_BINARY_PARAMS: - case PROT_Q931_IE_PACKET_LAYER_WINDOW_SIZE: - case PROT_Q931_IE_PACKET_LAYER_SIZE: - case PROT_Q931_IE_TRANSIT_NETWORK_SELECTION: - case PROT_Q931_IE_LOW_LAYER_COMPAT: - case PROT_Q931_IE_HIGH_LAYER_COMPAT: - case PROT_Q931_IE_ESCAPE_FOR_EXTENSION: - case PROT_Q931_IE_CALL_IDENTITY: - case PROT_Q931_IE_CALL_STATE: - case PROT_Q931_IE_SEGMENTED_MESSAGE: - case PROT_Q931_IE_NETWORK_SPF_FACILITY: - case PROT_Q931_IE_CALLING_PARTY_SUBADDRESS: - default: - { - *str_len += sprintf(&str[*str_len], "Undecoded"); - print_hex_dump((char*)str, str_len, data, index_start, index_end + 1); - } - break; - } - - return len+1; -} - -void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end) -{ - uint32_t k; - *str_len += sprintf(&str[*str_len], " [ "); - for(k=index_start; k < index_end; k++) { - if (k && !(k%32)) { - *str_len += sprintf(&str[*str_len], "\n "); - } - *str_len += sprintf(&str[*str_len], "%02x ", data[k]); - } - *str_len += sprintf(&str[*str_len], "]\n"); - return; -} - -static ftdm_status_t sngisdn_get_frame_info(uint8_t *data, uint32_t data_len, ftdm_trace_dir_t dir, sngisdn_frame_info_t *target) -{ - uint8_t pos = 0; - uint8_t flag; - uint16_t ref = 0; - uint8_t ref_len = 0; - uint8_t bchan_no = 0; - uint8_t msgtype; - - /* First octet is protocol discriminator */ - pos++; - /* Second octet contains length of call reference */ - ref_len = data[pos++] & 0x0F; - - /* third octet is call reference */ - flag = (data[pos] & 0x80) >> 7; - if (ref_len == 2) { - ref = (data[pos++] & 0x7F) << 8; - ref |= (data[pos++] & 0xFF) ; - } else { - ref = (data[pos++] & 0x7F); - } - - /* Next octet is the message type */ - msgtype = data[pos++] & 0x7F; - - /* - ftdm_log(FTDM_LOG_DEBUG, "Raw frame:call_ref:0x%04x flag:%d msgtype:%d\n", ref, flag, msgtype); - */ - if (!ref) { - /* This is not a call specific message (RESTART for example and we do not care about it) */ - return FTDM_FAIL; - } - - /* Look for the b-channel */ - if (msgtype == PROT_Q931_MSGTYPE_SETUP) { - /* Try to find the b-channel no*/ - - for(; pos < data_len; pos++) { - uint8_t ie_id = data[pos]; - uint8_t ie_len = data[pos+1]; - - switch(ie_id) { - case PROT_Q931_IE_SENDING_COMPLETE: - /* Single octet ie's do not have a length */ - ie_len = 0; - break; - case PROT_Q931_IE_CHANNEL_ID: - { - /* Try to obtain the b-channel */ - uint8_t ie_pos = pos+2; - //ifaceIdPresent = get_bits(OCTET(3),7,7); - if (data[ie_pos] & 0x20) { - /* Interface type is Primary Rate */ - ie_pos+=2; - bchan_no = data[ie_pos] & 0x7F; - } else { - /* Interface type is Basic Interface */ - /* Get the channel number from info channel selection */ - bchan_no = data[ie_pos] & 0x03; - } - ftdm_log(FTDM_LOG_DEBUG, "Found b-channel:%d\n", bchan_no); - goto parse_ies_done; - } - break; - default: - pos = pos+ie_len+1; - } - //ftdm_log(FTDM_LOG_DEBUG, "Decoded IE:%s\n", get_code_2_str(ie_id, dcodQ931IEIDTable)); - } - if (!bchan_no) { - uint32_t tmp_len = 0; - char tmp[1000]; - print_hex_dump(tmp, &tmp_len, data, 0, data_len); - ftdm_log(FTDM_LOG_DEBUG, "Failed to determine b-channel on SETUP message\n%s\n", tmp); - } - } - -parse_ies_done: - - target->call_ref = ref; - target->call_ref_flag = flag; - target->msgtype = msgtype; - target->bchan_no = bchan_no; - target->dir = dir; - - return FTDM_SUCCESS; -} - -static ftdm_status_t sngisdn_map_call(sngisdn_span_data_t *signal_data, sngisdn_frame_info_t frame_info, ftdm_channel_t **found) -{ - sngisdn_chan_data_t *sngisdn_info; - ftdm_channel_t *ftdmchan = NULL; - ftdm_iterator_t *chaniter = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_status_t status = FTDM_FAIL; - uint8_t outbound_call = 0; - - if ((!frame_info.call_ref_flag && frame_info.dir == FTDM_TRACE_DIR_OUTGOING) || - (frame_info.call_ref_flag && frame_info.dir == FTDM_TRACE_DIR_INCOMING)) { - - /* If this is an outgoing frame and this frame was sent by the originating side - of the call (frame_info.call_ref_flag == 0), then this is an outbound call */ - outbound_call = 1; - } else { - outbound_call = 0; - } - - switch (frame_info.msgtype) { - case PROT_Q931_MSGTYPE_SETUP: - /* We initiated this outgoing call try to match the call reference with our internal call-id*/ - if (!frame_info.bchan_no) { - /* We were not able to determine the bchannel on this call, so we will not be able to match it anyway */ - status = FTDM_FAIL; - } - - chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdmchan = (ftdm_channel_t*)(ftdm_iterator_current(curr)); - ftdm_channel_lock(ftdmchan); - - if (outbound_call) { - sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; - if (sngisdn_info && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (ftdmchan->caller_data.call_id && ftdmchan->physical_chan_id == frame_info.bchan_no) { - - sngisdn_info->call_ref = frame_info.call_ref; - *found = ftdmchan; - status = FTDM_SUCCESS; - } - } - } else { - if (ftdmchan->physical_chan_id == frame_info.bchan_no) { - *found = ftdmchan; - status = FTDM_SUCCESS; - } - } - ftdm_channel_unlock(ftdmchan); - } - ftdm_iterator_free(chaniter); - break; - case PROT_Q931_MSGTYPE_ALERTING: - case PROT_Q931_MSGTYPE_PROCEEDING: - case PROT_Q931_MSGTYPE_PROGRESS: - case PROT_Q931_MSGTYPE_CONNECT: - case PROT_Q931_MSGTYPE_SETUP_ACK: - case PROT_Q931_MSGTYPE_CONNECT_ACK: - case PROT_Q931_MSGTYPE_USER_INFO: - case PROT_Q931_MSGTYPE_DISCONNECT: - case PROT_Q931_MSGTYPE_RELEASE: - case PROT_Q931_MSGTYPE_RESTART_ACK: - case PROT_Q931_MSGTYPE_RELEASE_COMPLETE: - case PROT_Q931_MSGTYPE_FACILITY: - case PROT_Q931_MSGTYPE_NOTIFY: - case PROT_Q931_MSGTYPE_STATUS_ENQUIRY: - case PROT_Q931_MSGTYPE_INFORMATION: - case PROT_Q931_MSGTYPE_STATUS: - /* Look for an outbound call on that span and and try to match the call-id */ - chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); - for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { - ftdmchan = (ftdm_channel_t*)(ftdm_iterator_current(curr)); - ftdm_channel_lock(ftdmchan); - sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; - if (outbound_call) { - if (sngisdn_info && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (sngisdn_info->call_ref == frame_info.call_ref) { - - *found = ftdmchan; - status = FTDM_SUCCESS; - } - } - } else { - if (sngisdn_info && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (sngisdn_info->call_ref && sngisdn_info->call_ref == frame_info.call_ref) { - - *found = ftdmchan; - status = FTDM_SUCCESS; - } - } - } - ftdm_channel_unlock(ftdmchan); - } - ftdm_iterator_free(chaniter); - break; - default: - /* This frame is not call specific, ignore */ - break; - } - if (status == FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Mapped %s with Call Ref:%04x to call-id:%d\n", get_code_2_str(frame_info.msgtype, dcodQ931MsgTypeTable), frame_info.call_ref, (*found)->caller_data.call_id); - } else { - /* We could not map this frame to a call-id */ - ftdm_log(FTDM_LOG_DEBUG, "Failed to map %s with Call Ref:%04x to local call\n", - get_code_2_str(frame_info.msgtype, dcodQ931MsgTypeTable), frame_info.call_ref); - } - - return status; -} - - - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h deleted file mode 100644 index b09bcbd33a..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __FTMOD_SANGOMA_ISDN_TRACE_H__ -#define __FTMOD_SANGOMA_ISDN_TRACE_H__ - -#define MX_CODE_TXT_LEN 70 -#define Q931_LOCKING_SHIFT 0x90 -#define Q931_NON_LOCKING_SHIFT 0x98 - -#define PROT_Q931_RELEASE_CAUSE_MISDIALED_TRUNK_PREFIX 5 -#define PROT_Q931_RELEASE_CAUSE_INVALID_NUMBER_FORMAT 28 -#define PROT_Q931_RELEASE_CAUSE_NO_CHAN_AVAIL 34 -#define PROT_Q931_RELEASE_CAUSE_DEST_OUT_OF_ORDER 27 -#define PROT_Q931_RELEASE_CAUSE_IE_NOT_EXIST 99 -#define PROT_Q931_RECOVERY_ON_TIMER_EXPIRE 102 -#define PROT_Q931_RELEASE_CAUSE_WRONG_CALL_STATE 101 - - -#define PROT_Q931_IE_SEGMENTED_MESSAGE 0x00 -#define PROT_Q931_IE_BEARER_CAP 0x04 -#define PROT_Q931_IE_CAUSE 0x08 -#define PROT_Q931_IE_CALL_IDENTITY 0x10 -#define PROT_Q931_IE_CALL_STATE 0x14 -#define PROT_Q931_IE_CHANNEL_ID 0x18 -#define PROT_Q931_IE_FACILITY 0x1c -#define PROT_Q931_IE_PROGRESS_IND 0x1e -#define PROT_Q931_IE_NETWORK_SPF_FACILITY 0x20 -#define PROT_Q931_IE_NOTIFICATION_IND 0x27 -#define PROT_Q931_IE_DISPLAY 0x28 -#define PROT_Q931_IE_DATE_TIME 0x29 -#define PROT_Q931_IE_KEYPAD_FACILITY 0x2c -#define PROT_Q931_IE_INFORMATION_REQUEST 0x32 -#define PROT_Q931_IE_SIGNAL 0x34 -#define PROT_Q931_IE_SWITCHOOK 0x36 -#define PROT_Q931_IE_GENERIC_DIGITS 0x37 -#define PROT_Q931_IE_FEATURE_ACT 0x38 -#define PROT_Q931_IE_FEATURE_IND 0x39 -#define PROT_Q931_IE_INFORMATION_RATE 0x40 -#define PROT_Q931_IE_END_TO_END_TRANSIT_DELAY 0x42 -#define PROT_Q931_IE_TRANSIT_DELAY_SELECT_IND 0x43 -#define PROT_Q931_IE_PACKET_LAYER_BINARY_PARAMS 0x44 -#define PROT_Q931_IE_PACKET_LAYER_WINDOW_SIZE 0x45 -#define PROT_Q931_IE_PACKET_LAYER_SIZE 0x46 -#define PROT_Q931_IE_CALLING_PARTY_NUMBER 0x6c -#define PROT_Q931_IE_CALLING_PARTY_SUBADDRESS 0x6d -#define PROT_Q931_IE_CALLED_PARTY_NUMBER 0x70 -#define PROT_Q931_IE_CALLED_PARTY_SUBADDRESS 0x71 -#define PROT_Q931_IE_REDIRECTING_NUMBER 0x74 -#define PROT_Q931_IE_REDIRECTION_NUMBER 0x76 -#define PROT_Q931_IE_TRANSIT_NETWORK_SELECTION 0x78 -#define PROT_Q931_IE_RESTART_IND 0x79 -#define PROT_Q931_IE_LOW_LAYER_COMPAT 0x7c -#define PROT_Q931_IE_HIGH_LAYER_COMPAT 0x7d -#define PROT_Q931_IE_USER_USER 0x7e -#define PROT_Q931_IE_SENDING_COMPLETE 0xa1 -#define PROT_Q931_IE_ESCAPE_FOR_EXTENSION 0x7f -#define PROT_Q931_IE_SENDING_COMPLETE 0xa1 - -#define NULL_CHAR 0 - - -struct code2str -{ - int code; - char text[MX_CODE_TXT_LEN]; -}; - -enum { - I_FRAME = 1, /* Information frame */ - S_FRAME, /* Supervisory frame */ - U_FRAME, /* Unnumbered frame */ -}; - -char ia5[16][8]={{NULL_CHAR,NULL_CHAR,' ','0','@','P','`','p'}, - {NULL_CHAR,NULL_CHAR,'!','1','A','Q','a','q'}, - {NULL_CHAR,NULL_CHAR,'"','2','B','R','b','r'}, - {NULL_CHAR,NULL_CHAR,'#','3','C','S','c','s'}, - {NULL_CHAR,NULL_CHAR,'$','4','D','T','d','t'}, - {NULL_CHAR,NULL_CHAR,'%','5','E','U','e','u'}, - {NULL_CHAR,NULL_CHAR,'&','6','F','V','f','v'}, - {NULL_CHAR,NULL_CHAR,'\'','7','G','W','g','w'}, - {NULL_CHAR,NULL_CHAR,'(','8','H','X','h','x'}, - {NULL_CHAR,NULL_CHAR,')','9','I','Y','i','y'}, - {NULL_CHAR,NULL_CHAR,'*',':','J','Z','j','z'}, - {NULL_CHAR,NULL_CHAR,'+',';','K','[','k','{'}, - {NULL_CHAR,NULL_CHAR,',','<','L','\\','l','|'}, - {NULL_CHAR,NULL_CHAR,'-','=','M',']','m','}'}, - {NULL_CHAR,NULL_CHAR,'.','>','N','^','n','~'}, - {NULL_CHAR,NULL_CHAR,'/','?','O','_','o',NULL_CHAR}}; - -/* Based on Table 4 - pg 15 of Q.921 Recommendation */ -struct code2str dcodQ921FrameFormatTable[] = { - {I_FRAME, "Information"}, - {S_FRAME, "Supervisory"}, - {U_FRAME, "Unnumbered"}, - {-1, "?"}, -}; - - -/* Based on Table 5 - pg 15 of Q.921 Recommendation */ -struct code2str dcodQ921SupervisoryCmdTable[] = { - {0, "RR - receive ready"}, - {1, "RNR - receive not ready"}, - {2, "REJ - reject"}, - {-1, "Unknown"}, -}; - -/* Based on Table 5 - pg 15 of Q.921 Recommendation */ -struct code2str dcodQ921UnnumberedCmdTable[] = { - {0x0F, "SABME - set async balanced mode extended"}, - {0x03, "DM - disconnected mode"}, - {0x00, "UI - unnumbered information"}, - {0x08, "DISC - disconnect"}, - {0x0C, "UA - unnumbered acknowledgement"}, - {0x11, "FRMR - frame reject"}, - {0x17, "XID - Exchange Identification)"}, - {-1, "Unknown"}, -}; - -struct code2str dcodQ931ProtDiscTable[] = { - {0x08, "Q.931/I.451"}, - {0x09, "Q.2931"}, - {-1, "Unknown"}, -}; - -struct code2str dcodQ931CallRefHiTable[] = { - {0, "0"}, - {16, "1"}, - {32, "2"}, - {48, "3"}, - {64, "4"}, - {80, "5"}, - {96, "6"}, - {112, "7"}, - {128, "8"}, - {144, "9"}, - {160, "A"}, - {176, "B"}, - {192, "C"}, - {208, "D"}, - {224, "E"}, - {240, "F"}, - {-1,"?"}, -}; - -struct code2str dcodQ931CallRefLoTable[] = { - {0, "0"}, - {1, "1"}, - {2, "2"}, - {3, "3"}, - {4, "4"}, - {5, "5"}, - {6, "6"}, - {7, "7"}, - {8, "8"}, - {9, "9"}, - {10, "A"}, - {11, "B"}, - {12, "C"}, - {13, "D"}, - {14, "E"}, - {15, "F"}, - {-1, "?"}, -}; - -#define PROT_Q931_MSGTYPE_ALERTING 1 -#define PROT_Q931_MSGTYPE_PROCEEDING 2 -#define PROT_Q931_MSGTYPE_PROGRESS 3 -#define PROT_Q931_MSGTYPE_SETUP 5 -#define PROT_Q931_MSGTYPE_CONNECT 7 -#define PROT_Q931_MSGTYPE_SETUP_ACK 13 -#define PROT_Q931_MSGTYPE_CONNECT_ACK 15 -#define PROT_Q931_MSGTYPE_USER_INFO 32 -#define PROT_Q931_MSGTYPE_SUSPEND_REJ 33 -#define PROT_Q931_MSGTYPE_RESUME_REJ 34 -#define PROT_Q931_MSGTYPE_SUSPEND 37 -#define PROT_Q931_MSGTYPE_RESUME 38 -#define PROT_Q931_MSGTYPE_SUSPEND_ACK 45 -#define PROT_Q931_MSGTYPE_RESUME_ACK 46 -#define PROT_Q931_MSGTYPE_DISCONNECT 69 -#define PROT_Q931_MSGTYPE_RESTART 70 -#define PROT_Q931_MSGTYPE_RELEASE 77 -#define PROT_Q931_MSGTYPE_RESTART_ACK 78 -#define PROT_Q931_MSGTYPE_RELEASE_COMPLETE 90 -#define PROT_Q931_MSGTYPE_SEGMENT 96 -#define PROT_Q931_MSGTYPE_FACILITY 98 -#define PROT_Q931_MSGTYPE_NOTIFY 110 -#define PROT_Q931_MSGTYPE_STATUS_ENQUIRY 117 -#define PROT_Q931_MSGTYPE_CONGESTION_CNTRL 121 -#define PROT_Q931_MSGTYPE_INFORMATION 123 -#define PROT_Q931_MSGTYPE_STATUS 125 - - -struct code2str dcodQ931MsgTypeTable[] = { - {PROT_Q931_MSGTYPE_ALERTING, "ALERT"}, - {PROT_Q931_MSGTYPE_PROCEEDING, "PROCEED"}, - {PROT_Q931_MSGTYPE_PROGRESS, "PROGRESS"}, - {PROT_Q931_MSGTYPE_SETUP, "SETUP"}, - {PROT_Q931_MSGTYPE_CONNECT, "CONNECT"}, - {PROT_Q931_MSGTYPE_SETUP_ACK, "SETUP ACK"}, - {PROT_Q931_MSGTYPE_CONNECT_ACK, "CONNECT ACK"}, - {PROT_Q931_MSGTYPE_USER_INFO, "USER INFO"}, - {PROT_Q931_MSGTYPE_SUSPEND_REJ, "SUSPEND REJ"}, - {PROT_Q931_MSGTYPE_RESUME_REJ, "RESUME REJ"}, - {PROT_Q931_MSGTYPE_SUSPEND, "SUSPEND"}, - {PROT_Q931_MSGTYPE_RESUME, "RESUME"}, - {PROT_Q931_MSGTYPE_SUSPEND_ACK, "SUSPEND ACK"}, - {PROT_Q931_MSGTYPE_RESUME_ACK, "RESUME ACK"}, - {PROT_Q931_MSGTYPE_DISCONNECT, "DISCONNECT"}, - {PROT_Q931_MSGTYPE_RESTART, "RESTART"}, - {PROT_Q931_MSGTYPE_RELEASE, "RELEASE"}, - {PROT_Q931_MSGTYPE_RESTART_ACK, "RESTART ACK"}, - {PROT_Q931_MSGTYPE_RELEASE_COMPLETE, "RELEASE COMPLETE"}, - {PROT_Q931_MSGTYPE_SEGMENT, "SEGMENT"}, - {PROT_Q931_MSGTYPE_FACILITY, "FACILITY"}, - {PROT_Q931_MSGTYPE_NOTIFY, "NOTIFY"}, - {PROT_Q931_MSGTYPE_STATUS_ENQUIRY, "STATUS ENQ"}, - {PROT_Q931_MSGTYPE_CONGESTION_CNTRL, "CONGESTION CTRL"}, - {PROT_Q931_MSGTYPE_INFORMATION, "INFO"}, - {PROT_Q931_MSGTYPE_STATUS, "STATUS"}, - {-1, "UNKNOWN"}, -}; - -struct code2str dcodQ931CauseCodeTable[] = { - {1, "Unallocated (unassigned) number"}, - {2, "No route to specified network"}, - {3, "No route to destination"}, - {4, "Send special information tone"}, - {5, "Misdialed trunk prefix"}, - {6, "Channel Unacceptable"}, - {7, "Call awarded and channel established"}, - {8, "Pre-emption"}, - {9, "Pre-emption-circuit reserved"}, - {16, "Normal call clearing"}, - {17, "User Busy"}, - {18, "No User Responding"}, - {19, "No Answer from User"}, - {20, "Subscriber Absent"}, - {21, "Call Rejected"}, - {22, "Number Changed"}, - {26, "Non-Selected User Clearing"}, - {27, "Destination Out-of-Order"}, - {28, "Invalid Number Format"}, - {29, "Facility Rejected"}, - {30, "Response to Status Enquiry"}, - {31, "Normal, Unspecified"}, - {34, "No Circuit/Channel Available"}, - {38, "Network Out-of-Order"}, - {39, "Permanent Frame Mode OOS"}, - {40, "Permanent Frame Mode Operational"}, - {41, "Temporary Failure"}, - {42, "Switching Equipment Congestion"}, - {43, "Access Information Discarded"}, - {44, "Requested Circuit/Channel not available"}, - {47, "Resource Unavailable, Unspecified"}, - {49, "Quality of Service not available"}, - {50, "Requested facility not subscribed"}, - {53, "Outgoing calls barred within CUG"}, - {55, "Incoming calls barred within CUG"}, - {57, "Bearer capability not authorized"}, - {58, "Bearer capability not presently available"}, - {62, "Inconsistency in access inf and subscriber"}, - {63, "Service or Option not available"}, - {65, "Bearer capability not implemented"}, - {66, "Channel type not implemented"}, - {69, "Requested facility not implemented"}, - {70, "Only restricted digital BC available"}, - {79, "Service or option not implemented"}, - {81, "Invalid call reference value"}, - {82, "Identified channel does not exist"}, - {83, "Suspended call exists"}, - {84, "Call identity in use"}, - {85, "No call suspended"}, - {86, "Call already cleared"}, - {87, "User not member of CUG"}, - {88, "Incompatible destination"}, - {90, "Non existent CUG"}, - {91, "Invalid transit network selection"}, - {95, "Invalid message, unspecified"}, - {96, "Mandatory IE missing"}, - {97, "Message type non-existent, not implemented"}, - {98, "Message not compatible with call state"}, - {99, "An IE or parameter does not exist"}, - {100, "Invalid IE contents"}, - {101, "Message not compatible with call state"}, - {102, "Recovery on timer expired"}, - {103, "Parameter non-existent, not impl"}, - {110, "Message with unrecognized parameter"}, - {111, "Protocol error, unspecified"}, - {127, "Interworking, unspecified"}, - {-1, "Unknown"}, -}; - -struct code2str dcodQ931IEIDTable[] = { - {PROT_Q931_IE_SEGMENTED_MESSAGE, "Segmented Message"}, - {PROT_Q931_IE_BEARER_CAP, "Bearer Capability"}, - {PROT_Q931_IE_CAUSE, "Cause"}, - {PROT_Q931_IE_CALL_IDENTITY, "Call Identity"}, - {PROT_Q931_IE_CALL_STATE, "Call State"}, - {PROT_Q931_IE_CHANNEL_ID, "Channel Id"}, - {PROT_Q931_IE_FACILITY, "Facility"}, - {PROT_Q931_IE_PROGRESS_IND, "Progress Indicator"}, - {PROT_Q931_IE_NETWORK_SPF_FACILITY, "Network Specific Facilities"}, - {PROT_Q931_IE_NOTIFICATION_IND, "Notification Indicator"}, - {PROT_Q931_IE_DISPLAY, "Display"}, - {PROT_Q931_IE_DATE_TIME, "Date/Time"}, - {PROT_Q931_IE_KEYPAD_FACILITY, "Keypad Facility"}, - {PROT_Q931_IE_INFORMATION_REQUEST, "Information Request"}, - {PROT_Q931_IE_SIGNAL, "Signal"}, - {PROT_Q931_IE_SWITCHOOK, "Switchhook"}, - {PROT_Q931_IE_GENERIC_DIGITS, "Generic Digits"}, - {PROT_Q931_IE_FEATURE_ACT, "Feature Activation"}, - {PROT_Q931_IE_FEATURE_IND, "Feature Indication"}, - {PROT_Q931_IE_INFORMATION_RATE, "Information Rate"}, - {PROT_Q931_IE_END_TO_END_TRANSIT_DELAY, "End-to-end Transit Delay"}, - {PROT_Q931_IE_TRANSIT_DELAY_SELECT_IND, "Transit Delay Selection and Indication"}, - {PROT_Q931_IE_PACKET_LAYER_BINARY_PARAMS, "Packet layer binary parameters"}, - {PROT_Q931_IE_PACKET_LAYER_WINDOW_SIZE, "Packet layer Window Size"}, - {PROT_Q931_IE_PACKET_LAYER_SIZE, "Packet layer Size"}, - {PROT_Q931_IE_CALLING_PARTY_NUMBER, "Calling Party Number"}, - {PROT_Q931_IE_CALLING_PARTY_SUBADDRESS, "Calling Party Subaddress"}, - {PROT_Q931_IE_CALLED_PARTY_NUMBER, "Called Party Number"}, - {PROT_Q931_IE_CALLED_PARTY_SUBADDRESS, "Called Party Subaddress"}, - {PROT_Q931_IE_REDIRECTING_NUMBER, "Redirecting Number"}, - {PROT_Q931_IE_REDIRECTION_NUMBER, "Redirection Number"}, - {PROT_Q931_IE_TRANSIT_NETWORK_SELECTION, "Transit Network Selection"}, - {PROT_Q931_IE_RESTART_IND, "Restart Indicator"}, - {PROT_Q931_IE_LOW_LAYER_COMPAT, "Low-Layer Compatibility"}, - {PROT_Q931_IE_HIGH_LAYER_COMPAT, "High-Layer Compatibility"}, - {PROT_Q931_IE_USER_USER, "User-User"}, - {PROT_Q931_IE_SENDING_COMPLETE, "Sending complete"}, - {PROT_Q931_IE_ESCAPE_FOR_EXTENSION, "Escape for extension"}, - {-1,"Unknown"}, -}; - -struct code2str dcodQ931NumberingPlanTable[] = { - {0, "unknown"}, - {1, "isdn"}, - {3, "data"}, - {4, "telex"}, - {8, "national"}, - {9, "private"}, - {15, "reserved"}, - {-1, "invalid"}, -}; - -struct code2str dcodQ931TypeofNumberTable[] = { - {0, "unknown"}, - {1, "international"}, - {2, "national"}, - {3, "network spf"}, - {4, "subscriber"}, - {6, "abbreviated"}, - {7, "reserved"}, - {-1, "invalid" }, -}; - -struct code2str dcodQ931PresentationTable[] = { - {0, "allowed"}, - {1, "restricted"}, - {2, "not available"}, - {-1, "invalid" }, -}; - -struct code2str dcodQ931ScreeningTable[] = { - {0, "user, not screened"}, - {1, "user, passed"}, - {2, "user, failed"}, - {3, "network, provided"}, - {-1, "invalid" }, -}; - -struct code2str dcodQ931InfoChannelSelTable[] = { - {0, "No Chan"}, - {1, "B1"}, - {2, "B2"}, - {3, "Any Chan"}, - {-1, "invalid" }, -}; - -struct code2str dcodQ931ReasonTable[] = { - {0x0, "Unknown"}, - {0x1, "Call forwarding busy"}, - {0x2, "Call forwarding no reply"}, - {0x4, "Call deflection"}, - {0x9, "Called DTE out of order"}, - {0xA, "Call forwarding by the called DTE"}, - {0xF, "Call forwarding unconditional"}, - {-1, "reserved" }, -}; - -struct code2str dcodQ931BcCodingStandardTable[] = { - {0x0, "ITU-T"}, - {0x1, "ISO/IEC"}, - {0x2, "National"}, - {0x3, "Defined standard"}, - {-1, "unknown"}, -}; - -struct code2str dcodQ931BcInfTransferCapTable[] = { - {0x00, "Speech"}, - {0x08, "Unrestricted digital"}, - {0x09, "Restricted digital"}, - {0x10, "3.1Khz audio"}, - {0x11, "Unrestricted digital w/ tones"}, - {0x18, "Video"}, - {-1, "reserved"}, -}; - -struct code2str dcodQ931BcInfTransferRateTable[] = { - {0x00, "n/a"}, /* for packet-mode calls */ - {0x10, "64 Kbit/s"}, - {0x11, "2x64 Kbit/s"}, - {0x13, "384 Kbit/s"}, - {0x15, "1536 Kbit/s"}, - {0x17, "1920 Kbit/s"}, - {0x18, "Multirate"}, - {-1, "reserved"}, -}; - - -struct code2str dcodQ931BcusrL1ProtTable[] = { - {0x01, "ITU-T rate/V.110/I.460/X.30"}, - {0x02, "G.711 u-Law"}, - {0x03, "G.711 A-Law"}, - {0x04, "G.721/I.460"}, - {0x05, "H.221/H.242"}, - {0x06, "H.223/H.245"}, - {0x07, "Non-ITU-T rate"}, - {0x08, "V.120"}, - {0x09, "X.31 HDLC"}, - {-1, "reserved"}, -}; - -struct code2str dcodQ931UuiProtDiscrTable[] = { - {0x00, "User-specific"}, - {0x01, "OSI high layer prot"}, - {0x02, "Recommendation X.244"}, - {0x03, "System management"}, - {0x04, "IA5 Chars"}, - {0x05, "X.208/X.209"}, - {0x07, "V.120"}, - {0x08, "Q.931/I.451"}, - {0x10, "X.25"}, - {-1,"reserved"}, -}; - -struct code2str dcodQ931ChanTypeTable[] = { - {0x3,"B-chans"}, - {0x6,"H0-chans"}, - {0x8,"H11-chans"}, - {0x9,"H12-chans"}, - {-1,"reserved"}, -}; - -struct code2str dcodQ931RestartIndClassTable[] = { - {0x0 ,"Indicated in channel IE"}, - {0x6 ,"Single interface"}, - {0x7 ,"All interfaces"}, - {-1, "reserved"}, -}; - -struct code2str dcodQ931IelocationTable[] = { - {0x0, "User"}, - {0x1, "Private network, local user"}, - {0x2, "Public network, local user"}, - {0x3, "Transit network"}, - {0x4, "Public network, remote user"}, - {0x5, "Private network, remote user"}, - {0xA, "Beyond interworking point"}, - {-1, "reserved"}, -}; - -struct code2str dcodQ931IeprogressDescrTable[] = { - {0x01, "Further info maybe available"}, - {0x02, "Destination is non-ISDN"}, - {0x03, "Origination address is non-ISDN"}, - {0x04, "Call returned to ISDN"}, - {0x08, "In-band data ready"}, - {-1, "reserved"}, -}; - -struct code2str dcodQ931IeFacilityProtProfileTable[] = { - {0x11, "Remote Operations Protocol"}, - {0x12, "CMIP Protocol"}, - {0x13, "ACSE Protocol"}, - {0x16, "GAT Protocol"}, - {0x1F, "Networking Extensions"}, - {-1, "reserved"}, -}; - -//from www.voip-info.org/wiki/ANI2 - NANPA -struct code2str dcodQ931LineInfoTable[] = { - {0, "Plain Old Telephone Service(POTS)" }, - {1, "Multiparty line"}, - {2, "ANI Failure"}, - {6, "Station Level Rating"}, - {7, "Special Operator Handling Required"}, - {20, "Automatic Identified Outward Dialing (AIOD)"}, - {23, "Coin or Non-coin"}, - {24, "Toll free service, POTS originated for non-pay station"}, - {25, "Toll free service, POTS originated for pay station"}, - {27, "Pay station with coin control"}, - {29, "Prison-Inmate service"}, - {30, "Intercept - blank"}, - {31, "Intercept - trouble"}, - {32, "Intercept - regular"}, - {34, "Telco operator handled call"}, - {52, "Outward Wide Area Telecommunications Service(OUTWATS)"}, - {60, "TRS call - from unrestricted line"}, - {61, "Cellular-Wireless PCS Type 1"}, - {62, "Cellular-Wireless PCS Type 2"}, - {63, "Cellular-Wireless PCS Type Roaming"}, - {66, "TRS call - from hotel/motel"}, - {67, "TRS call - from restricted line"}, - {70, "Line connected to pay station"}, - {93, "Private virtual network call"}, - {-1, "Unassigned"}, -}; - - -struct code2str dcodQ931GenDigitsEncodingTable[] = { - {0, "BCD even"}, - {1, "BCD odd"}, - {2, "IA5"}, - {3, "Binary"}, - {-1, "Invalid"}, -}; - - -struct code2str dcodQ931GenDigitsTypeTable[] = { - { 0, "Account Code"}, - { 1, "Auth Code"}, - { 2, "Customer ID" }, - { 3, "Universal Access"}, - { 4, "Info Digits"}, - { 5, "Callid"}, - { 6, "Opart"}, - { 7, "TCN"}, - { 9, "Adin"}, - {-1, "Invalid"}, -}; - -struct code2str dcodQ931TypeOfSubaddressTable[] = { - { 0x00, "NSAP"}, - { 0x02, "User-specified"}, - { -1, "Invalid"}, -}; - -struct code2str dcodQ931DisplayTypeTable[] = { - { 0x00, "Calling Party Name"}, - { 0x01, "Connected Party Name"}, - { 0x05, "Original Called Party Name"}, - { -1, "Invalid"}, -}; - -struct code2str dcodQ931AssocInfoTable[] = { - { 0x00, "Requested"}, - { 0x03, "Included"}, - { -1, "Invalid"}, -}; - - -struct code2str dcodQ931NotificationIndTable[] = { - { 0x71, "Call Information/event"}, - { -1, "Invalid"}, -}; -#endif /* __FTMOD_SANGOMA_ISDN_TRACE_H__ */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_transfer.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_transfer.c deleted file mode 100644 index 5df54f48ea..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_transfer.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2011, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ftmod_sangoma_isdn.h" - -#define TRANSFER_FUNC(name) ftdm_status_t (name)(ftdm_channel_t *ftdmchan, sngisdn_transfer_type_t type, char* target) - -#define SNGISDN_ATT_TRANSFER_RESPONSE_CP_DROP_OFF "**1" -#define SNGISDN_ATT_TRANSFER_RESPONSE_LIMITS_EXCEEDED "**5" -#define SNGISDN_ATT_TRANSFER_RESPONSE_OK "**6" -#define SNGISDN_ATT_TRANSFER_RESPONSE_INVALID_NUM "**7" -#define SNGISDN_ATT_TRANSFER_RESPONSE_INVALID_COMMAND "**8" - - -void att_courtesy_transfer_complete(sngisdn_chan_data_t *sngisdn_info, ftdm_transfer_response_t response); -void att_courtesy_transfer_timeout(void* p_sngisdn_info); -static ftdm_status_t att_courtesy_vru(ftdm_channel_t *ftdmchan, sngisdn_transfer_type_t type, char* target); - -typedef struct transfer_interfaces { - const char *name; - sngisdn_transfer_type_t type; - TRANSFER_FUNC(*func); -}transfer_interface_t; - -static transfer_interface_t transfer_interfaces[] = { - /* AT&T TR-50075 Courtesy Transfer - VRU -- No Data (Section 4.3) */ - { "ATT_COURTESY_TRANSFER_V", SNGISDN_TRANSFER_ATT_COURTESY_VRU, att_courtesy_vru}, - /* AT&T TR-50075 Courtesy Transfer - VRU --Data (Section 4.4) */ - { "ATT_COURTESY_TRANSFER_V_DATA", SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA, att_courtesy_vru}, -}; - -void att_courtesy_transfer_complete(sngisdn_chan_data_t *sngisdn_info, ftdm_transfer_response_t response) -{ - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL); - - sngisdn_info->transfer_data.type = SNGISDN_TRANSFER_NONE; - sngisdn_info->transfer_data.response = response; - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Transfer Complete:%s\n", ftdm_transfer_response2str(sngisdn_info->transfer_data.response)); - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_TRANSFER_COMPLETED); - - ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_RX_BUFFERS, NULL); - return; -} - -void att_courtesy_transfer_timeout(void* p_sngisdn_info) -{ - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; - ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - - ftdm_mutex_lock(ftdmchan->mutex); - if (sngisdn_info->transfer_data.type == SNGISDN_TRANSFER_NONE) { - /* Call was already cleared */ - ftdm_mutex_unlock(ftdmchan->mutex); - return; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "AT&T Courtesy Transfer timeout (%d)\n", signal_data->transfer_timeout); - att_courtesy_transfer_complete(sngisdn_info, FTDM_TRANSFER_RESPONSE_TIMEOUT); - ftdm_mutex_unlock(ftdmchan->mutex); - return; -} - -static ftdm_status_t att_courtesy_vru(ftdm_channel_t *ftdmchan, sngisdn_transfer_type_t type, char* args) -{ - char dtmf_digits[64]; - ftdm_status_t status = FTDM_FAIL; - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - char *p = args; - uint8_t forced_answer = 0; - - switch (signal_data->switchtype) { - case SNGISDN_SWITCH_5ESS: - case SNGISDN_SWITCH_4ESS: - break; - default: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "AT&T Courtesy Transfer not supported for switchtype\n"); - return FTDM_FAIL; - } - - while (!ftdm_strlen_zero(p)) { - if (!isdigit(*p) && *p != 'w' && *p != 'W') { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot transfer to non-numeric number:%s\n", args); - return FTDM_FAIL; - } - p++; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Performing AT&T Courtesy Transfer-VRU%s to %s\n", (type == SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA) ?"--data" : "", args); - sprintf(dtmf_digits, "*8w%s", args); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending digits %s\n", dtmf_digits); - - switch (ftdmchan->last_state) { - case FTDM_CHANNEL_STATE_PROCEED: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - /* Call has to be in answered state - so send a CONNECT message if we did not answer this call yet */ - forced_answer++; - sngisdn_snd_connect(ftdmchan); - /* fall-through */ - case FTDM_CHANNEL_STATE_UP: - memset(&sngisdn_info->transfer_data.tdata.att_courtesy_vru.dtmf_digits, 0, sizeof(sngisdn_info->transfer_data.tdata.att_courtesy_vru.dtmf_digits)); - sngisdn_info->transfer_data.type = type; - - /* We will be polling the channel for IO so that we can receive the DTMF events, - * Disable user RX otherwise it is a race between who calls channel_read */ - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED); - - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, dtmf_digits); - - if (type == SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA) { - /* We need to save transfer data, so we can send it in the disconnect msg */ - const char *val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "transfer_data"); - if (ftdm_strlen_zero(val)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot perform data transfer because transfer_data variable is not set\n"); - goto done; - } - if (strlen(val) > COURTESY_TRANSFER_MAX_DATA_SIZE) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Data exceeds max size (len:%"FTDM_SIZE_FMT" max:%d), cannot perform transfer\n", strlen(val), COURTESY_TRANSFER_MAX_DATA_SIZE); - goto done; - } - memcpy(sngisdn_info->transfer_data.tdata.att_courtesy_vru.data, val, strlen(val)); - } - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - if (forced_answer) { - /* Notify the user that we answered the call */ - sngisdn_send_signal(sngisdn_info, FTDM_SIGEVENT_UP); - } - if (signal_data->transfer_timeout) { - ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "courtesy_transfer_timeout", signal_data->transfer_timeout, att_courtesy_transfer_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_CHAN_TIMER_ATT_TRANSFER]); - } - - status = FTDM_SUCCESS; - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer in state %s\n", ftdm_channel_state2str(ftdmchan->state)); - break; - - } -done: - return status; -} - - -ftdm_status_t sngisdn_transfer(ftdm_channel_t *ftdmchan) -{ - const char* args; - char *p; - char *type = NULL; - char *target = NULL; - ftdm_status_t status = FTDM_FAIL; - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - unsigned i; - - args = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "transfer_arg"); - if (ftdm_strlen_zero(args)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer because call_transfer_arg variable is not set\n"); - goto done; - } - - type = ftdm_strdup(args); - if ((p = strchr(type, '/'))) { - target = ftdm_strdup(p+1); - *p = '\0'; - } - - if (ftdm_strlen_zero(type) || ftdm_strlen_zero(target)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid parameters for transfer %s, expected /\n", args); - goto done; - } - - if (sngisdn_info->transfer_data.type != SNGISDN_TRANSFER_NONE) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot perform transfer because an existing transfer transfer is pending (%s)\n", sngisdn_transfer_type2str(sngisdn_info->transfer_data.type)); - goto done; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Transfer requested type:%s target:%s\n", type, target); - for (i = 0; i < ftdm_array_len(transfer_interfaces); i++ ) { - if (!strcasecmp(transfer_interfaces[i].name, type)) { - /* Depending on the transfer type, the transfer function may change the - * channel state to UP, or last_state, but the transfer function will always result in - * an immediate state change if FTDM_SUCCESS is returned */ - - status = transfer_interfaces[i].func(ftdmchan, transfer_interfaces[i].type, target); - goto done; - } - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid transfer type:%s\n", type); - -done: - if (status != FTDM_SUCCESS) { - ftdm_set_state(ftdmchan, ftdmchan->last_state); - } - - ftdm_safe_free(type); - ftdm_safe_free(target); - return status; -} - -ftdm_status_t sngisdn_att_transfer_process_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf) -{ - ftdm_status_t status = FTDM_SUCCESS; - sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - char *dtmf_digits = sngisdn_info->transfer_data.tdata.att_courtesy_vru.dtmf_digits; - ftdm_size_t dtmf_digits_len = strlen(dtmf_digits); - - dtmf_digits_len += sprintf(&dtmf_digits[dtmf_digits_len], "%s", dtmf); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Transfer response digits:%s\n", dtmf_digits); - if (dtmf_digits_len == 3) { - if (!strcmp(dtmf_digits, SNGISDN_ATT_TRANSFER_RESPONSE_CP_DROP_OFF)) { - sngisdn_info->transfer_data.response = FTDM_TRANSFER_RESPONSE_CP_DROP_OFF; - } else if (!strcmp(dtmf_digits, SNGISDN_ATT_TRANSFER_RESPONSE_LIMITS_EXCEEDED)) { - sngisdn_info->transfer_data.response = FTDM_TRANSFER_RESPONSE_LIMITS_EXCEEDED; - } else if (!strcmp(dtmf_digits, SNGISDN_ATT_TRANSFER_RESPONSE_OK)) { - sngisdn_info->transfer_data.response = FTDM_TRANSFER_RESPONSE_OK; - } else if (!strcmp(dtmf_digits, SNGISDN_ATT_TRANSFER_RESPONSE_INVALID_NUM)) { - sngisdn_info->transfer_data.response = FTDM_TRANSFER_RESPONSE_INVALID_NUM; - } else if (!strcmp(dtmf_digits, SNGISDN_ATT_TRANSFER_RESPONSE_INVALID_COMMAND)) { - sngisdn_info->transfer_data.response = FTDM_TRANSFER_RESPONSE_INVALID_COMMAND; - } else { - sngisdn_info->transfer_data.response = FTDM_TRANSFER_RESPONSE_INVALID; - } - if (signal_data->transfer_timeout) { - ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_CHAN_TIMER_ATT_TRANSFER]); - } - - if (sngisdn_info->transfer_data.response == FTDM_TRANSFER_RESPONSE_OK && - sngisdn_info->transfer_data.type == SNGISDN_TRANSFER_ATT_COURTESY_VRU_DATA) { - sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; - sngisdn_snd_disconnect(ftdmchan); - } - /* Network side will send disconnect in case of NO-DATA Transfer */ - att_courtesy_transfer_complete(sngisdn_info, sngisdn_info->transfer_data.response); - } - - if (signal_data->att_remove_dtmf != SNGISDN_OPT_FALSE) { - /* If we return FTDM_BREAK, dtmf event is not queue'ed to user */ - status = FTDM_BREAK; - } - return status; -} diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_user.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_user.h deleted file mode 100644 index 74abeef94c..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_user.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __FTMOD_SANGOMA_ISDN_USER_H__ -#define __FTMOD_SANGOMA_ISDN_USER_H__ - - -#define SNGISDN_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL }; -#define SNGISDN_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) _TYPE _FUNC1 (const char *name); const char * _FUNC2 (_TYPE type); -#define SNGISDN_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \ - _TYPE _FUNC1 (const char *name) \ - { \ - int i; \ - _TYPE t = _MAX ; \ - \ - for (i = 0; i < _MAX ; i++) { \ - if (!strcasecmp(name, _STRINGS[i])) { \ - t = (_TYPE) i; \ - break; \ - } \ - } \ - return t; \ - } \ - const char * _FUNC2 (_TYPE type) \ - { \ - if (type > _MAX) { \ - type = _MAX; \ - } \ - return _STRINGS[(int)type]; \ - } \ - - -typedef enum { - /* Call is not end-to-end ISDN */ - SNGISDN_PROGIND_DESCR_NETE_ISDN, - /* Destination address is non-ISDN */ - SNGISDN_PROGIND_DESCR_DEST_NISDN, - /* Origination address is non-ISDN */ - SNGISDN_PROGIND_DESCR_ORIG_NISDN, - /* Call has returned to the ISDN */ - SNGISDN_PROGIND_DESCR_RET_ISDN, - /* Interworking as occured and has resulted in a telecommunication service change */ - SNGISDN_PROGIND_DESCR_SERV_CHANGE, - /* In-band information or an appropriate pattern is now available */ - SNGISDN_PROGIND_DESCR_IB_AVAIL, - /* Invalid */ - SNGISDN_PROGIND_DESCR_INVALID, -} ftdm_sngisdn_progind_descr_t; -#define SNGISDN_PROGIND_DESCR_STRINGS "not-end-to-end-isdn", "destination-is-non-isdn", "origination-is-non-isdn", "call-returned-to-isdn", "service-change", "inband-info-available", "invalid" -SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t); - - -typedef enum { - /* User */ - SNGISDN_PROGIND_LOC_USER, - /* Private network serving the local user */ - SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR, - /* Public network serving the local user */ - SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR, - /* Transit network */ - SNGISDN_PROGIND_LOC_TRANSIT_NET, - /* Public network serving remote user */ - SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR, - /* Private network serving remote user */ - SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR, - /* Network beyond the interworking point */ - SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW, - /* Invalid */ - SNGISDN_PROGIND_LOC_INVALID, -} ftdm_sngisdn_progind_loc_t; -#define SNGISDN_PROGIND_LOC_STRINGS "user", "private-net-local-user", "public-net-local-user", "transit-network", "public-net-remote-user", "private-net-remote-user", "beyond-interworking", "invalid" -SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t); - -typedef enum { - /* User Specified */ - SNGISDN_NETSPECFAC_TYPE_USER_SPEC, - /* National network identification */ - SNGISDN_NETSPECFAC_TYPE_NATIONAL_NETWORK_IDENT, - /* International network identification */ - SNGISDN_NETSPECFAC_TYPE_INTERNATIONAL_NETWORK_IDENT, - /* Invalid */ - SNGISDN_NETSPECFAC_TYPE_INVALID, -} ftdm_sngisdn_netspecfac_type_t; -#define SNGISDN_NETSPECFAC_TYPE_STRINGS "user-specified", "national-network-identification", "national-network-identification", "invalid" -SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_netspecfac_type, ftdm_sngisdn_netspecfac_type2str, ftdm_sngisdn_netspecfac_type_t); - -typedef enum { - /* Unknown */ - SNGISDN_NETSPECFAC_PLAN_UNKNOWN, - /* Carrier Identification Code */ - SNGISDN_NETSPECFAC_PLAN_CARRIER_IDENT, - /* Data network identification code */ - SNGISDN_NETSPECFAC_PLAN_DATA_NETWORK_IDENT, - /* Invalid */ - SNGISDN_NETSPECFAC_PLAN_INVALID, -} ftdm_sngisdn_netspecfac_plan_t; -#define SNGISDN_NETSPECFAC_PLAN_STRINGS "unknown", "carrier-identification", "data-network-identification", "invalid" -SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_netspecfac_plan, ftdm_sngisdn_netspecfac_plan2str, ftdm_sngisdn_netspecfac_plan_t); - -typedef enum { - /* Unknown */ - SNGISDN_NETSPECFAC_SPEC_ACCUNET, - SNGISDN_NETSPECFAC_SPEC_MEGACOM, - SNGISDN_NETSPECFAC_SPEC_MEGACOM_800, - SNGISDN_NETSPECFAC_SPEC_SDDN, - SNGISDN_NETSPECFAC_SPEC_INVALID, -} ftdm_sngisdn_netspecfac_spec_t; -#define SNGISDN_NETSPECFAC_SPEC_STRINGS "accunet", "megacom", "megacom-800", "sddn", "invalid" -SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_netspecfac_spec, ftdm_sngisdn_netspecfac_spec2str, ftdm_sngisdn_netspecfac_spec_t); - -#endif /* __FTMOD_SANGOMA_ISDN_USER_H__*/ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c deleted file mode 100644 index 1210e39bb0..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ /dev/null @@ -1,1745 +0,0 @@ -/* - * Copyright (c) 2009|Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms|with or without - * modification|are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice|this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice|this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT - * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, - * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -int ft_to_sngss7_cfg_all(void); - -int ftmod_ss7_relay_gen_config(void); -int ftmod_ss7_mtp1_gen_config(void); -int ftmod_ss7_mtp2_gen_config(void); -int ftmod_ss7_mtp3_gen_config(void); -int ftmod_ss7_isup_gen_config(void); -int ftmod_ss7_cc_gen_config(void); - -int ftmod_ss7_mtp1_psap_config(int id); - -int ftmod_ss7_mtp2_dlsap_config(int id); - -int ftmod_ss7_mtp3_dlsap_config(int id); -int ftmod_ss7_mtp3_nsap_config(int id); -int ftmod_ss7_mtp3_linkset_config(int id); -int ftmod_ss7_mtp3_route_config(int id); - -int ftmod_ss7_isup_nsap_config(int id); -int ftmod_ss7_isup_intf_config(int id); -int ftmod_ss7_isup_ckt_config(int id); -int ftmod_ss7_isup_isap_config(int id); - -int ftmod_ss7_cc_isap_config(int id); - -int ftmod_ss7_relay_chan_config(int id); -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -int ft_to_sngss7_cfg_all(void) -{ - int x = 0; - int ret = 0; - - /* check if we have done gen_config already */ - if (g_ftdm_sngss7_data.gen_config == SNG_GEN_CFG_STATUS_INIT) { - /* update the global gen_config so we don't do it again */ - g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_PENDING; - - /* start of by checking if the license and sig file are valid */ - if (sng_validate_license(g_ftdm_sngss7_data.cfg.license, - g_ftdm_sngss7_data.cfg.signature)) { - - SS7_CRITICAL("License verification failed..ending!\n"); - return 1; - } - - /* if the procId is not 0 then we are using relay mode */ - if (g_ftdm_sngss7_data.cfg.procId != 0) { - /* set the desired procID value */ - sng_set_procId((uint16_t)g_ftdm_sngss7_data.cfg.procId); - } - - /* start up the stack manager */ - if (sng_isup_init_sm()) { - SS7_CRITICAL("Failed to start Stack Manager\n"); - return 1; - } else { - SS7_INFO("Started Stack Manager!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM_STARTED); - } - - /* check if the configuration had a Relay Channel */ - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_PRESENT)) { - /* start up the relay task */ - if (sng_isup_init_relay()) { - SS7_CRITICAL("Failed to start Relay\n"); - return 1; - } else { - SS7_INFO("Started Relay!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_STARTED); - } - - /* run general configuration on the relay task */ - if (ftmod_ss7_relay_gen_config()) { - SS7_CRITICAL("Relay General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("Relay General configuration DONE\n"); - } - - } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) */ - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_PRESENT)) { - if (sng_isup_init_cc()) { - SS7_CRITICAL("Failed to start Call-Control\n"); - return 1; - } else { - SS7_INFO("Started Call-Control!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_STARTED); - } - if (ftmod_ss7_cc_gen_config()) { - SS7_CRITICAL("CC General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("CC General configuration DONE\n"); - } - if (ftmod_ss7_cc_isap_config(1)) { - SS7_CRITICAL("CC ISAP configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("CC ISAP configuration DONE!\n"); - } - } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) */ - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_PRESENT)) { - if (sng_isup_init_isup()) { - SS7_CRITICAL("Failed to start ISUP\n"); - return 1; - } else { - SS7_INFO("Started ISUP!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED); - } - if (ftmod_ss7_isup_gen_config()) { - SS7_CRITICAL("ISUP General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("ISUP General configuration DONE\n"); - } - } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */ - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_PRESENT)) { - if (sng_isup_init_mtp3()) { - SS7_CRITICAL("Failed to start MTP3\n"); - return 1; - } else { - SS7_INFO("Started MTP3!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_STARTED); - } - - if (ftmod_ss7_mtp3_gen_config()) { - SS7_CRITICAL("MTP3 General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP3 General configuration DONE\n"); - } - } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) */ - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_PRESENT)) { - if (sng_isup_init_mtp2()) { - SS7_CRITICAL("Failed to start MTP2\n"); - return 1; - } else { - SS7_INFO("Started MTP2!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED); - } - if (sng_isup_init_mtp1()) { - SS7_CRITICAL("Failed to start MTP1\n"); - return 1; - } else { - SS7_INFO("Started MTP1!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_STARTED); - } - if (ftmod_ss7_mtp1_gen_config()) { - SS7_CRITICAL("MTP1 General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP1 General configuration DONE\n"); - } - if (ftmod_ss7_mtp2_gen_config()) { - SS7_CRITICAL("MTP2 General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP2 General configuration DONE\n"); - } - } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) */ - - if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){ - if(FTDM_SUCCESS != ftmod_ss7_m2ua_init()){ - ftdm_log (FTDM_LOG_ERROR, "ftmod_ss7_m2ua_init FAILED \n"); - return FTDM_FAIL; - } - } - - g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_DONE; - - } /* if (!(g_ftdm_sngss7_data.gen_config)) */ - - - if (g_ftdm_sngss7_data.gen_config != SNG_GEN_CFG_STATUS_DONE) { - SS7_CRITICAL("General configuration FAILED!\n"); - return 1; - } - - x = 1; - while (x < (MAX_MTP_LINKS)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.mtp1Link[x].flags & SNGSS7_CONFIGURED))) { - - /* configure mtp1 */ - if (ftmod_ss7_mtp1_psap_config(x)) { - SS7_CRITICAL("MTP1 PSAP %d configuration FAILED!\n", x); - return 1;; - } else { - SS7_INFO("MTP1 PSAP %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtp1Link[x].flags |= SNGSS7_CONFIGURED; - } - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - x = 1; - while (x < (MAX_MTP_LINKS)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.mtp2Link[x].flags & SNGSS7_CONFIGURED))) { - - /* configure mtp2 */ - if (ftmod_ss7_mtp2_dlsap_config(x)) { - SS7_CRITICAL("MTP2 DLSAP %d configuration FAILED!\n",x); - return 1;; - } else { - SS7_INFO("MTP2 DLSAP %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtp2Link[x].flags |= SNGSS7_CONFIGURED; - } - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - /* no configs above mtp2 for relay */ - if (g_ftdm_sngss7_data.cfg.procId == 1) { - x = 1; - while (x < (MAX_MTP_LINKS)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) { - - /* configure mtp3 */ - if (ftmod_ss7_mtp3_dlsap_config(x)) { - SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x); - return 1;; - } else { - SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED; - } - - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - /* in M2UA_SG mode there will not be any MTP3 layer */ - if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){ - x = 1; - while (x < (MAX_NSAPS)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) { - - ret = ftmod_ss7_mtp3_nsap_config(x); - if (ret) { - SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret)); - return 1; - } else { - SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x); - } - - ret = ftmod_ss7_isup_nsap_config(x); - if (ret) { - SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret)); - return 1; - } else { - SS7_INFO("ISUP NSAP %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED; - } /* if !SNGSS7_CONFIGURED */ - - x++; - } /* while (x < (MAX_NSAPS)) */ - } - - /* in M2UA_SG mode there will not be any MTP3 layer */ - if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){ - x = 1; - while (x < (MAX_MTP_LINKSETS+1)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) { - - if (ftmod_ss7_mtp3_linkset_config(x)) { - SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED; - } /* if !SNGSS7_CONFIGURED */ - - x++; - } /* while (x < (MAX_MTP_LINKSETS+1)) */ - } - - /* in M2UA_SG mode there will not be any MTP3 layer */ - if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){ - x = 1; - while (x < (MAX_MTP_ROUTES+1)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) { - - if (ftmod_ss7_mtp3_route_config(x)) { - SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED; - } /* if !SNGSS7_CONFIGURED */ - - x++; - } /* while (x < (MAX_MTP_ROUTES+1)) */ - } - - x = 1; - while (x < (MAX_ISAPS)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED))) { - - if (ftmod_ss7_isup_isap_config(x)) { - SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("ISUP ISAP %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_CONFIGURED; - } /* if !SNGSS7_CONFIGURED */ - - x++; - } /* while (x < (MAX_ISAPS)) */ - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) { - x = 1; - while (x < (MAX_ISUP_INFS)) { - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED))) { - - if (ftmod_ss7_isup_intf_config(x)) { - SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("ISUP INTF %d configuration DONE!\n", x); - /* set the interface to paused */ - sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= SNGSS7_CONFIGURED; - } /* if !SNGSS7_CONFIGURED */ - - x++; - } /* while (x < (MAX_ISUP_INFS)) */ - } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */ - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - - if (g_ftdm_sngss7_data.cfg.procId > 1) { - break; - } - - /* check if this link has been configured already */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & SNGSS7_CONFIGURED))) { - - if (ftmod_ss7_isup_ckt_config(x)) { - SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("ISUP CKT %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED; - } /* if !SNGSS7_CONFIGURED */ - - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - } - - /* go through all the relays channels and configure it */ - x = 1; - while (x < (MAX_RELAY_CHANNELS)) { - /* check if this relay channel has been configured already */ - if ((g_ftdm_sngss7_data.cfg.relay[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED))) { - - /* send the specific configuration */ - if (ftmod_ss7_relay_chan_config(x)) { - SS7_CRITICAL("Relay Channel %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("Relay Channel %d configuration DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED; - } /* if !SNGSS7_CONFIGURED */ - x++; - } /* while (x < (MAX_RELAY_CHANNELS)) */ - - - if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){ - return ftmod_ss7_m2ua_cfg(); - } - - return 0; -} - -/******************************************************************************/ -int ftmod_ss7_relay_gen_config(void) -{ - RyMngmt cfg; /*configuration structure*/ - Pst pst; /*post structure*/ - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTRY; - - /* clear the configuration structure */ - memset(&cfg, 0x0, sizeof(RyMngmt)); - - /* fill in some general sections of the header */ - smHdrInit(&cfg.hdr); - - /* fill in the post structure */ - smPstInit( &cfg.t.cfg.s.ryGenCfg.lmPst ); - - /*fill in the specific fields of the header */ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTRY; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - cfg.t.cfg.s.ryGenCfg.lmPst.srcEnt = ENTRY; - cfg.t.cfg.s.ryGenCfg.lmPst.dstEnt = ENTSM; - - cfg.t.cfg.s.ryGenCfg.nmbChan = 10; - cfg.t.cfg.s.ryGenCfg.tmrRes = RY_PERIOD; - cfg.t.cfg.s.ryGenCfg.usta = 1; - - - return(sng_cfg_relay(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp1_gen_config(void) -{ - L1Mngmt cfg; /*configuration structure*/ - Pst pst; /*post structure*/ - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTL1; - - /* clear the configuration structure */ - memset(&cfg, 0x0, sizeof(L1Mngmt)); - - /* fill in some general sections of the header */ - smHdrInit(&cfg.hdr); - - /* fill in the post structure */ - smPstInit( &cfg.t.cfg.s.l1Gen.sm ); - - /*fill in the specific fields of the header */ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTL1; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1; - cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM; - - cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS; - cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */ - cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ - - return(sng_cfg_mtp1(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp2_gen_config(void) -{ - SdMngmt cfg; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSD; - - /* clear the configuration structure */ - memset(&cfg, 0x0, sizeof(SdMngmt)); - - /* fill in some general sections of the header */ - smHdrInit(&cfg.hdr); - - /* fill in the post structure */ - smPstInit( &cfg.t.cfg.s.sdGen.sm ); - - /* fill in the specific fields of the header */ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - cfg.t.cfg.s.sdGen.sm.srcEnt = ENTSD; - cfg.t.cfg.s.sdGen.sm.dstEnt = ENTSM; - - cfg.t.cfg.s.sdGen.nmbLnks = MAX_SD_LINKS; - cfg.t.cfg.s.sdGen.poolTrUpper = POOL_UP_TR; - cfg.t.cfg.s.sdGen.poolTrLower = POOL_LW_TR; - - return(sng_cfg_mtp2(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp3_gen_config(void) -{ - SnMngmt cfg; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SnMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /* fill in the post structure */ - smPstInit(&cfg.t.cfg.s.snGen.sm); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - cfg.t.cfg.s.snGen.sm.srcEnt = ENTSN; - cfg.t.cfg.s.snGen.sm.dstEnt = ENTSM; - - - cfg.t.cfg.s.snGen.typeSP = LSN_TYPE_SP; /* type of signalling postatic int */ - cfg.t.cfg.s.snGen.spCode1 = 0; /* our DPC for CCITT version */ -#if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snGen.spCode2 = 0; /* our DPC for ANSI or CHINA version */ -#endif - cfg.t.cfg.s.snGen.ssfValid = TRUE; /* ssf validation required */ - cfg.t.cfg.s.snGen.nmbDLSap = MAX_SN_LINKS; /* number of MTP Data Link SAPs */ - cfg.t.cfg.s.snGen.nmbNSap = MAX_SN_ROUTES; /* number of Upper Layer Saps */ - cfg.t.cfg.s.snGen.nmbRouts = MAX_SN_ROUTES; /* maximum number of routing entries */ - cfg.t.cfg.s.snGen.nmbLnkSets = MAX_SN_LINKSETS; /* number of link sets */ - cfg.t.cfg.s.snGen.nmbRteInst = MAX_SN_ROUTES*16; /* number of simultaneous Rte instances */ - cfg.t.cfg.s.snGen.cbTimeRes = SN_CB_PERIOD; /* link time resolution */ - cfg.t.cfg.s.snGen.spTimeRes = SN_SP_PERIOD; /* general time resolution */ - cfg.t.cfg.s.snGen.rteTimeRes = SN_RTE_PERIOD; /* route time resolution */ - cfg.t.cfg.s.snGen.extCmbndLnkst = FALSE; /* enbale extended combined linkset feature */ - -#if (defined(LSNV3) || defined(SN_MULTIPLE_NETWORK_RESTART)) - -#else - cfg.t.cfg.s.snGen.rstReq = LSN_NO_RST; /* restarting procedure required */ - cfg.t.cfg.s.snGen.tfrReq = FALSE; /* TFR procedure required or not */ - cfg.t.cfg.s.snGen.tmr.t15.enb = TRUE; /* t15 - waiting to start route set congestion test */ - cfg.t.cfg.s.snGen.tmr.t15.val = 30; - cfg.t.cfg.s.snGen.tmr.t16.enb = TRUE; /* t16 - waiting for route set congestion status update */ - cfg.t.cfg.s.snGen.tmr.t16.val = 20; - cfg.t.cfg.s.snGen.tmr.t18.enb = TRUE; /* t18 - waiting for links to become available */ - cfg.t.cfg.s.snGen.tmr.t18.val = 200; - cfg.t.cfg.s.snGen.tmr.t19.enb = TRUE; /* t19 - waiting to receive all traffic restart allowed */ - cfg.t.cfg.s.snGen.tmr.t19.val = 690; - cfg.t.cfg.s.snGen.tmr.t21.enb = TRUE; /* t21 - waiting to restart traffic routed through adjacent SP */ - cfg.t.cfg.s.snGen.tmr.t21.val = 650; -# if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snGen.tmr.t26.enb = TRUE; /* t26 - waiting to repeat traffic restart waiting message for ANSI */ - cfg.t.cfg.s.snGen.tmr.t26.val = 600; -# endif -#endif - -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS96) - cfg.t.cfg.s.snGen.mopc = FALSE; -#endif - - return(sng_cfg_mtp3(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_isup_gen_config(void) -{ - SiMngmt cfg; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* clear the configuration structure */ - memset(&cfg, 0x0, sizeof(SiMngmt)); - - /* fill in some general sections of the header */ - smHdrInit(&cfg.hdr); - - /* fill in the post structure */ - smPstInit( &cfg.t.cfg.s.siGen.sm ); - - /*fill in the specific fields of the header */ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSI; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - cfg.t.cfg.s.siGen.sm.srcEnt = ENTSI; - cfg.t.cfg.s.siGen.sm.dstEnt = ENTSM; - - cfg.t.cfg.s.siGen.nmbSaps = MAX_CC_INTERFACE; /* Number of ISUP Saps */ - cfg.t.cfg.s.siGen.nmbNSaps = MAX_SN_INTERFACE; /* Number of Network Saps */ - cfg.t.cfg.s.siGen.nmbCir = MAX_SI_CIRCUITS; /* Number of circuits */ - cfg.t.cfg.s.siGen.nmbIntf = MAX_SI_INTERFACES; /* Number of interfaces */ - cfg.t.cfg.s.siGen.nmbCirGrp = MAX_SI_CIR_GRP; /* Max number of circuit groups */ - cfg.t.cfg.s.siGen.nmbCalRef = MAX_SI_CALL_REF; /* Number of Call References */ - cfg.t.cfg.s.siGen.timeRes = SI_PERIOD; /* time resolution */ - cfg.t.cfg.s.siGen.sccpSup = FALSE; /* SCCP support */ - cfg.t.cfg.s.siGen.handleTTBinCC = FALSE; /* Flag used for controlling TTB feature */ - cfg.t.cfg.s.siGen.mapCPCandFCI = TRUE; /* Flag used for controlling TTB feature */ -#if (LSIV3 || LSIV4 || LSIV5) - cfg.t.cfg.s.siGen.lnkSelOpt = SI_LINK_SELECTION; /* link selector option */ -#endif - cfg.t.cfg.s.siGen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */ - cfg.t.cfg.s.siGen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ - cfg.t.cfg.s.siGen.cirGrTmr.t18.enb = TRUE; /* t18 timer - group blocking sent */ - cfg.t.cfg.s.siGen.cirGrTmr.t18.val = 300; - cfg.t.cfg.s.siGen.cirGrTmr.t19.enb = TRUE; /* t19 timer - initial group blocking sent */ - cfg.t.cfg.s.siGen.cirGrTmr.t19.val = 3000; - cfg.t.cfg.s.siGen.cirGrTmr.t20.enb = TRUE; /* t20 timer - group unblocking sent */ - cfg.t.cfg.s.siGen.cirGrTmr.t20.val = 300; - cfg.t.cfg.s.siGen.cirGrTmr.t21.enb = TRUE; /* t21 timer - initial grp unblocking sent */ - cfg.t.cfg.s.siGen.cirGrTmr.t21.val = 3000; - cfg.t.cfg.s.siGen.cirGrTmr.t22.enb = TRUE; /* t22 timer - group reset sent */ - cfg.t.cfg.s.siGen.cirGrTmr.t22.val = 300; - cfg.t.cfg.s.siGen.cirGrTmr.t23.enb = TRUE; /* t23 timer - initial group reset sent */ - cfg.t.cfg.s.siGen.cirGrTmr.t23.val = 3000; -#ifndef SS7_UK - cfg.t.cfg.s.siGen.cirGrTmr.t28.enb = TRUE; /* t28 timer - circuit group query sent */ - cfg.t.cfg.s.siGen.cirGrTmr.t28.val = 100; -#endif -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - cfg.t.cfg.s.siGen.cirGrTmr.tFGR.enb = TRUE; /* first group received timer */ - cfg.t.cfg.s.siGen.cirGrTmr.tFGR.val = 50; -#endif -#if CGPN_CHK - cfg.t.cfg.s.siGen.cgPtyNumGenCfg = TRUE; /* Calling party number general config flag */ -#endif -#ifdef SI_SUPPRESS_CFN - cfg.t.cfg.s.siGen.suppressCfn = TRUE; /* Flag used for 'suppress CFN' feature */ -#endif - - return(sng_cfg_isup(&pst, &cfg)); - -} - -/******************************************************************************/ -int ftmod_ss7_cc_gen_config(void) -{ - CcMngmt cfg; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTCC; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(CcMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /* fill in the post structure */ - smPstInit( &cfg.t.cfg.s.ccGen.sm ); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTCC; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STGEN; - - cfg.t.cfg.s.ccGen.sm.srcEnt = ENTCC; - cfg.t.cfg.s.ccGen.sm.dstEnt = ENTSM; - - cfg.t.cfg.s.ccGen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */ - cfg.t.cfg.s.ccGen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ - - return(sng_cfg_cc(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp1_psap_config(int id) -{ - L1Mngmt cfg; - Pst pst; - sng_mtp1_link_t *k = &g_ftdm_sngss7_data.cfg.mtp1Link[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTL1; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(L1Mngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTL1; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STPSAP; - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.l1PSAP.span = k->span; - cfg.t.cfg.s.l1PSAP.chan = k->chan; - cfg.t.cfg.s.l1PSAP.spId = k->id; - - return(sng_cfg_mtp1(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp2_dlsap_config(int id) -{ - SdMngmt cfg; - Pst pst; - sng_mtp2_link_t *k = &g_ftdm_sngss7_data.cfg.mtp2Link[id]; - - /* initalize the post structure */ - smPstInit( &pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSD; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SdMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSD; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLSAP; - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.sdDLSAP.mem.region = S_REG; /* memory region */ - cfg.t.cfg.s.sdDLSAP.mem.pool = S_POOL; /* memory pool */ - cfg.t.cfg.s.sdDLSAP.swtch = k->linkType; /* protocol type */ - cfg.t.cfg.s.sdDLSAP.priorDl = PRIOR0; /* priority for data link layer */ - cfg.t.cfg.s.sdDLSAP.routeDl = RTESPEC; /* route for data link layer */ - cfg.t.cfg.s.sdDLSAP.selectorDl = 0; /* upper interface selector */ - if (k->mtp1ProcId > 0) { - cfg.t.cfg.s.sdDLSAP.dstProcId = k->mtp1ProcId; /* the procid of MAC/L1/MTP1 */ - } else { - cfg.t.cfg.s.sdDLSAP.dstProcId = SFndProcId(); /* the procid of MAC/L1/MTP1 */ - } - cfg.t.cfg.s.sdDLSAP.dstProcId = SFndProcId(); /* the procid of MAC/L1/MTP1 */ - cfg.t.cfg.s.sdDLSAP.entMac = ENTL1; /* entity for MAC */ - cfg.t.cfg.s.sdDLSAP.instMac = S_INST; /* instance for MAC */ - cfg.t.cfg.s.sdDLSAP.priorMac = PRIOR0; /* priority for MAC layer */ - cfg.t.cfg.s.sdDLSAP.routeMac = RTESPEC; /* route for MAC layer */ - cfg.t.cfg.s.sdDLSAP.selectorMac = 0; /* lower interface selector */ - cfg.t.cfg.s.sdDLSAP.memMac.region = S_REG; /* memory region and pool id for MAC */ - cfg.t.cfg.s.sdDLSAP.memMac.pool = S_POOL; - cfg.t.cfg.s.sdDLSAP.maxOutsFrms = MAX_SD_OUTSTANDING; /* maximum outstanding frames */ - cfg.t.cfg.s.sdDLSAP.errType = k->errorType; - cfg.t.cfg.s.sdDLSAP.t1.enb = TRUE; /* timer 1 - Alignment Ready Timer */ - cfg.t.cfg.s.sdDLSAP.t1.val = k->t1; - cfg.t.cfg.s.sdDLSAP.t2.enb = TRUE; /* timer 2 - Not Aligned Timer */ - cfg.t.cfg.s.sdDLSAP.t2.val = k->t2; - cfg.t.cfg.s.sdDLSAP.t3.enb = TRUE; /* timer 3 - Aligned Timer */ - cfg.t.cfg.s.sdDLSAP.t3.val = k->t3; - cfg.t.cfg.s.sdDLSAP.t5.enb = TRUE; /* timer 5 - Sending SIB timer */ - cfg.t.cfg.s.sdDLSAP.t5.val = k->t5; - cfg.t.cfg.s.sdDLSAP.t6.enb = TRUE; /* timer 6 - Remote Congestion Timer */ - cfg.t.cfg.s.sdDLSAP.t6.val = k->t6; - cfg.t.cfg.s.sdDLSAP.t7.enb = TRUE; /* timer 7 - Excessive delay of acknowledgement timer */ - cfg.t.cfg.s.sdDLSAP.t7.val = k->t7; - cfg.t.cfg.s.sdDLSAP.provEmrgcy = k->t4e; /* emergency proving period */ - cfg.t.cfg.s.sdDLSAP.provNormal = k->t4n; /* normal proving period */ - cfg.t.cfg.s.sdDLSAP.lssuLen = k->lssuLength; /* one or two byte LSSU length */ - cfg.t.cfg.s.sdDLSAP.maxFrmLen = MAX_SD_FRAME_LEN; /* max frame length for MSU */ - cfg.t.cfg.s.sdDLSAP.congDisc = FALSE; /* congestion discard TRUE or FALSE */ - cfg.t.cfg.s.sdDLSAP.sdT = MAX_SD_SUERM; /* SUERM error rate threshold */ - cfg.t.cfg.s.sdDLSAP.sdTie = MAX_SD_AERM_EMERGENCY; /* AERM emergency error rate threshold */ - cfg.t.cfg.s.sdDLSAP.sdTin = MAX_SD_AERM_NORMAL; /* AERM normal error rate threshold */ - cfg.t.cfg.s.sdDLSAP.sdN1 = MAX_SD_MSU_RETRANS; /* maximum number of MSUs for retransmission */ - cfg.t.cfg.s.sdDLSAP.sdN2 = MAX_SD_OCTETS_RETRANS; /* maximum number of MSU octets for retrans */ - cfg.t.cfg.s.sdDLSAP.sdCp = MAX_SD_ALIGN_ATTEMPTS; /* maximum number of alignment attempts */ - cfg.t.cfg.s.sdDLSAP.spIdSE = k->mtp1Id; /* service provider id */ - cfg.t.cfg.s.sdDLSAP.sdtFlcStartTr = 256; /* SDT interface flow control start thresh */ - cfg.t.cfg.s.sdDLSAP.sdtFlcEndTr = 512; /* SDT interface flow control end thresh */ - -#ifdef SD_HSL - cfg.t.cfg.s.sdDLSAP.sapType =; /* Indcates whether link is HSL or LSL */ - cfg.t.cfg.s.sdDLSAP.sapFormat =; /* The extened sequence no to be used or not */ - cfg.t.cfg.s.sdDLSAP.t8.enb =; /* timer 8 configuration structure */ - cfg.t.cfg.s.sdDLSAP.sdTe =; /* EIM threshold */ - cfg.t.cfg.s.sdDLSAP.sdUe =; /* increment constant */ - cfg.t.cfg.s.sdDLSAP.sdDe =; /* decrement constant */ -#endif /* HIGH_SPEED_SIGNALING_SUPPORT */ - -#if (SS7_TTC || SS7_NTT) - cfg.t.cfg.s.sdDLSAP.numRtb =; /* outstanding number of messages in RTB */ - cfg.t.cfg.s.sdDLSAP.tf =; /* FISU transmission interval */ - cfg.t.cfg.s.sdDLSAP.tfv =; /* FISU transmission interval during verification */ - cfg.t.cfg.s.sdDLSAP.to =; /* SIO transmission interval */ - cfg.t.cfg.s.sdDLSAP.ta =; /* SIE transmission interval */ - cfg.t.cfg.s.sdDLSAP.ts =; /* SIOS transmission interval */ - cfg.t.cfg.s.sdDLSAP.tso =; /* SIOS transmission duration when out of service */ - cfg.t.cfg.s.sdDLSAP.te =; /* SU normalization time */ -#endif /* (SS7_TTC || SS7_NTT) */ - -#if (SS7_NTT) /* NTTT - Q.703 */ - cfg.t.cfg.s.sdDLSAP.repMsuNack =; /* Nack on receipt of repeated MSU */ - cfg.t.cfg.s.sdDLSAP.invFibIgnore =; /* invalid FIB ignore or bring the link down */ - cfg.t.cfg.s.sdDLSAP.invBsnIgnore =; /* invalid BSN ignore or bring the link down */ - cfg.t.cfg.s.sdDLSAP.congAbatOnNack =; /* congestion abatement on nack or only on acks */ -#endif /* (SS7_NTT) */ - -#ifdef TDS_ROLL_UPGRADE_SUPPORT - cfg.t.cfg.s.sdDLSAP.hlremIntfValid = FALSE; /* Upper Sap Version number valid ? */ - cfg.t.cfg.s.sdDLSAP.remIntfVer = SDTIFVER; /* remote version info */ -#endif /*RUG*/ - - return(sng_cfg_mtp2(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp3_dlsap_config(int id) -{ - Pst pst; - SnMngmt cfg; - sng_mtp3_link_t *k = &g_ftdm_sngss7_data.cfg.mtp3Link[id]; - - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SnMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STDLSAP; - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.snDLSAP.lnkSetId = k->linkSetId; /* link set ID */ - cfg.t.cfg.s.snDLSAP.opc = k->spc; /* Originating Postatic int Code */ - cfg.t.cfg.s.snDLSAP.adjDpc = k->apc; /* Adlacent Destination Postatic int Code */ - cfg.t.cfg.s.snDLSAP.lnkPrior = 0; /* link priority within the link set */ - cfg.t.cfg.s.snDLSAP.msgSize = MAX_SN_MSG_SIZE; /* message length */ - cfg.t.cfg.s.snDLSAP.msgPrior = 0; /* management message priority */ - cfg.t.cfg.s.snDLSAP.lnkType = k->linkType; /* link type ANSI, ITU, BICI or CHINA */ - cfg.t.cfg.s.snDLSAP.upSwtch = k->switchType; /* user part switch type */ - cfg.t.cfg.s.snDLSAP.maxSLTtry = MAX_SLTM_RETRIES; /* maximun times to retry SLTM */ - cfg.t.cfg.s.snDLSAP.p0QLen = 32; /* size of the priority 0 Q */ - cfg.t.cfg.s.snDLSAP.p1QLen = 32; /* size of the priority 1 Q */ - cfg.t.cfg.s.snDLSAP.p2QLen = 32; /* size of the priority 2 Q */ - cfg.t.cfg.s.snDLSAP.p3QLen = 32; /* size of the priority 3 Q */ - cfg.t.cfg.s.snDLSAP.discPrior = 0; /* discard priority */ -#ifndef SDT2 - cfg.t.cfg.s.snDLSAP.maxCredit = MAX_SN_CREDIT; /* max credit */ -#endif /* SDT2 */ - cfg.t.cfg.s.snDLSAP.lnkId = 0; /* signalling link allocation procedure identity */ - cfg.t.cfg.s.snDLSAP.lnkTstSLC = k->slc; /* link selection code for link test */ - cfg.t.cfg.s.snDLSAP.tstLen = 7; /* link test pattern length */ - cfg.t.cfg.s.snDLSAP.tst[0] = 'S'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.tst[1] = 'A'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.tst[2] = 'N'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.tst[3] = 'G'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.tst[4] = 'O'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.tst[5] = 'M'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.tst[6] = 'A'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.ssf = k->ssf; /* sub service field */ - cfg.t.cfg.s.snDLSAP.dstProcId = k->mtp2ProcId; /* destination processor id */ - cfg.t.cfg.s.snDLSAP.dstEnt = ENTSD; /* entity */ - cfg.t.cfg.s.snDLSAP.dstInst = S_INST; /* instance */ - cfg.t.cfg.s.snDLSAP.prior = PRIOR0; /* priority */ - cfg.t.cfg.s.snDLSAP.route = RTESPEC; /* route */ - cfg.t.cfg.s.snDLSAP.selector = 0; /* lower layer selector */ - cfg.t.cfg.s.snDLSAP.mem.region = S_REG; /* memory region id */ - cfg.t.cfg.s.snDLSAP.mem.pool = S_POOL; /* memory pool id */ - cfg.t.cfg.s.snDLSAP.spId = k->mtp2Id; /* service provider id */ - - switch (k->linkType) { - /**************************************************************************/ - case (LSN_SW_ANS): - case (LSN_SW_ANS96): - case (LSN_SW_CHINA): - cfg.t.cfg.s.snDLSAP.dpcLen = DPC24; /* dpc length 24 bits */ - cfg.t.cfg.s.snDLSAP.l2Type = LSN_MTP2_56KBPS; /* layer 2 type - 56kbps MTP2 link, 1.536Mbps MTP2 link or QSAAL link */ - cfg.t.cfg.s.snDLSAP.isCLink = FALSE; /* identifies if the link is a C type link.Required to check if sls has to be rotated.*/ - break; - /**************************************************************************/ - case (LSN_SW_ITU): - cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */ - break; - /**************************************************************************/ - default: - cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */ - break; - /**************************************************************************/ - } /* switch (k->linkType) */ - - switch (k->linkType) { - /**************************************************************************/ - case (LSN_SW_ANS): - case (LSN_SW_ANS96): - cfg.t.cfg.s.snDLSAP.flushContFlag = TRUE; /* flush continue handling */ - break; - /**************************************************************************/ - case (LSN_SW_ITU): - case (LSN_SW_CHINA): - cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */ - break; - /**************************************************************************/ - default: - cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */ - break; - /**************************************************************************/ - } /* switch (k->linkType) */ - - cfg.t.cfg.s.snDLSAP.tmr.t1.enb = TRUE; /* t1 - delay to avoid missequencing on changeover */ - cfg.t.cfg.s.snDLSAP.tmr.t1.val = k->t1; - cfg.t.cfg.s.snDLSAP.tmr.t2.enb = TRUE; /* t2 - waiting for changeover ack */ - cfg.t.cfg.s.snDLSAP.tmr.t2.val = k->t2; - cfg.t.cfg.s.snDLSAP.tmr.t3.enb = TRUE; /* t3 - delay to avoid missequencing on changeback */ - cfg.t.cfg.s.snDLSAP.tmr.t3.val = k->t3; - cfg.t.cfg.s.snDLSAP.tmr.t4.enb = TRUE; /* t4 - waiting for first changeback ack */ - cfg.t.cfg.s.snDLSAP.tmr.t4.val = k->t4; - cfg.t.cfg.s.snDLSAP.tmr.t5.enb = TRUE; /* t5 - waiting for second changeback ack */ - cfg.t.cfg.s.snDLSAP.tmr.t5.val = k->t5; - cfg.t.cfg.s.snDLSAP.tmr.t7.enb = TRUE; /* t7 - waiting for link connection ack */ - cfg.t.cfg.s.snDLSAP.tmr.t7.val = k->t7; - cfg.t.cfg.s.snDLSAP.tmr.t12.enb = TRUE; /* t12 - waiting for uninhibit ack */ - cfg.t.cfg.s.snDLSAP.tmr.t12.val = k->t12; - cfg.t.cfg.s.snDLSAP.tmr.t13.enb = TRUE; /* t13 - waiting for forced uninhibit */ - cfg.t.cfg.s.snDLSAP.tmr.t13.val = k->t13; - cfg.t.cfg.s.snDLSAP.tmr.t14.enb = TRUE; /* t14 - waiting for inhibition ack */ - cfg.t.cfg.s.snDLSAP.tmr.t14.val = k->t14; - cfg.t.cfg.s.snDLSAP.tmr.t17.enb = TRUE; /* t17 - delay to avoid oscillation of initial alignment failure */ - cfg.t.cfg.s.snDLSAP.tmr.t17.val = k->t17; - cfg.t.cfg.s.snDLSAP.tmr.t22.enb = TRUE; /* t22 - local inhibit test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t22.val = k->t22; - cfg.t.cfg.s.snDLSAP.tmr.t23.enb = TRUE; /* t23 - remote inhibit test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t23.val = k->t23; - cfg.t.cfg.s.snDLSAP.tmr.t24.enb = TRUE; /* t24 - stabilizing timer */ - cfg.t.cfg.s.snDLSAP.tmr.t24.val = k->t24; - cfg.t.cfg.s.snDLSAP.tmr.t31.enb = TRUE; /* t31 - BSN requested timer */ - cfg.t.cfg.s.snDLSAP.tmr.t31.val = k->t31; - cfg.t.cfg.s.snDLSAP.tmr.t32.enb = TRUE; /* t32 - SLT timer */ - cfg.t.cfg.s.snDLSAP.tmr.t32.val = k->t32; - cfg.t.cfg.s.snDLSAP.tmr.t33.enb = TRUE; /* t33 - connecting timer */ - cfg.t.cfg.s.snDLSAP.tmr.t33.val = k->t33; - cfg.t.cfg.s.snDLSAP.tmr.t34.enb = TRUE; /* t34 - periodic signalling link test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t34.val = k->t34; -#if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snDLSAP.tmr.t35.enb = TRUE; /* t35 - false link congestion timer, same as t31 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t35.val = k->t35; - cfg.t.cfg.s.snDLSAP.tmr.t36.enb = TRUE; /* t36 - false link congestion timer, same as t33 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t36.val = k->t36; - cfg.t.cfg.s.snDLSAP.tmr.t37.enb = TRUE; /* t37 - false link congestion timer, same as t34 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t37.val = k->t37; - cfg.t.cfg.s.snDLSAP.tmr.tCraft.enb = TRUE; /* link referral craft timer - T19 in ANSI */ - cfg.t.cfg.s.snDLSAP.tmr.tCraft.val = k->tcraft; -#endif -#ifdef SDT2 - cfg.t.cfg.s.snDLSAP.tmr.tFlc.enb = TRUE; /* flow control timer */ - cfg.t.cfg.s.snDLSAP.tmr.tFlc.val = 300; - cfg.t.cfg.s.snDLSAP.tmr.tBnd.enb = TRUE; /* bind request timer */ - cfg.t.cfg.s.snDLSAP.tmr.tBnd.val = 20; -#endif /* SDT2 */ -#ifdef TDS_ROLL_UPGRADE_SUPPORT - cfg.t.cfg.s.snDLSAP.remIntfValid = FALSE; /* remote interface version is valid */ - cfg.t.cfg.s.snDLSAP.remIntfVer = SNTIFVER; /* remote interface version */ -#endif - - return(sng_cfg_mtp3(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp3_nsap_config(int id) -{ - Pst pst; - SnMngmt cfg; - sng_nsap_t *k = &g_ftdm_sngss7_data.cfg.nsap[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SnMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STNSAP; - - cfg.hdr.elmId.elmntInst1 = k->spId; - - cfg.t.cfg.s.snNSAP.ssf = k->ssf; /* sub service field */ - cfg.t.cfg.s.snNSAP.lnkType = k->linkType; /* link type -ANSI, ITU, CHINA or BICI */ - cfg.t.cfg.s.snNSAP.upSwtch = k->switchType; /* user part switch type */ - cfg.t.cfg.s.snNSAP.selector = 0; /* upper layer selector */ - cfg.t.cfg.s.snNSAP.mem.region = S_REG; /* memory region id */ - cfg.t.cfg.s.snNSAP.mem.pool = S_POOL; /* memory pool id */ - cfg.t.cfg.s.snNSAP.prior = PRIOR0; /* priority */ - cfg.t.cfg.s.snNSAP.route = RTESPEC; /* route */ -#if( SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA ) - cfg.t.cfg.s.snNSAP.dpcLen = DPC24; /* dpc length 14 or 24 bits */ -#else - cfg.t.cfg.s.snNSAP.dpcLen = DPC14; /* dpc length 14 or 24 bits */ -#endif -#if (defined(SN_SG) || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snNSAP.usrParts = ; /* user parts configured on self postatic int code on IP side */ -#endif -#ifdef TDS_ROLL_UPGRADE_SUPPORT - cfg.t.cfg.s.snNSAP.remIntfValid = FALSE; /* remote interface version is valid */ - cfg.t.cfg.s.snNSAP.remIntfVer = SNTIFVER; /* remote interface version */ -#endif - - return(sng_cfg_mtp3(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp3_linkset_config(int id) -{ - Pst pst; - SnMngmt cfg; - int c; - sng_link_set_t *k = &g_ftdm_sngss7_data.cfg.mtpLinkSet[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SnMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STLNKSET; /* link set */ - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.snLnkSet.lnkSetId = k->id; /* link set ID */ - cfg.t.cfg.s.snLnkSet.lnkSetType = k->linkType; /* link type */ - cfg.t.cfg.s.snLnkSet.adjDpc = k->apc; /* adjacent DPC */ - cfg.t.cfg.s.snLnkSet.nmbActLnkReqd = k->minActive; /* minimum number of active links */ - cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = k->numLinks; /* number of combined link sets */ - for(c = 0; c < k->numLinks;c++) { - cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].cmbLnkSetId = k->links[c]; - cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].lnkSetPrior = 0; - } - - - return(sng_cfg_mtp3(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp3_route_config(int id) -{ - Pst pst; - SnMngmt cfg; - sng_route_t *k = &g_ftdm_sngss7_data.cfg.mtpRoute[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SnMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSN; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STROUT; - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.snRout.dpc = k->dpc; /* destination postatic int code */ - cfg.t.cfg.s.snRout.spType = LSN_TYPE_SP; /* signalling postatic int type */ - cfg.t.cfg.s.snRout.swtchType = k->linkType; /* switch type */ - cfg.t.cfg.s.snRout.upSwtch = k->switchType; /* user part switch type */ - cfg.t.cfg.s.snRout.cmbLnkSetId = k->cmbLinkSetId; /* combined link set ID */ - if (k->dir == SNG_RTE_UP) { - cfg.t.cfg.s.snRout.dir = LSN_RTE_UP; /* direction */ - } else { - cfg.t.cfg.s.snRout.dir = LSN_RTE_DN; /* direction */ - } - cfg.t.cfg.s.snRout.rteToAdjSp = 0; /* flag indicating this route to adjacent SP */ - cfg.t.cfg.s.snRout.ssf = k->ssf; /* sub service field */ - cfg.t.cfg.s.snRout.brdcastFlg = TRUE; /* flag indicating to have TFP broadcast */ - if (cfg.t.cfg.s.snRout.swtchType == LSN_SW_ITU) { - cfg.t.cfg.s.snRout.rstReq = LSN_ITU92_RST; /* Restart type supported by the node */ - } else if ((cfg.t.cfg.s.snRout.swtchType == LSN_SW_ANS) || - (cfg.t.cfg.s.snRout.swtchType == LSN_SW_ANS96)) { - cfg.t.cfg.s.snRout.rstReq = LSN_ANS_RST; /* Restart type supported by the node */ - } else { - cfg.t.cfg.s.snRout.rstReq = LSN_NO_RST; /* Restart type supported by the node */ - } - if ((cfg.t.cfg.s.snRout.swtchType == LSN_SW_ITU) || - (cfg.t.cfg.s.snRout.swtchType == LSN_SW_CHINA) || - (cfg.t.cfg.s.snRout.swtchType == LSN_SW_BICI)) { - cfg.t.cfg.s.snRout.slsRange = LSN_ITU_SLS_RANGE; /* max value of SLS for this DPC */ - } else { - cfg.t.cfg.s.snRout.slsRange = LSN_ANSI_5BIT_SLS_RANGE; /* max value of SLS for this DPC */ - } - cfg.t.cfg.s.snRout.lsetSel = 0x1; /* linkset selection bit in SLS for STP */ - cfg.t.cfg.s.snRout.multiMsgPrior = TRUE; /* TRUE if multiple cong priorities of messages */ - cfg.t.cfg.s.snRout.rctReq = TRUE; /* route set congestion test required or not */ - cfg.t.cfg.s.snRout.slsLnk = FALSE; -#ifdef LSNV2 -# if (SS7_NTT || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snRout.destSpec =; /* destination specfication A or B*/ -# endif -#endif -#if (defined(LSNV3) || defined(SN_MULTIPLE_NETWORK_RESTART)) - cfg.t.cfg.s.snRout.tfrReq =; /* TFR procedure required or not */ -#endif - cfg.t.cfg.s.snRout.tmr.t6.enb = TRUE; - cfg.t.cfg.s.snRout.tmr.t6.val = k->t6; - cfg.t.cfg.s.snRout.tmr.t8.enb = TRUE; /* t8 - transfer prohibited inhibition timer */ - cfg.t.cfg.s.snRout.tmr.t8.val = k->t8; - cfg.t.cfg.s.snRout.tmr.t10.enb = TRUE; /* t10 - waiting to repeat route set test */ - cfg.t.cfg.s.snRout.tmr.t10.val = k->t10; - cfg.t.cfg.s.snRout.tmr.t11.enb = TRUE; /* t11 - transfer restrict timer */ - cfg.t.cfg.s.snRout.tmr.t11.val = k->t11; - cfg.t.cfg.s.snRout.tmr.t19.enb = TRUE; /* t19 - TRA sent timer */ - cfg.t.cfg.s.snRout.tmr.t19.val = k->t19; - cfg.t.cfg.s.snRout.tmr.t21.enb = TRUE; /* t21 - waiting to restart traffic routed through adjacent SP */ - cfg.t.cfg.s.snRout.tmr.t21.val = k->t21; - -#if (defined(LSNV3) || defined(SN_MULTIPLE_NETWORK_RESTART)) - cfg.t.cfg.s.snRout.tmr.t15.enb = TRUE; /* t15 - waiting to start route set congestion test */ - cfg.t.cfg.s.snRout.tmr.t15.val = k->t15; - cfg.t.cfg.s.snRout.tmr.t16.enb = TRUE; /* t16 - waiting for route set congestion status update */ - cfg.t.cfg.s.snRout.tmr.t16.val = k->t16; - cfg.t.cfg.s.snRout.tmr.t18.enb = TRUE; /* t18 - transfer prohibited inhibition timer */ - cfg.t.cfg.s.snRout.tmr.t18.val = k->t18; -# if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snRout.tmr.t25.enb = TRUE; /* t25 - waiting to traffic resatrt allowed message for ANSI */ - cfg.t.cfg.s.snRout.tmr.t25.val = k->t25; - cfg.t.cfg.s.snRout.tmr.t26.enb = TRUE; /* t26 - waiting to repeat traffic restart waiting message for ANSI */ - cfg.t.cfg.s.snRout.tmr.t26.val = k->t26; -# endif -#endif -#if (SS7_TTC || SS7_NTT || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snRout.tmr.tc.enb = TRUE; /* tc - Waiting for congestion abatement */ - cfg.t.cfg.s.snRout.tmr.tc.val = k->tc; -#endif -#if (defined(SN_SG) || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snRout.tmr.tQry.enb = TRUE; /* Periodic query timer over the NIF */ - cfg.t.cfg.s.snRout.tmr.tQry.val = k->tqry; -#endif - - return(sng_cfg_mtp3(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_isup_nsap_config(int id) -{ - SiMngmt cfg; - Pst pst; - sng_nsap_t *k = &g_ftdm_sngss7_data.cfg.nsap[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SiMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSI; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STNSAP; - - cfg.hdr.elmId.elmntInst1 = k->id; - -#if (SI_LMINT3 || SMSI_LMINT3) - cfg.t.cfg.s.siNSap.nsapId = k->id; /* Id of the NSAP being configured */ -#endif - cfg.t.cfg.s.siNSap.nwId = k->nwId; /* Network Id */ - cfg.t.cfg.s.siNSap.spId = k->spId; /* service providor id */ - cfg.t.cfg.s.siNSap.ssf = k->ssf; /* sub service field */ - cfg.t.cfg.s.siNSap.dstEnt = ENTSN; /* entity */ - cfg.t.cfg.s.siNSap.dstInst = S_INST; /* instance */ - cfg.t.cfg.s.siNSap.prior = PRIOR0; /* priority */ - cfg.t.cfg.s.siNSap.route = RTESPEC; /* route */ - cfg.t.cfg.s.siNSap.dstProcId = SFndProcId(); /* destination processor id */ - cfg.t.cfg.s.siNSap.sapType = SAP_MTP; /* sap type */ - cfg.t.cfg.s.siNSap.selector = 0; /* selector */ - cfg.t.cfg.s.siNSap.tINT.enb = TRUE; /* interface (Bind Confirm) timer */ - cfg.t.cfg.s.siNSap.tINT.val = 50; - cfg.t.cfg.s.siNSap.mem.region = S_REG; /* memory region & pool id */ - cfg.t.cfg.s.siNSap.mem.pool = S_POOL; - -#ifdef TDS_ROLL_UPGRADE_SUPPORT - cfg.t.cfg.s.siNSap.remIntfValid = FALSE; /* remote interface version is valid */ - cfg.t.cfg.s.siNSap.remIntfVer; /* remote interface version */ -#endif - - return(sng_cfg_isup(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_isup_intf_config(int id) -{ - SiMngmt cfg; - Pst pst; - sng_isup_inf_t *k = &g_ftdm_sngss7_data.cfg.isupIntf[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SiMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSI; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = SI_STINTF; - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.siIntfCb.intfId = k->id; /* Interface id */ - cfg.t.cfg.s.siIntfCb.nwId = k->nwId; /* Network Id */ - cfg.t.cfg.s.siIntfCb.sapId = k->isap; /* Id of the Upper ISUP SAP */ - cfg.t.cfg.s.siIntfCb.opc = k->spc; /* physical originating postatic int code */ - cfg.t.cfg.s.siIntfCb.phyDpc = k->dpc; /* physical destination postatic int code */ - cfg.t.cfg.s.siIntfCb.swtch = k->switchType; /* Protocol Switch */ - cfg.t.cfg.s.siIntfCb.ssf = k->ssf; /* subsystem service information */ - cfg.t.cfg.s.siIntfCb.pauseActn = SI_PAUSE_CLRTRAN; /* call clearing behavior upon rx. PAUSE */ - cfg.t.cfg.s.siIntfCb.dpcCbTmr.t4.enb = TRUE; /* t4 timer - user part test sent */ - cfg.t.cfg.s.siIntfCb.dpcCbTmr.t4.val = k->t4; - cfg.t.cfg.s.siIntfCb.dpcCbTmr.tPAUSE.enb = TRUE; /* waiting for PAUSE to be effective */ - cfg.t.cfg.s.siIntfCb.dpcCbTmr.tPAUSE.val = k->tpause; - cfg.t.cfg.s.siIntfCb.dpcCbTmr.tSTAENQ.enb = TRUE; /* status enquiry timer */ - cfg.t.cfg.s.siIntfCb.dpcCbTmr.tSTAENQ.val = k->tstaenq; -#if SS7_ANS95 - cfg.t.cfg.s.siIntfCb.availTest = FALSE; /* circuit validation test */ -#endif -#if (SS7_ITU97 || SS7_ETSIV3 || SS7_UK || SS7_NZL || SS7_ITU2000 || SS7_KZ) - cfg.t.cfg.s.siIntfCb.checkTable = LSI_CHKTBLE_MRATE; /* Validation flag for Table 3 p1/p2 Q.763 */ -#endif -#if (SS7_ANS95 || SS7_ITU97 || SS7_ETSIV3 || SS7_UK || SS7_NZL || SS7_ITU2000 || SS7_KZ) - switch (k->switchType) { - case LSI_SW_TST: - case LSI_SW_ITU: - case LSI_SW_ITU97: - case LSI_SW_ITU2000: - case LSI_SW_ETSI: - case LSI_SW_ETSIV3: - case LSI_SW_RUSSIA: - case LSI_SW_RUSS2000: - case LSI_SW_INDIA: - case LSI_SW_CHINA: - cfg.t.cfg.s.siIntfCb.trunkType = TRUE; /* truck type E1(TRUE)/T1(FALSE) at intf */ - break; - case LSI_SW_ANS88: - case LSI_SW_ANS92: - case LSI_SW_ANS95: - case LSI_SW_BELL: - cfg.t.cfg.s.siIntfCb.trunkType = FALSE; /* truck type E1(TRUE)/T1(FALSE) at intf */ - break; - } - -#endif -#if (LSIV4 || LSIV5) - cfg.t.cfg.s.siIntfCb.lnkSelOpt = LSI_LINSEK_CIC; /* link select option */ -# if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - cfg.t.cfg.s.siIntfCb.lnkSelBits = LSI_LNKSEL_8BITS; /* number of bits for link selection */ -# endif -#endif - - return(sng_cfg_isup(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_isup_ckt_config(int id) -{ - SiMngmt cfg; - Pst pst; - U32 tmp_flag; - sng_isup_ckt_t *k = &g_ftdm_sngss7_data.cfg.isupCkt[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* check the for the correct ProcId and make sure it goes to the right system */ - if (g_ftdm_sngss7_data.cfg.procId != 1) { - pst.dstProcId = 1; - } - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SiMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSI; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STICIR; - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.siCir.cirId = k->id; /* circuit id code */ - cfg.t.cfg.s.siCir.cic = k->cic; /* cic */ - cfg.t.cfg.s.siCir.intfId = k->infId; /* interface id */ - cfg.t.cfg.s.siCir.typeCntrl = k->typeCntrl; /* type of control */ - cfg.t.cfg.s.siCir.contReq = FALSE; /* continuity check required */ -#if (SI_218_COMP || SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - cfg.t.cfg.s.siCir.firstCic = 1; /* First cic in the circuit group */ - cfg.t.cfg.s.siCir.numCir = 24; /* Number of circuits in the circuit group */ - cfg.t.cfg.s.siCir.nonSS7Con = TRUE; /* connecting to non SS7 network */ - cfg.t.cfg.s.siCir.outTrkGrpN.length = 0; /* outgoing trunk group number (For EXM) */ - cfg.t.cfg.s.siCir.cvrTrkClli.length = 0; /* Trunk Group number (For CVR validation) */ - cfg.t.cfg.s.siCir.clli.length = 0; /* common language location identifier */ -#endif - cfg.t.cfg.s.siCir.cirTmr.t3.enb = TRUE; /* t3 timer - overload received */ - cfg.t.cfg.s.siCir.cirTmr.t3.val = k->t3; - cfg.t.cfg.s.siCir.cirTmr.t12.enb = TRUE; /* t12 timer - blocking sent */ - cfg.t.cfg.s.siCir.cirTmr.t12.val = k->t12; - cfg.t.cfg.s.siCir.cirTmr.t13.enb = TRUE; /* t13 timer - initial blocking sent */ - cfg.t.cfg.s.siCir.cirTmr.t13.val = k->t13; - cfg.t.cfg.s.siCir.cirTmr.t14.enb = TRUE; /* t14 timer - unblocking sent */ - cfg.t.cfg.s.siCir.cirTmr.t14.val = k->t14; - cfg.t.cfg.s.siCir.cirTmr.t15.enb = TRUE; /* t15 timer - initial unblocking sent */ - cfg.t.cfg.s.siCir.cirTmr.t15.val = k->t15; - cfg.t.cfg.s.siCir.cirTmr.t16.enb = TRUE; /* t16 timer - reset sent */ - cfg.t.cfg.s.siCir.cirTmr.t16.val = k->t16; - cfg.t.cfg.s.siCir.cirTmr.t17.enb = TRUE; /* t17 timer - initial reset sent */ - cfg.t.cfg.s.siCir.cirTmr.t17.val = k->t17; -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - cfg.t.cfg.s.siCir.cirTmr.tVal.enb = TRUE; /* circuit validation timer */ - cfg.t.cfg.s.siCir.cirTmr.tVal.val = k->tval; -#endif -#if (SS7_ANS95 || SS7_ITU97 || SS7_ETSIV3 || SS7_UK) - tmp_flag = 0x0; - /* bit 0 - 4 is the timeslot on the span for this circuit */ - tmp_flag = ( 1 ); - - /* bit 5 -> can this timeslot be used for contigous M-rate call */ - tmp_flag |= !(0x20); - - /* bit 6 -> does this timeslot support contigous M-rate call */ - tmp_flag |= !(0x40); - - cfg.t.cfg.s.siCir.slotId = tmp_flag ; /* physical slot id bit wise flag */ - cfg.t.cfg.s.siCir.ctrlMult = 0; /* Controller for multirate calls */ -#endif - - tmp_flag = 0x0; - /* bit 0 -> ANSI international support or national support */ - tmp_flag = k->ssf; - - /* bit 1 -> confusion message on */ - tmp_flag |= LSI_CIRFLG_CFN_ON; - - /*bit 2-3 -> circuit group carrier information */ - tmp_flag |= LSI_CFCI_ANALDIG; - - /*bit 4-5 -> alarm carrier */ - tmp_flag |= LSI_CFAC_UNKNOWN; - - /*bit 6-7 -> continuity check requirement*/ - tmp_flag |= LSI_CFCO_NONE; - - cfg.t.cfg.s.siCir.cirFlg = tmp_flag; /* Flag indicating diff cfg options for ckt */ - - return(sng_cfg_isup(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_isup_isap_config(int id) -{ - SiMngmt cfg; - Pst pst; - sng_isap_t *k = &g_ftdm_sngss7_data.cfg.isap[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(SiMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSI; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STISAP; - - cfg.hdr.elmId.elmntInst1 = k->id; - -#if (SI_LMINT3 || SMSI_LMINT3) - cfg.t.cfg.s.siSap.sapId = k->id; /* Id of the SAP being configured */ -#endif - cfg.t.cfg.s.siSap.swtch = k->switchType; /* Protocol Switch */ - cfg.t.cfg.s.siSap.ssf = k->ssf; /* Sub service field */ - cfg.t.cfg.s.siSap.sidIns = FALSE; /* SID insertion Flag */ - cfg.t.cfg.s.siSap.sidVer = FALSE; /* SID verification Flag */ - if ( cfg.t.cfg.s.siSap.sidIns == TRUE ) { /* SID */ - #if 0 - cfg.t.cfg.s.siSap.sid =; - cfg.t.cfg.s.siSap.natAddrInd =; /* SID Nature of Addres Indicator */ - cfg.t.cfg.s.siSap.sidNPlan =; /* SID Numbering Plan */ - cfg.t.cfg.s.siSap.sidPresInd =; /* default presentation indicator */ - cfg.t.cfg.s.siSap.incSidPresRes =; /* Presentation Restriction of incoming SID */ - cfg.t.cfg.s.siSap.sidPresRes =; /* Presentation Restriction */ - #endif - } else { - cfg.t.cfg.s.siSap.sid.length = 0; - /*cfg.t.cfg.s.siSap.sid.strg[0] =*/ - cfg.t.cfg.s.siSap.natAddrInd = ADDR_NOTPRSNT; /* SID Nature of Addres Indicator */ - cfg.t.cfg.s.siSap.sidNPlan = NP_ISDN; /* SID Numbering Plan */ - cfg.t.cfg.s.siSap.sidPresInd = FALSE; /* default presentation indicator */ - cfg.t.cfg.s.siSap.incSidPresRes = FALSE; /* Presentation Restriction of incoming SID */ - cfg.t.cfg.s.siSap.sidPresRes = 0; /* Presentation Restriction */ - } - cfg.t.cfg.s.siSap.reqOpt = FALSE; /* Request option */ - cfg.t.cfg.s.siSap.allCallMod = TRUE; /* call modification allowed flag */ - cfg.t.cfg.s.siSap.maxLenU2U = MAX_SI_USER_2_USER_LEN; /* Max length of user to user messages */ - cfg.t.cfg.s.siSap.passOnFlag = TRUE; /* flag for passing unknown par/msg */ - cfg.t.cfg.s.siSap.relLocation = ILOC_PRIVNETLU; /* release location indicator in cause val */ - cfg.t.cfg.s.siSap.prior = PRIOR0; /* priority */ - cfg.t.cfg.s.siSap.route = RTESPEC; /* route */ - cfg.t.cfg.s.siSap.selector = 0; /* selector */ - cfg.t.cfg.s.siSap.mem.region = S_REG; /* memory region & pool id */ - cfg.t.cfg.s.siSap.mem.pool = S_POOL; /* memory region & pool id */ - - cfg.t.cfg.s.siSap.tmr.t1.enb = TRUE; /* t1 timer - release sent */ - cfg.t.cfg.s.siSap.tmr.t1.val = k->t1; - cfg.t.cfg.s.siSap.tmr.t2.enb = TRUE; /* t2 timer - suspend received */ - cfg.t.cfg.s.siSap.tmr.t2.val = k->t2; - cfg.t.cfg.s.siSap.tmr.t5.enb = TRUE; /* t5 timer - initial release sent */ - cfg.t.cfg.s.siSap.tmr.t5.val = k->t5; - cfg.t.cfg.s.siSap.tmr.t6.enb = TRUE; /* t6 timer - suspend received */ - cfg.t.cfg.s.siSap.tmr.t6.val = k->t6; - cfg.t.cfg.s.siSap.tmr.t7.enb = TRUE; /* t7 timer - latest address sent */ - cfg.t.cfg.s.siSap.tmr.t7.val = k->t7; - cfg.t.cfg.s.siSap.tmr.t8.enb = TRUE; /* t8 timer - initial address received */ - cfg.t.cfg.s.siSap.tmr.t8.val = k->t8; - cfg.t.cfg.s.siSap.tmr.t9.enb = TRUE; /* t9 timer - latest address sent after ACM */ - cfg.t.cfg.s.siSap.tmr.t9.val = k->t9; - cfg.t.cfg.s.siSap.tmr.t27.enb = TRUE; /* t27 timer - wait. for continuity recheck */ - cfg.t.cfg.s.siSap.tmr.t27.val = k->t27; - cfg.t.cfg.s.siSap.tmr.t31.enb = TRUE; /* t31 timer - call reference frozen period */ - cfg.t.cfg.s.siSap.tmr.t31.val = k->t31; - cfg.t.cfg.s.siSap.tmr.t33.enb = TRUE; /* t33 timer - INR sent */ - cfg.t.cfg.s.siSap.tmr.t33.val = k->t33; - cfg.t.cfg.s.siSap.tmr.t34.enb = TRUE; /* t34 timer - wait. for continuity after recheck */ - cfg.t.cfg.s.siSap.tmr.t34.val = k->t34; - cfg.t.cfg.s.siSap.tmr.t36.enb = TRUE; /* waiting SGM */ - cfg.t.cfg.s.siSap.tmr.t36.val = k->t36; - cfg.t.cfg.s.siSap.tmr.tCCR.enb = TRUE; /* tCCR timer - continuity recheck timer */ - cfg.t.cfg.s.siSap.tmr.tCCR.val = k->tccr; - cfg.t.cfg.s.siSap.tmr.tRELRSP.enb = TRUE; /* waiting for release response */ - cfg.t.cfg.s.siSap.tmr.tRELRSP.val = k->trelrsp; - cfg.t.cfg.s.siSap.tmr.tFNLRELRSP.enb = TRUE; /* waiting for final release response */ - cfg.t.cfg.s.siSap.tmr.tFNLRELRSP.val = k->tfnlrelrsp; -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - cfg.t.cfg.s.siSap.tmr.tEx.enb = TRUE; /* tEx timer - Exit to be sent */ - cfg.t.cfg.s.siSap.tmr.tEx.val = k->tex; - cfg.t.cfg.s.siSap.tmr.tCCRt.enb = TRUE; /* tCCR timer (o/g side) - continuity recheck timer */ - cfg.t.cfg.s.siSap.tmr.tCCRt.val = k->tccrt; -#endif -#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL) - cfg.t.cfg.s.siSap.tmr.tCRM.enb = TRUE; /* circuit reservation message timer */ - cfg.t.cfg.s.siSap.tmr.tCRM.val = k->tcrm; - cfg.t.cfg.s.siSap.tmr.tCRA.enb = TRUE; /* circuit reservation ack. timer */ - cfg.t.cfg.s.siSap.tmr.tCRA.val = k->tcra; -#endif -#if (SS7_ETSI || SS7_ITU97 || SS7_ETSIV3 || SS7_UK || SS7_NZL || SS7_KZ) - cfg.t.cfg.s.siSap.tmr.tECT.enb = TRUE; /* Explicit Call Transfer - waiting for loop prvnt rsp */ - cfg.t.cfg.s.siSap.tmr.tECT.val = k->tect; -#endif - -#ifdef TDS_ROLL_UPGRADE_SUPPORT - cfg.t.cfg.s.siSap.remIntfValid = FALSE; /* remote interface version is valid */ - cfg.t.cfg.s.siSap.remIntfVer =; /* remote interface version */ -#endif - - return(sng_cfg_isup(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_cc_isap_config(int dstProcId) -{ - CcMngmt cfg; - Pst pst; - - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTCC; - - /*clear the configuration structure*/ - memset(&cfg, 0x0, sizeof(CcMngmt)); - - /*fill in some general sections of the header*/ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header*/ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTCC; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STISAP; - - cfg.hdr.elmId.elmntInst1 = 1; - - cfg.t.cfg.s.ccISAP.suId = 1; - cfg.t.cfg.s.ccISAP.spId = 1; - cfg.t.cfg.s.ccISAP.pst.dstProcId = dstProcId; - cfg.t.cfg.s.ccISAP.pst.dstEnt = ENTSI; - cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST; - cfg.t.cfg.s.ccISAP.pst.srcProcId = SFndProcId(); - cfg.t.cfg.s.ccISAP.pst.srcEnt = ENTCC; - cfg.t.cfg.s.ccISAP.pst.srcInst = S_INST; - cfg.t.cfg.s.ccISAP.pst.prior = PRIOR0; - cfg.t.cfg.s.ccISAP.pst.route = RTESPEC; - cfg.t.cfg.s.ccISAP.pst.region = S_REG; - cfg.t.cfg.s.ccISAP.pst.pool = S_POOL; - cfg.t.cfg.s.ccISAP.pst.selector = 0; - - return(sng_cfg_cc(&pst, &cfg)); -} - -/******************************************************************************/ -int ftmod_ss7_relay_chan_config(int id) -{ - RyMngmt cfg; /*configuration structure*/ - Pst pst; /*post structure*/ - sng_relay_t *k = &g_ftdm_sngss7_data.cfg.relay[id]; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTRY; - - /* clear the configuration structure */ - memset(&cfg, 0x0, sizeof(RyMngmt)); - - /* fill in some general sections of the header */ - smHdrInit(&cfg.hdr); - - /*fill in the specific fields of the header */ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTRY; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STCHCFG; - - cfg.hdr.elmId.elmntInst1 = k->id; - - cfg.t.cfg.s.ryChanCfg.id = k->id; /* channel id */ - cfg.t.cfg.s.ryChanCfg.type = k->type; /* channel type */ -/* cfg.t.cfg.s.ryChanCfg.msInd =;*/ /* master/slave indicator */ - if (k->type == LRY_CT_TCP_LISTEN) { - cfg.t.cfg.s.ryChanCfg.low = 0; /* low proc id for channel */ - cfg.t.cfg.s.ryChanCfg.high = 0; /* high proc id for channel */ - } else { - cfg.t.cfg.s.ryChanCfg.low = k->procId; /* low proc id for channel */ - cfg.t.cfg.s.ryChanCfg.high = k->procId; /* high proc id for channel */ - } - cfg.t.cfg.s.ryChanCfg.nmbScanQ = MAX_RELAY_NMBSCAN; /* number of times to scan the queue */ - cfg.t.cfg.s.ryChanCfg.flags = LRY_FLG_INTR; /* flags */ - cfg.t.cfg.s.ryChanCfg.congThrsh = MAX_RELAY_CONGTHRSH; /* congestion threshold */ - cfg.t.cfg.s.ryChanCfg.dropThrsh = 0; /* drop threshold */ - cfg.t.cfg.s.ryChanCfg.contThrsh = MAX_RELAY_CONGTHRSH + 1; /* continue threshold */ - cfg.t.cfg.s.ryChanCfg.kaTxTmr.enb = 1; /* keep alive transmit timer config */ - cfg.t.cfg.s.ryChanCfg.kaTxTmr.val = RY_TX_KP_ALIVE_TMR; - cfg.t.cfg.s.ryChanCfg.kaRxTmr.enb = 1; /* keep alive receive timer config */ - cfg.t.cfg.s.ryChanCfg.kaRxTmr.val = RY_RX_KP_ALIVE_TMR; - cfg.t.cfg.s.ryChanCfg.btTmr.enb = 1; /* boot timer */ - cfg.t.cfg.s.ryChanCfg.btTmr.val = RY_BT_TMR; - cfg.t.cfg.s.ryChanCfg.region = S_REG; /* Relay region */ - cfg.t.cfg.s.ryChanCfg.pool = S_POOL; /* Relay pool */ -#if (RY_ENBUDPSOCK || RY_ENBTCPSOCK) - cfg.t.cfg.s.ryChanCfg.listenPortNo = k->port; /* Listen Port of Rx Relay Channel*/ - strncpy(cfg.t.cfg.s.ryChanCfg.transmittoHostName, k->hostname, (size_t)RY_REMHOSTNAME_SIZE); - cfg.t.cfg.s.ryChanCfg.transmittoPortNo = k->port; /* TransmitTo PortId for Tx Relay Channel */ - cfg.t.cfg.s.ryChanCfg.targetProcId = k->procId; /* procId of the node present in the other end of this channel */ -# ifdef LRY1 - cfg.t.cfg.s.ryChanCfg.sockParam =; /* Socket Parameters */ -# endif /* LRY1 */ -# ifdef LRYV2 - cfg.t.cfg.s.ryChanCfg.selfHostName[RY_REMHOSTNAME_SIZE]; -# endif /* LRY2 */ -#endif /* RY_ENBUDPSOCK || RY_ENBTCPSOCK */ - - return(sng_cfg_relay(&pst, &cfg)); -} - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c deleted file mode 100644 index 98a2398630..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ /dev/null @@ -1,4007 +0,0 @@ -/* - * Copyright (c) 2009|Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms|with or without - * modification|are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice|this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice|this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT - * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, - * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * James Zhang - * - */ - -#if 0 -#define SMG_RELAY_DBG -#endif - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data); - -static ftdm_status_t handle_print_usage(ftdm_stream_handle_t *stream); - -static ftdm_status_t handle_show_procId(ftdm_stream_handle_t *stream); - -static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level); -static ftdm_status_t handle_set_message_trace(ftdm_stream_handle_t *stream, int on, int level); -static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *name); - -static ftdm_status_t handle_show_free(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_show_inuse(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, int chan, int verbose); - -static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); - -static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose); - -static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); -static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); - -static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name); - -static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name); - -static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name); - -static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_status_isup_ckt(ftdm_stream_handle_t *stream, char *id_name); - -static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan); -static ftdm_status_t check_arg_count(int args, int min); - - - -static ftdm_status_t cli_ss7_show_general(ftdm_stream_handle_t *stream); - -static ftdm_status_t cli_ss7_show_mtp2link_by_id(ftdm_stream_handle_t *stream, int rcId); -static ftdm_status_t cli_ss7_show_mtp2link_by_name(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t cli_ss7_show_all_mtp2link(ftdm_stream_handle_t *stream); - -static ftdm_status_t cli_ss7_show_mtp3link_by_id(ftdm_stream_handle_t *stream, int rcId); -static ftdm_status_t cli_ss7_show_mtp3link_by_name(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t cli_ss7_show_all_mtp3link(ftdm_stream_handle_t *stream); - -static ftdm_status_t cli_ss7_show_relay_by_id(ftdm_stream_handle_t *stream, int rcId); -static ftdm_status_t cli_ss7_show_relay_by_name(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t cli_ss7_show_all_relay(ftdm_stream_handle_t *stream); - -static ftdm_status_t cli_ss7_show_channel_detail_of_span(ftdm_stream_handle_t *stream, char *span_id, char *chan_id); -static ftdm_status_t cli_ss7_show_all_channels_of_span(ftdm_stream_handle_t *stream, char *span_id); - -static ftdm_status_t cli_ss7_show_span_by_id(ftdm_stream_handle_t *stream, char *span_id); -static ftdm_status_t cli_ss7_show_all_spans_general(ftdm_stream_handle_t *stream); -static ftdm_status_t cli_ss7_show_all_spans_detail(ftdm_stream_handle_t *stream); -static ftdm_status_t handle_show_sctp_profiles(ftdm_stream_handle_t *stream); -static ftdm_status_t handle_show_sctp_profile(ftdm_stream_handle_t *stream, char* sctp_profile_name); -static ftdm_status_t handle_show_m2ua_profiles(ftdm_stream_handle_t *stream); -static ftdm_status_t handle_show_m2ua_profile(ftdm_stream_handle_t *stream, char* m2ua_profile_name); -static ftdm_status_t handle_show_m2ua_peer_status(ftdm_stream_handle_t *stream, char* m2ua_profile_name); -static ftdm_status_t handle_show_m2ua_cluster_status(ftdm_stream_handle_t *stream, char* m2ua_profile_name); -static ftdm_status_t handle_show_nif_profiles(ftdm_stream_handle_t *stream); -static ftdm_status_t handle_show_nif_profile(ftdm_stream_handle_t *stream, char* profile_name); -int get_assoc_resp_buf(char* buf,SbMgmt* cfm); - -/******************************************************************************/ -/* FUNCTIONS ******************************************************************/ -ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data) -{ - char *mycmd = NULL; - char *argv[10] = { 0 }; - int argc = 0; - int span = 0; - int chan = 0; - int range = 0; - int trace = 0; - int trace_level = 7; - int verbose = 1; - int c = 0; - - if (data) { - mycmd = ftdm_strdup(data); - argc = ftdm_separate_string(mycmd, ' ', argv, ftdm_array_len(argv)); - } - - if (check_arg_count(argc, 1)) { - goto handle_cli_error_argc; - } - - if (!strcasecmp(argv[c], "show")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) { - cli_ss7_show_general(stream); - return FTDM_SUCCESS; - } - c++; - - if (!strcasecmp(argv[c], "relay")) { - /**********************************************************************/ - c++; - handle_status_relay(stream, argv[c]); - - } else if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - switch (argc) { - case 2: - { - /* > ftdm ss7 show span */ - cli_ss7_show_all_spans_general(stream); - } - break; - - case 3: - { - if (!strcasecmp(argv[2], "all")) { - /* > ftdm ss7 show span all */ - cli_ss7_show_all_spans_detail(stream); - } else { - /* > ftdm ss7 show span 1 */ - cli_ss7_show_span_by_id(stream, argv[2]); - } - } - break; - - case 4: - { - /* > ftdm ss7 show span 1 chan */ - cli_ss7_show_all_channels_of_span(stream, argv[2]); - } - break; - - case 5: - default: - { - if (!strcasecmp(argv[3], "chan")) { - /* > ftdm ss7 show span 1 chan 2 */ - cli_ss7_show_channel_detail_of_span(stream, argv[2], argv[4]); - } else { - /* > ftdm ss7 show span 1 bla bla bla*/ - cli_ss7_show_all_channels_of_span(stream, argv[2]); - } - } - break; - } - } else if (!strcasecmp(argv[c], "status")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) { - cli_ss7_show_general(stream); - return FTDM_SUCCESS; - } - - c++; - - if (!strcasecmp(argv[c], "mtp3")) { - /******************************************************************/ - c++; - handle_status_mtp3link(stream, argv[c]); - /******************************************************************/ - } else if (!strcasecmp(argv[c], "mtp2")) { - /******************************************************************/ - c++; - handle_status_mtp2link(stream, argv[c]); - /******************************************************************/ - } else if (!strcasecmp(argv[c], "linkset")) { - /******************************************************************/ - c++; - handle_status_linkset(stream, argv[c]); - /******************************************************************/ - } else if (!strcasecmp(argv[c], "relay")) { - /******************************************************************/ - c++; - handle_status_relay(stream, argv[c]); - /******************************************************************/ - } else if (!strcasecmp(argv[c], "span")) { - /******************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_show_status(stream, span, chan, verbose); - /******************************************************************/ - } else if (!strcasecmp(argv[c], "isup")) { - /******************************************************************/ - if (check_arg_count(argc, 4)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "ckt")) { - /**************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - c++; - - handle_status_isup_ckt(stream, argv[c]); - /**************************************************************/ - } else { - /**************************************************************/ - stream->write_function(stream, "Unknown \"status isup\" command\n"); - goto handle_cli_error; - /**************************************************************/ - } - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"status\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "inuse")) { - /**********************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /******************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_show_inuse(stream, span, chan, verbose); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"inuse\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "inreset")) { - /**********************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /******************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_show_inreset(stream, span, chan, verbose); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"inreset\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "free")) { - /**********************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /******************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_show_free(stream, span, chan, verbose); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"free\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "blocks")) { - /**********************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /******************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_show_blocks(stream, span, chan, verbose); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"blocks\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "flags")) { - /**********************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /******************************************************************/ - if (check_arg_count(argc, 6)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_show_flags(stream, span, chan, verbose); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"flags\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "mem")) { - /**********************************************************************/ - sng_isup_reg_info_show(); - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "stats")) { - /**********************************************************************/ -/* sng_mtp1_sts_t sts; - - memset(&sts, 0x0, sizeof(sng_mtp1_sts_t)); - - sng_mtp1_sts(1, &sts); - - stream->write_function(stream,"MTP1 tx stats:|tx_frm=%d|tx_err=%d|tx_fisu=%d|tx_lssu=%d|tx_msu=%d|\n", - sts.tx_frm, sts.tx_err, sts.tx_fisu, sts.tx_lssu, sts.tx_msu); - stream->write_function(stream,"MTP1 rx stats:|rx_frm=%d|rx_err=%d|rx_fisu=%d|rx_lssu=%d|rx_msu=%d|\n", - sts.rx_frm, sts.rx_err, sts.rx_fisu, sts.rx_lssu, sts.rx_msu); -*/ - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "procid")) { - /**********************************************************************/ - handle_show_procId(stream); - - /**********************************************************************/ - } else{ - /**********************************************************************/ - stream->write_function(stream, "Unknown \"show\" command\n"); - goto handle_cli_error; - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "xmlshow")) { - /**************************************************************************/ - - if (check_arg_count(argc, 2)) { - stream->write_function(stream, "Unknown \"xmlshow\" command\n"); - goto handle_cli_error; - } - c++; - /**************************************************************************/ - if (!strcasecmp(argv[c], "m2ua")) { - /**************************************************************************/ - switch(argc) - { - case 2: /* show m2ua */ - { - handle_show_m2ua_profiles(stream); - break; - } - case 3: /* show m2ua */ - { - c++; - handle_show_m2ua_profile(stream, argv[c]); - break; - } - case 4: - { - char* profile_name = argv[++c]; - c++; - /***************************************************************/ - if(!strcasecmp(argv[c],"peerstatus")){ - /***************************************************************/ - handle_show_m2ua_peer_status(stream, profile_name); - /***************************************************************/ - }else if(!strcasecmp(argv[c],"clusterstatus")){ - /***************************************************************/ - handle_show_m2ua_cluster_status(stream, profile_name); - /***************************************************************/ - } else{ - /***************************************************************/ - stream->write_function(stream, "Unknown \"show m2ua \" command..\n"); - goto handle_cli_error_argc; - } - break; - } - default: - goto handle_cli_error_argc; - } - - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "nif")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)){ - handle_show_nif_profiles(stream); - }else{ - c++; - handle_show_nif_profile(stream, argv[c]); - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "sctp")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)){ - handle_show_sctp_profiles(stream); - }else{ - c++; - handle_show_sctp_profile(stream, argv[c]); - } - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"xmlshow\" command\n"); - goto handle_cli_error; - } - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "set")) { - /**************************************************************************/ - if (check_arg_count(argc, 4)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "ftrace")) { - /**********************************************************************/ - c++; - trace = atoi(argv[c]); - c++; - trace_level = atoi(argv[c]); - c++; - handle_set_function_trace(stream, trace, trace_level); - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "mtrace")) { - /**********************************************************************/ - c++; - trace = atoi(argv[c]); - c++; - trace_level = atoi(argv[c]); - c++; - handle_set_message_trace(stream, trace, trace_level); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"set\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "inhibit")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_set_inhibit(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"block\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "uninhibit")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_set_uninhibit(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"unblock\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "blo")) { - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_tx_blo(stream, span, chan, verbose); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"block\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "ubl")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_tx_ubl(stream, span, chan, verbose); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"ubl\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "cgb")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - c = c + 4; - - if (check_arg_count(argc, 7)) goto handle_cli_error_argc; - - if (!strcasecmp(argv[c], "range")) { - /******************************************************************/ - c++; - range = atoi(argv[c]); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"cgb range\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - - handle_tx_cgb(stream, span, chan, range, verbose); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"cgb\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "cgu")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - c = c + 4; - - if (check_arg_count(argc, 7)) goto handle_cli_error_argc; - - if (!strcasecmp(argv[c], "range")) { - /******************************************************************/ - c++; - range = atoi(argv[c]); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"cgu range\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - - handle_tx_cgu(stream, span, chan, range, verbose); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"cgu\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "rsc")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_tx_rsc(stream, span, chan, verbose); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"rsc\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "grs")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - c = c + 4; - - if (check_arg_count(argc, 7)) goto handle_cli_error_argc; - - if (!strcasecmp(argv[c], "range")) { - /******************************************************************/ - c++; - range = atoi(argv[c]); - /******************************************************************/ - } else { - /******************************************************************/ - stream->write_function(stream, "Unknown \"grs range\" command\n"); - goto handle_cli_error; - /******************************************************************/ - } - - handle_tx_grs(stream, span, chan, range, verbose); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"grs\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "lpo")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_tx_lpo(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"lpo\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "lpr")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_tx_lpr(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"lpr\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "bind")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_bind_link(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"bind\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "unbind")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_unbind_link(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"bind\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "activate")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_activate_link(stream, argv[c]); - /**********************************************************************/ - }else if (!strcasecmp(argv[c], "linkset")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_activate_linkset(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"activate\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "deactivate")) { - /**************************************************************************/ - if (check_arg_count(argc, 2)) goto handle_cli_error_argc; - c++; - - if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_deactivate_link(stream, argv[c]); - /**********************************************************************/ - }else if (!strcasecmp(argv[c], "linkset")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_deactivate_linkset(stream, argv[c]); - /**********************************************************************/ - } else { - /**********************************************************************/ - stream->write_function(stream, "Unknown \"deactivate\" command\n"); - goto handle_cli_error; - /**********************************************************************/ - } - /**************************************************************************/ - } else if (!strcasecmp(argv[c], "m2ua")) { - /**************************************************************************/ - if (check_arg_count(argc, 3)) { - stream->write_function(stream, "Invalid \"m2ua option\", please use \"m2ua logging [enable|disable] \n"); - goto handle_cli_error_argc; - } - c++; - if(!strcasecmp(argv[c],"logging")){ - c++; - if(!strcasecmp(argv[c],"enable")){ - ftmod_ss7_enable_m2ua_sg_logging(); - }else if(!strcasecmp(argv[c],"disable")){ - ftmod_ss7_disable_m2ua_sg_logging(); - } else{ - stream->write_function(stream, "Unknown \"m2ua logging %s option\", supported values enable/disable\n",argv[c]); - goto handle_cli_error_argc; - } - }else{ - stream->write_function(stream, "Unknown \"m2ua %s option\", supported values \"logging\"\n",argv[c]); - goto handle_cli_error_argc; - } - /**************************************************************************/ - } else { - /**************************************************************************/ - goto handle_cli_error; - /**************************************************************************/ - } - - return FTDM_SUCCESS; - -handle_cli_error_argc: - stream->write_function(stream, "Invalid # of arguments in command\n"); - handle_print_usage(stream); - return FTDM_SUCCESS; - -handle_cli_error_span_chan: - stream->write_function(stream, "Unknown \"span\\chan\" command\n"); - handle_print_usage(stream); - return FTDM_SUCCESS; - -handle_cli_error: - stream->write_function(stream, "Unknown command requested\n"); - handle_print_usage(stream); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_print_usage(ftdm_stream_handle_t *stream) -{ - stream->write_function(stream, "Sangoma SS7 CLI usage:\n\n"); - - stream->write_function(stream, "ftmod_sangoma_ss7 general control:\n"); - stream->write_function(stream, "ftdm ss7 set ftrace X Y\n"); - stream->write_function(stream, "ftdm ss7 set mtrace X Y\n"); - stream->write_function(stream, "\n"); - - stream->write_function(stream, "ftmod_sangoma_ss7 signaling information:\n"); - stream->write_function(stream, "ftdm ss7 show \n"); - stream->write_function(stream, "ftdm ss7 show status mtp2 X\n"); - stream->write_function(stream, "ftdm ss7 show status mtp3 X\n"); - stream->write_function(stream, "ftdm ss7 show status linkset X\n"); - stream->write_function(stream, "\n"); - - stream->write_function(stream, "ftmod_sangoma_ss7 circuit information:\n"); - stream->write_function(stream, "ftdm ss7 show span all\n"); - stream->write_function(stream, "ftdm ss7 show span X\n"); - stream->write_function(stream, "ftdm ss7 show status span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 show free span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 show blocks span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 show inuse span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 show inreset span X chan Y\n"); - stream->write_function(stream, "\n"); - - stream->write_function(stream, "ftmod_sangoma_ss7 circuit control:\n"); - stream->write_function(stream, "ftdm ss7 blo span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 ubl span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 rsc span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 grs span X chan Y range Z\n"); - stream->write_function(stream, "ftdm ss7 cgb span X chan Y range Z\n"); - stream->write_function(stream, "ftdm ss7 cgu span X chan Y range Z\n"); - stream->write_function(stream, "\n"); - - stream->write_function(stream, "ftmod_sangoma_ss7 link control:\n"); - /* - stream->write_function(stream, "ftdm ss7 inhibit link X\n"); - stream->write_function(stream, "ftdm ss7 uninhibit link X\n"); - */ - stream->write_function(stream, "ftdm ss7 activate link X\n"); - stream->write_function(stream, "ftdm ss7 deactivate link X\n"); - stream->write_function(stream, "ftdm ss7 activate linkset X\n"); - stream->write_function(stream, "ftdm ss7 deactivate linkset X\n"); - stream->write_function(stream, "ftdm ss7 lpo link X\n"); - stream->write_function(stream, "ftdm ss7 lpr link X\n"); - stream->write_function(stream, "\n"); - - - stream->write_function(stream, "ftmod_sangoma_ss7 Relay status:\n"); - stream->write_function(stream, "ftdm ss7 show status relay X\n"); - stream->write_function(stream, "ftdm ss7 show relay X\n"); - stream->write_function(stream, "ftdm ss7 show relay\n"); - stream->write_function(stream, "\n"); - - stream->write_function(stream, "ftmod_sangoma_ss7 M2UA :\n"); - stream->write_function(stream, "ftdm ss7 xmlshow sctp \n"); - stream->write_function(stream, "ftdm ss7 xmlshow sctp \n"); - stream->write_function(stream, "ftdm ss7 xmlshow m2ua \n"); - stream->write_function(stream, "ftdm ss7 xmlshow m2ua \n"); - stream->write_function(stream, "ftdm ss7 xmlshow m2ua peerstatus\n"); - stream->write_function(stream, "ftdm ss7 xmlshow m2ua clusterstatus\n"); - stream->write_function(stream, "ftdm ss7 xmlshow nif \n"); - stream->write_function(stream, "ftdm ss7 xmlshow nif \n"); - stream->write_function(stream, "\n"); - - - stream->write_function(stream, "ftmod_sangoma_ss7 M2UA logging:\n"); - stream->write_function(stream, "ftdm ss7 m2ua logging [enable|disable] \n"); - - stream->write_function(stream, "\n"); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_show_procId(ftdm_stream_handle_t *stream) -{ - int procId = sng_get_procId(); - - stream->write_function(stream, "Local ProcId = %d\n", procId); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level) -{ - stream->write_function(stream, "ftmod_sangoma_ss7 Function Trace was %s, level = %d\n", - (g_ftdm_sngss7_data.function_trace == 1) ? "ON" : "OFF", - g_ftdm_sngss7_data.function_trace_level); - - g_ftdm_sngss7_data.function_trace = on; - g_ftdm_sngss7_data.function_trace_level = level; - - stream->write_function(stream, "ftmod_sangoma_ss7 Function Trace now is %s, level = %d\n", - (g_ftdm_sngss7_data.function_trace == 1) ? "ON" : "OFF", - g_ftdm_sngss7_data.function_trace_level); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_set_message_trace(ftdm_stream_handle_t *stream, int on, int level) -{ - stream->write_function(stream, "ftmod_sangoma_ss7 Message Trace was %s, level = %d\n", - (g_ftdm_sngss7_data.message_trace == 1) ? "ON" : "OFF", - g_ftdm_sngss7_data.message_trace_level); - - g_ftdm_sngss7_data.message_trace = on; - g_ftdm_sngss7_data.message_trace_level = level; - - stream->write_function(stream, "ftmod_sangoma_ss7 Message Trace now is %s, level = %d\n", - (g_ftdm_sngss7_data.message_trace == 1) ? "ON" : "OFF", - g_ftdm_sngss7_data.message_trace_level); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_show_free(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - int free; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - free = 0; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - switch (ftdmchan->state) { - /******************************************************************/ - case (FTDM_CHANNEL_STATE_DOWN): - if (verbose) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|state=%s\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - ss7_info->circuit->cic, - ftdm_channel_state2str(ftdmchan->state)); - } /* if (verbose) */ - - /*increment the count of circuits in reset */ - free++; - break; - /******************************************************************/ - default: - break; - /******************************************************************/ - } /* switch (ftdmchan->state) */ - } /* if ( span and chan) */ - } /* if ( cic != 0) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - stream->write_function(stream, "\nTotal # of CICs free = %d\n",free); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_show_inuse(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - int in_use; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - in_use = 0; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - switch (ftdmchan->state) { - /******************************************************************/ - case (FTDM_CHANNEL_STATE_COLLECT): - case (FTDM_CHANNEL_STATE_RING): - case (FTDM_CHANNEL_STATE_DIALING): - case (FTDM_CHANNEL_STATE_PROGRESS): - case (FTDM_CHANNEL_STATE_PROGRESS_MEDIA): - case (FTDM_CHANNEL_STATE_UP): - case (FTDM_CHANNEL_STATE_TERMINATING): - case (FTDM_CHANNEL_STATE_HANGUP): - if (verbose) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|state=%s\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - ss7_info->circuit->cic, - ftdm_channel_state2str(ftdmchan->state)); - } /* if (verbose) */ - - /*increment the count of circuits in reset */ - in_use++; - break; - /******************************************************************/ - default: - break; - /******************************************************************/ - } /* switch (ftdmchan->state) */ - } /* if ( span and chan) */ - } /* if ( cic != 0) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - stream->write_function(stream, "\nTotal # of CICs in use = %d\n",in_use); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - int in_reset; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - in_reset = 0; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - if ((sngss7_test_ckt_flag(ss7_info, FLAG_RESET_RX)) || - (sngss7_test_ckt_flag(ss7_info, FLAG_RESET_TX)) || - (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_RESET_RX)) || - (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_RESET_TX))) { - - if (verbose) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|in_reset=Y\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - ss7_info->circuit->cic); - } /* if (verbose) */ - - /*increment the count of circuits in reset */ - in_reset++; - } /* if ((sngss7_test_ckt_flag(ss7_info, FLAG_RESET_RX) ... */ - } /* if ( span and chan) */ - } /* if ( cic != 0) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - stream->write_function(stream, "\nTotal # of CICs in reset = %d\n",in_reset); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int x; - int bit; - int lspan; - int lchan; - const char *text; - int flag; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - ss7_info->circuit->cic); - - for (bit = 0; bit < 33; bit++) { - if (ss7_info->ckt_flags & ( 0x1 << bit)) { - stream->write_function(stream, "|"); - flag = bit; - text = ftmod_ss7_ckt_flag2str(flag); - stream->write_function(stream, "%s",text); - } - } - - for (bit = 0; bit < 33; bit++) { - if (ss7_info->blk_flags & ( 0x1 << bit)) { - stream->write_function(stream, "|"); - flag = bit; - text = ftmod_ss7_blk_flag2str(flag); - stream->write_function(stream, "%s",text); - } - } - - stream->write_function(stream, "\n"); - } /* if ( span and chan) */ - - } /* if ( cic != 0) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - ss7_info->circuit->cic); - - if((sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { - stream->write_function(stream, "l_mn=Y|"); - }else { - stream->write_function(stream, "l_mn=N|"); - } - - if((sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { - stream->write_function(stream, "r_mn=Y|"); - }else { - stream->write_function(stream, "r_mn=N|"); - } - - if(sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { - stream->write_function(stream, "l_hw=Y|"); - }else { - stream->write_function(stream, "l_hw=N|"); - } - - if(sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { - stream->write_function(stream, "r_hw=Y|"); - }else { - stream->write_function(stream, "r_hw=N|"); - } - - if(sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { - stream->write_function(stream, "l_mngmt=Y|"); - }else { - stream->write_function(stream, "l_mngmt=N|"); - } - - if(sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { - stream->write_function(stream, "l_ucic=Y|"); - }else { - stream->write_function(stream, "l_ucic=N|"); - } - -#ifdef SMG_RELAY_DBG - stream->write_function(stream," blk_flag=%x | ckt_flag=%x | chan_flag=%x", ss7_info->blk_flags, ss7_info->ckt_flags, ftdmchan->flags); -#endif - stream->write_function(stream, "\n"); - } /* if ( span and chan) */ - - } /* if ( cic != 0) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; - sng_isup_ckt_t *ckt; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /* extract the circuit to make it easier to work with */ - ckt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ckt->span; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ckt->chan; - } else { - lchan = chan; - } - - /* check if this circuit is one of the circuits we're interested in */ - if ((ckt->span == lspan) && (ckt->chan == lchan)) { - if (ckt->type == SNG_CKT_HOLE) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|NOT USED\n", - ckt->span, - ckt->chan, - ckt->cic); - } else if (ckt->type == SNG_CKT_SIG) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|SIGNALING LINK\n", - ckt->span, - ckt->chan, - ckt->cic); - } else { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - if (ftdmchan == NULL) { - /* this should never happen!!! */ - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|FTDMCHAN DOES NOT EXISTS", - ckt->span, - ckt->chan, - ckt->cic); - - } else { - /* grab the signaling_status */ - ftdm_channel_get_sig_status(ftdmchan, &sigstatus); - - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|ckt=%4d|sig_status=%4s|state=%s|", - ckt->span, - ckt->chan, - ckt->cic, - ckt->id, - ftdm_signaling_status2str(sigstatus), - ftdm_channel_state2str(ftdmchan->state)); - - if ((sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX)) || - (sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX))) { - stream->write_function(stream, "l_mn=Y|"); - }else { - stream->write_function(stream, "l_mn=N|"); - } - - if ((sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { - stream->write_function(stream, "r_mn=Y|"); - }else { - stream->write_function(stream, "r_mn=N|"); - } - - if (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { - stream->write_function(stream, "l_hw=Y|"); - }else { - stream->write_function(stream, "l_hw=N|"); - } - - if (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { - stream->write_function(stream, "r_hw=Y|"); - }else { - stream->write_function(stream, "r_hw=N|"); - } - - - if (g_ftdm_sngss7_data.cfg.procId != 1) { - /* if (sngss7_test_ckt_blk_flag(ss7_info, FLAG_RELAY_DOWN)) { */ - stream->write_function(stream, "relay=Y|"); - }else { - stream->write_function(stream, "relay=N"); - } - -#ifdef SMG_RELAY_DBG - stream->write_function(stream, "| flag=0x%llx", ftdmchan->flags); -#endif - } - -#ifdef SMG_RELAY_DBG - stream->write_function(stream," | blk_flag=%x | ckt_flag=%x", ss7_info->blk_flags, ss7_info->ckt_flags); -#endif - stream->write_function(stream, "\n"); - } /* if ( hole, sig, voice) */ - } /* if ( span and chan) */ - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - /* Look spans that are being used by M2UA SG links */ - for (x = 1; x < ftdm_array_len(g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif); x++) { - if (g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[x].id) { - if (g_ftdm_sngss7_data.cfg.mtp2Link[g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[x].mtp2LnkNmb].id) { - uint32_t mtp1_id = g_ftdm_sngss7_data.cfg.mtp2Link[g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[x].mtp2LnkNmb].id; - if (g_ftdm_sngss7_data.cfg.mtp1Link[mtp1_id].id) { - if (g_ftdm_sngss7_data.cfg.mtp1Link[mtp1_id].span == span) { - if (chan) { - if (chan == g_ftdm_sngss7_data.cfg.mtp1Link[mtp1_id].chan) { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|SIGNALING LINK\n", - g_ftdm_sngss7_data.cfg.mtp1Link[mtp1_id].span, - g_ftdm_sngss7_data.cfg.mtp1Link[mtp1_id].chan, - 0); - } - } else { - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|SIGNALING LINK\n", - g_ftdm_sngss7_data.cfg.mtp1Link[mtp1_id].span, - g_ftdm_sngss7_data.cfg.mtp1Link[mtp1_id].chan, - 0); - } - } - } - - } - } - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change|give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); - ftdm_assert(0, "State change not completed\n"); - ftdm_mutex_unlock(ftdmchan->mutex); - continue; - } else { - sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - ftdm_mutex_unlock(ftdmchan->mutex); - } - - } - - x++; - } - - handle_show_blocks(stream, span, chan, verbose); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change|give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); - ftdm_assert(0, "State change not completed\n"); - ftdm_mutex_unlock(ftdmchan->mutex); - continue; - } else { - sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); - sngss7_clear_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); - sngss7_clear_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX); - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - ftdm_mutex_unlock(ftdmchan->mutex); - - } - - } - - /* go the next circuit */ - x++; - } - - handle_show_blocks(stream, span, chan, verbose); - - return FTDM_SUCCESS; -} - - -/******************************************************************************/ -static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *name) -{ - SS7_RELAY_DBG_FUN(handle_status_mtp3link); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Invalid stream\n"); - - if (!name) { - return cli_ss7_show_all_mtp3link(stream); - } - - return cli_ss7_show_mtp3link_by_name(stream, name); -} - - -/******************************************************************************/ -static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *name) -{ - SS7_RELAY_DBG_FUN(handle_status_mtp2link); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Invalid stream\n"); - - if (!name) { - return cli_ss7_show_all_mtp2link(stream); - } - - return cli_ss7_show_mtp2link_by_name(stream, name); -} - -/******************************************************************************/ -static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - SnMngmt sta; - - /* find the linkset request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKSETS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) { - - /* send the status request */ - if (ftmod_ss7_mtplinkSet_sta(x, &sta)) { - stream->write_function(stream, "Failed to read linkset=%s status\n", name); - return FTDM_FAIL; - } - - /* print the results */ - stream->write_function(stream, "%s|state=%s|nmbActLnk=%d\n", - name, - DECODE_LSN_LINKSET_STATUS(sta.t.ssta.s.snLnkSet.state), - sta.t.ssta.s.snLnkSet.nmbActLnks); - - goto success; - } - - /* move to the next linkset */ - x++; - } /* while (id != 0) */ - - stream->write_function(stream, "Failed to find link=\"%s\"\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the inhibit request */ - if (ftmod_ss7_inhibit_mtp3link(x)) { - stream->write_function(stream, "Failed to inhibit link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - - goto success; - } - - /* move to the next linkset */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Failed to find link=\"%s\"\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the uninhibit request */ - if (ftmod_ss7_uninhibit_mtp3link(x)) { - stream->write_function(stream, "Failed to uninhibit link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - - goto success; - } - - /* move to the next linkset */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Failed to find link=\"%s\"\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose) -{ - int x; - sngss7_chan_data_t *sngss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - - /* if span == 0 then all spans should be printed */ - if (span == 0) { - lspan = ftdmchan->physical_span_id; - } else { - lspan = span; - } - - /* if chan == 0 then all chans should be printed */ - if (chan == 0) { - lchan = ftdmchan->physical_chan_id; - } else { - lchan = chan; - } - - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* throw the reset flag */ - sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - sngss7_clear_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_tx_reset_restart(sngss7_info); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - /* go to idle so that we can redo the restart state*/ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - break; - /**************************************************************************/ - default: - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - } /* if ( span and chan) */ - - } /* if ( cic == voice) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - /* print the status of channels */ - handle_show_status(stream, span, chan, verbose); - - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose) -{ - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_span_data_t *sngss7_span = NULL; - int x = 0; - int basefound = 0; - - if (range > 31) { - stream->write_function(stream, "Range value %d is too big for a GRS", range); - return FTDM_SUCCESS; - } - - if (range < 2) { - stream->write_function(stream, "Range value %d is too small for a GRS", range); - return FTDM_SUCCESS; - } - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - sngss7_span = ftdmchan->span->signal_data; - - if ((ftdmchan->physical_span_id == span) && - ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_channel_lock(ftdmchan); - - /* if another reset is still in progress, skip this channel */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX)) { - ftdm_channel_unlock(ftdmchan); - continue; - } - - /* check if there is a pending state change|give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_channel_unlock(ftdmchan); - continue; - } - - /* throw the grp reset flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); - if (!basefound) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Setting channel as GRS base\n"); - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE); - sngss7_info->tx_grs.circuit = sngss7_info->circuit->id; - sngss7_info->tx_grs.range = range - 1; - basefound = 1; - } - - /* set the channel to restart state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - ftdm_channel_unlock(ftdmchan); - - } - - } - - /* go the next circuit */ - x++; - } - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - sngss7_span = ftdmchan->span->signal_data; - - if ((ftdmchan->physical_span_id == span) && - ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { - - handle_show_status(stream, span, chan, verbose); - } - } /* if ( cic == voice) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose) -{ - int x; - sngss7_chan_data_t *sngss7_info; - ftdm_channel_t *ftdmchan; - ftdm_channel_t *main_chan = NULL; - sngss7_span_data_t *sngss7_span; - int byte = 0; - int bit = 0; - ftdm_sigmsg_t sigev; - - memset (&sigev, 0, sizeof (sigev)); - - - if (range <= 1 || range > 31) { - stream->write_function(stream, "Invalid range value %d. Range value must be greater than 1 and less than 31. \n", range); - return FTDM_SUCCESS; - } - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - /* extract the channel and span info for this circuit */ - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - sngss7_span = ftdmchan->span->signal_data; - - /* check if this circuit is part of the block */ - if ((ftdmchan->physical_span_id == span) && - ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_channel_lock(ftdmchan); - - /* throw the grp maint. block flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - /* if this is the first channel in the range */ - if (!main_chan) { - /* attach the cgb information */ - main_chan = ftdmchan; - sngss7_span->tx_cgb.circuit = sngss7_info->circuit->id; - sngss7_span->tx_cgb.range = 0; - sngss7_span->tx_cgb.type = 0; /* maintenace block */ - } else { - ((sngss7_span_data_t*)(main_chan->span->signal_data))->tx_cgb.range++; - } - - /* update the status field */ - sngss7_span->tx_cgb.status[byte] = (sngss7_span->tx_cgb.status[byte] | (1 << bit)); - - /* update the bit and byte counter*/ - bit ++; - if (bit == 8) { - byte++; - bit = 0; - } - - /* unlock the channel again before we exit */ - ftdm_channel_unlock(ftdmchan); - } - } - /* go the next circuit */ - x++; - } - - if (!main_chan) { - stream->write_function(stream, "Failed to find a voice cic in span %d chan %d range %d", span, chan, range); - return FTDM_SUCCESS; - } - - /* send the circuit group block */ - ft_to_sngss7_cgb(main_chan); - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - sngss7_span = ftdmchan->span->signal_data; - - if ((ftdmchan->physical_span_id == span) && - ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { - - handle_show_status(stream, ftdmchan->physical_span_id, ftdmchan->physical_chan_id, verbose); - } - } /* if ( cic == voice) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose) -{ - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - ftdm_channel_t *main_chan = NULL; - sngss7_span_data_t *sngss7_span = NULL; - sngss7_chan_data_t *ubl_sng_info[MAX_CIC_MAP_LENGTH+1]; - int x = 0; - int byte = 0; - int bit = 0; - int ubl_sng_info_idx = 1; - ftdm_sigmsg_t sigev; - - memset(ubl_sng_info, 0, sizeof(ubl_sng_info)); - memset (&sigev, 0, sizeof (sigev)); - - if (range <= 1 || range > 31) { - stream->write_function(stream, "Invalid range value %d. Range value must be greater than 1 and less than 31.\n", range); - return FTDM_SUCCESS; - } - - /* verify that there is not hardware block in the range. - * if there is any channel within the group unblock range, do not execute the group unblock */ - x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - sngss7_span = ftdmchan->span->signal_data; - - if ( (ftdmchan->physical_span_id == span) - && (ftdmchan->physical_chan_id >= chan) - && (ftdmchan->physical_chan_id < (chan+range)) - && sngss7_test_ckt_blk_flag(sngss7_info, (FLAG_GRP_HW_BLOCK_TX | FLAG_GRP_HW_BLOCK_TX_DN)) - ) { - stream->write_function(stream, "There is at least one channel with hardware block. Group unblock operation not allowed at this time.\n"); - return FTDM_SUCCESS; - } - } - x++; - } - - - x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - /* extract the channel and span info for this circuit */ - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - sngss7_span = ftdmchan->span->signal_data; - - /* check if this circuit is part of the block */ - if ((ftdmchan->physical_span_id == span) && - ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_channel_lock(ftdmchan); - - /* throw the grp maint. block flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); - - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN)) { - ubl_sng_info[ubl_sng_info_idx] = sngss7_info; - ubl_sng_info_idx++; - } - - /* bring the sig status up */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* if this is the first channel in the range */ - if (!main_chan) { - /* attach the cgb information */ - main_chan = ftdmchan; - sngss7_span->tx_cgu.circuit = sngss7_info->circuit->id; - sngss7_span->tx_cgu.range = 0; - sngss7_span->tx_cgu.type = 0; /* maintenace block */ - } else { - ((sngss7_span_data_t*)(main_chan->span->signal_data))->tx_cgu.range++; - } - - /* update the status field */ - sngss7_span->tx_cgu.status[byte] = (sngss7_span->tx_cgu.status[byte] | (1 << bit)); - - /* update the bit and byte counter*/ - bit ++; - if (bit == 8) { - byte++; - bit = 0; - } - - /* unlock the channel again before we exit */ - ftdm_channel_unlock(ftdmchan); - } - } - /* go the next circuit */ - x++; - } - - if (!main_chan) { - stream->write_function(stream, "Failed to find a voice cic in span %d chan %d range %d", span, chan, range); - return FTDM_SUCCESS; - } - - /* send the circuit group block */ - ft_to_sngss7_cgu(main_chan); - - /* clearing blocking flags */ - for (x = 1; ubl_sng_info[x]; x++) { - sngss7_info = ubl_sng_info[x]; - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN); - } - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = sngss7_info->ftdmchan; - sngss7_span = ftdmchan->span->signal_data; - - if ((ftdmchan->physical_span_id == span) && - ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { - - handle_show_status(stream, ftdmchan->physical_span_id, ftdmchan->physical_chan_id, verbose); - - } - } /* if ( cic == voice) */ - - /* go the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the uninhibit request */ - if (ftmod_ss7_bind_mtp3link(g_ftdm_sngss7_data.cfg.mtp3Link[x].mtp2Id)) { - stream->write_function(stream, "Failed to bind link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - goto success; - } - - /* move to the next link */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Could not find link=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the uninhibit request */ - if (ftmod_ss7_unbind_mtp3link(g_ftdm_sngss7_data.cfg.mtp3Link[x].mtp2Id)) { - stream->write_function(stream, "Failed to bind link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - goto success; - } - - /* move to the next link */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Could not find link=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the uninhibit request */ - if (ftmod_ss7_activate_mtp3link(x)) { - stream->write_function(stream, "Failed to activate link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - goto success; - } - - /* move to the next link */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Could not find link=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the deactivate request */ - if (ftmod_ss7_deactivate2_mtp3link(x)) { - stream->write_function(stream, "Failed to deactivate link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - goto success; - } - - /* move to the next link */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Could not find link=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the linkset request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKSETS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) { - - /* send the activate request */ - if (ftmod_ss7_activate_mtplinkSet(x)) { - stream->write_function(stream, "Failed to activate linkset=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the linkset */ - handle_status_linkset(stream, &name[0]); - goto success; - } - - /* move to the next linkset */ - x++; - } /* while (id != 0) */ - - stream->write_function(stream, "Could not find linkset=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the linkset request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKSETS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) { - - /* send the deactivate request */ - if (ftmod_ss7_deactivate2_mtplinkSet(x)) { - stream->write_function(stream, "Failed to deactivate linkset=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the linkset */ - handle_status_linkset(stream, &name[0]); - goto success; - } - - /* move to the next linkset */ - x++; - } /* while (id != 0) */ - - stream->write_function(stream, "Could not find linkset=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ - -static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the uninhibit request */ - if (ftmod_ss7_lpo_mtp3link(x)) { - stream->write_function(stream, "Failed set LPO link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - goto success; - } - - /* move to the next link */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Could not find link=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - /* find the link request by it's name */ - x = 1; - while(x < (MAX_MTP_LINKS+1)) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - - /* send the uninhibit request */ - if (ftmod_ss7_lpr_mtp3link(x)) { - stream->write_function(stream, "Failed set LPR link=%s\n", name); - return FTDM_FAIL; - } - - /* print the new status of the link */ - handle_status_mtp3link(stream, &name[0]); - goto success; - } - - /* move to the next link */ - x++; - } /* while (x < (MAX_MTP_LINKS+1)) */ - - stream->write_function(stream, "Could not find link=%s\n", name); - -success: - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *name) -{ - SS7_RELAY_DBG_FUN(handle_status_relay); - if (!name) { - return cli_ss7_show_all_relay(stream); - } - return cli_ss7_show_relay_by_name(stream, name); -} - -/******************************************************************************/ -static ftdm_status_t handle_status_isup_ckt(ftdm_stream_handle_t *stream, char *id_name) -{ - sng_isup_ckt_t *ckt; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - uint32_t id; - uint8_t state = 0; - uint8_t bits_ab = 0; - uint8_t bits_cd = 0; - uint8_t bits_ef = 0; - - /* extract the integer version of the id (ckt) */ - id = atoi(id_name); - - /* extract the global config circuit structure */ - ckt = &g_ftdm_sngss7_data.cfg.isupCkt[id]; - - /* confirm the ckt exists */ - if (ckt->id == 0) { - stream->write_function(stream, "Requested ckt does not exist (%d)\n", id); - return FTDM_FAIL; - } - - /* confirm the ckt is a voice channel */ - if (ckt->type != SNG_CKT_VOICE) { - stream->write_function(stream, "Requested ckt is a sig link/hole and can not be queried (%d)\n", id); - return FTDM_FAIL; - } - - /* extract the global structure */ - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[id].obj; - ftdmchan = ss7_info->ftdmchan; - - /* query the isup stack for the state of the ckt */ - if (ftmod_ss7_isup_ckt_sta(ckt->id, &state)) { - stream->write_function(stream, "Failed to read isup ckt =%d status\n", id); - return FTDM_FAIL; - } - - - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|ckt=%4d|state=0x%02X|", - ckt->span, - ckt->chan, - ckt->cic, - ckt->id, - state); - - /* extract the bit sections */ - bits_ab = (state & (SNG_BIT_A + SNG_BIT_B)) >> 0; - - bits_cd = (state & (SNG_BIT_C + SNG_BIT_D)) >> 2; - - bits_ef = (state & (SNG_BIT_E + SNG_BIT_F)) >> 4; - - /* check bits C and D */ - switch (bits_cd) { - /**************************************************************************/ - case (0): - /* ckt is either un-equipped or transient, check bits A and B */ - switch (bits_ab) { - /**********************************************************************/ - case (0): - /* bit a and bit are cleared, transient */ - stream->write_function(stream, "transient\n"); - goto success; - break; - /**********************************************************************/ - case (1): - case (2): - /* bit a or bit b are set, spare ... shouldn't happen */ - stream->write_function(stream, "spare\n"); - goto success; - break; - /**********************************************************************/ - case (3): - /* bit a and bit b are set, unequipped */ - stream->write_function(stream, "unequipped\n"); - goto success; - break; - /**********************************************************************/ - default: - stream->write_function(stream, "invalid values for bits A and B (%d)\n", - bits_ab); - goto success; - break; - /**********************************************************************/ - } /* switch (bits_ab) */ - - /* shouldn't get here but have a break for properness */ - break; - /**************************************************************************/ - case (1): - /* circuit incoming busy */ - stream->write_function(stream, "incoming busy"); - break; - /**************************************************************************/ - case (2): - /* circuit outgoing busy */ - stream->write_function(stream, "outgoing busy"); - break; - /**************************************************************************/ - case (3): - /* circuit idle */ - stream->write_function(stream, "idle"); - break; - /**************************************************************************/ - default: - /* invalid */ - stream->write_function(stream, "bits C and D are invalid (%d)!\n", - bits_cd); - goto success; - /**************************************************************************/ - } /* switch (bits_cd) */ - - /* check the maintenance block status in bits A and B */ - switch (bits_ab) { - /**************************************************************************/ - case (0): - /* no maintenace block...do nothing */ - break; - /**************************************************************************/ - case (1): - /* locally blocked */ - stream->write_function(stream, "|l_mn"); - break; - /**************************************************************************/ - case (2): - /* remotely blocked */ - stream->write_function(stream, "|r_mn"); - break; - /**************************************************************************/ - case (3): - /* both locally and remotely blocked */ - stream->write_function(stream, "|l_mn|r_mn"); - break; - /**************************************************************************/ - default: - stream->write_function(stream, "bits A and B are invlaid (%d)!\n", - bits_ab); - goto success; - /**************************************************************************/ - } /* switch (bits_ab) */ - - /* check the hardware block status in bits e and f */ - switch (bits_ef) { - /**************************************************************************/ - case (0): - /* no maintenace block...do nothing */ - break; - /**************************************************************************/ - case (1): - /* locally blocked */ - stream->write_function(stream, "|l_hw"); - break; - /**************************************************************************/ - case (2): - /* remotely blocked */ - stream->write_function(stream, "|r_hw"); - break; - /**************************************************************************/ - case (3): - /* both locally and remotely blocked */ - stream->write_function(stream, "|l_hw|r_hw"); - break; - /**************************************************************************/ - default: - stream->write_function(stream, "bits E and F are invlaid (%d)!\n", - bits_ef); - goto success; - /**************************************************************************/ - } /* switch (bits_ef) */ - -success: - stream->write_function(stream, "\n"); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan) -{ - - if (!strcasecmp(argv[pos], "span")) { - /**************************************************************************/ - pos++; - *span = atoi(argv[pos]); - - pos++; - if (!strcasecmp(argv[pos], "chan")) { - /**********************************************************************/ - pos++; - *chan = atoi(argv[pos]); - /**********************************************************************/ - } else { - /**********************************************************************/ - return FTDM_FAIL; - /**********************************************************************/ - } - /**************************************************************************/ - } else { - /**************************************************************************/ - *span = atoi(argv[pos]); - - pos++; - if (!strcasecmp(argv[pos], "chan")) { - /**********************************************************************/ - pos++; - *chan = atoi(argv[pos]); - /**********************************************************************/ - } else { - /**********************************************************************/ - return FTDM_FAIL; - /**********************************************************************/ - } - /**************************************************************************/ - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t check_arg_count(int args, int min) -{ - if ( args < min ) { - return FTDM_FAIL; - } else { - return FTDM_SUCCESS; - } -} - - -/****************************************************************************** -* Fun: cli_ss7_show_mtp2link_by_id() -* Desc: display mtp3 link information with id -* Param: -* stream : output stream object -* rcId : mtp2 link's id -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_mtp2link_by_id(ftdm_stream_handle_t *stream, int rcId) -{ - SdMngmt sta; - - SS7_RELAY_DBG_FUN(cli_ss7_show_mtp2link_by_id); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - if (ftmod_ss7_mtp2link_sta(rcId, &sta)) { - stream->write_function(stream, "Failed to read status of MTP2 link, id=%d \n", rcId); - return FTDM_FAIL; - } - - stream->write_function(stream, "name=%s|span=%d|chan=%d|sap=%d|state=%s|outsFrm=%d|drpdFrm=%d|lclStatus=%s|rmtStatus=%s|fsn=%d|bsn=%d\n", - g_ftdm_sngss7_data.cfg.mtp2Link[rcId].name, - g_ftdm_sngss7_data.cfg.mtp1Link[rcId].span, - g_ftdm_sngss7_data.cfg.mtp1Link[rcId].chan, - g_ftdm_sngss7_data.cfg.mtp2Link[rcId].id, - DECODE_LSD_LINK_STATUS(sta.t.ssta.s.sdDLSAP.hlSt), - sta.t.ssta.s.sdDLSAP.psOutsFrm, - sta.t.ssta.s.sdDLSAP.cntMaDrop, - (sta.t.ssta.s.sdDLSAP.lclBsy) ? "Y":"N", - (sta.t.ssta.s.sdDLSAP.remBsy) ? "Y":"N", - sta.t.ssta.s.sdDLSAP.fsn, - sta.t.ssta.s.sdDLSAP.bsn - ); - - return FTDM_SUCCESS; -} - -/****************************************************************************** -* Fun: cli_ss7_show_mtp2link_by_name() -* Desc: display all relay channels information -* Param: -* stream : output stream object -* rcName: mtp2 link's name -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_mtp2link_by_name(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - SS7_RELAY_DBG_FUN(cli_ss7_show_mtp2link_by_name); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - ftdm_assert_return(!ftdm_strlen_zero(name), FTDM_FAIL, "Null MTP2 link name\n"); - - for (x = 0; x < (MAX_MTP_LINKS + 1); x++) { - if (0 == strcasecmp(g_ftdm_sngss7_data.cfg.mtp2Link[x].name, name)) { - return cli_ss7_show_mtp2link_by_id( stream, x ); - } - } - - stream->write_function (stream, "The MTP2 link with name \'%s\' is not found. \n", name); - return FTDM_FAIL; -} - -/****************************************************************************** -* Fun: cli_ss7_show_all_mtp2link() -* Desc: display all mtp2 links information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_all_mtp2link(ftdm_stream_handle_t *stream) -{ - int x = 0; - - SS7_RELAY_DBG_FUN(cli_ss7_show_all_mtp2link); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - for (x = 0; x < (MAX_MTP_LINKS + 1); x++) { - if (!ftdm_strlen_zero( g_ftdm_sngss7_data.cfg.mtp2Link[x].name)) { - cli_ss7_show_mtp2link_by_id(stream, x ); - } - } - - return FTDM_SUCCESS; -} - -/****************************************************************************** -* Fun: cli_ss7_show_mtp3link_by_id() -* Desc: display mtp3 link information with id -* Param: -* stream : output stream object -* rcId : mtp3 link's id -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_mtp3link_by_id(ftdm_stream_handle_t *stream, int rcId) -{ - SnMngmt sta; - - SS7_RELAY_DBG_FUN(cli_ss7_show_mtp3link_by_id); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - memset(&sta, 0, sizeof(sta)); - if (ftmod_ss7_mtp3link_sta(rcId, &sta)) { - stream->write_function(stream, "Failed to read status of MTP3 link, id=%d \n", rcId); - return FTDM_FAIL; - } - - stream->write_function(stream, "name=%s|span=%d|chan=%d|sap=%d|state=%s|l_blk=%s|r_blk=%s|l_inhbt=%s|r_inhbt=%s\n", - g_ftdm_sngss7_data.cfg.mtp3Link[rcId].name, - g_ftdm_sngss7_data.cfg.mtp1Link[rcId].span, - g_ftdm_sngss7_data.cfg.mtp1Link[rcId].chan, - g_ftdm_sngss7_data.cfg.mtp3Link[rcId].id, - DECODE_LSN_LINK_STATUS(sta.t.ssta.s.snDLSAP.state), - (sta.t.ssta.s.snDLSAP.locBlkd) ? "Y":"N", - (sta.t.ssta.s.snDLSAP.remBlkd) ? "Y":"N", - (sta.t.ssta.s.snDLSAP.locInhbt) ? "Y":"N", - (sta.t.ssta.s.snDLSAP.rmtInhbt) ? "Y":"N" - ); - - return FTDM_SUCCESS; -} - -/****************************************************************************** -* Fun: cli_ss7_show_mtp3link_by_name() -* Desc: display all relay channels information -* Param: -* stream : output stream object -* rcName: mtp3 link's name -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_mtp3link_by_name(ftdm_stream_handle_t *stream, char *name) -{ - int x=0; - SS7_RELAY_DBG_FUN(cli_ss7_show_mtp3link_by_name); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - ftdm_assert_return(!ftdm_strlen_zero(name), FTDM_FAIL, "Null MTP3 link name\n"); - - for (x = 0; x < (MAX_MTP_LINKS + 1); x++) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { - return cli_ss7_show_mtp3link_by_id(stream, x ); - } - } - - stream->write_function(stream, "The MTP3 link with name \'%s\' is not found. \n", name); - return FTDM_FAIL; -} -/****************************************************************************** -* Fun: cli_ss7_show_all_mtp3link() -* Desc: display all mtp3 links information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_all_mtp3link(ftdm_stream_handle_t *stream) -{ - int x = 0; - - SS7_RELAY_DBG_FUN(cli_ss7_show_all_mtp3link); - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - for (x = 0; x < (MAX_MTP_LINKS + 1); x++) { - if (!ftdm_strlen_zero(g_ftdm_sngss7_data.cfg.mtp3Link[x].name)) { - cli_ss7_show_mtp3link_by_id(stream, x); - } - } - - return FTDM_SUCCESS; -} - - -/****************************************************************************** -* Fun: cli_ss7_show_all_linkset() -* Desc: display all mtp3 linksets information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_all_linkset(ftdm_stream_handle_t *stream) -{ - int x = 0; - SnMngmt sta; - - SS7_RELAY_DBG_FUN(cli_ss7_show_all_linkset); - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - x = 1; - while(x < (MAX_MTP_LINKSETS+1)) { - if (!ftdm_strlen_zero(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name)) { - if (ftmod_ss7_mtplinkSet_sta(x, &sta)) { - stream->write_function(stream, "Failed to read linkset=%s status\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); - } else { - stream->write_function(stream, "name=%s|state=%s|nmbActLnk=%d\n", - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, - DECODE_LSN_LINKSET_STATUS(sta.t.ssta.s.snLnkSet.state), sta.t.ssta.s.snLnkSet.nmbActLnks - ); - } - } - x++; - } - return FTDM_SUCCESS; -} - - -/****************************************************************************** -* Fun: cli_ss7_show_general() -* Desc: display all general information about ss7 -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_general(ftdm_stream_handle_t *stream) -{ - SS7_RELAY_DBG_FUN(cli_ss7_show_general); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - stream->write_function(stream, "MTP2 status: \n"); - cli_ss7_show_all_mtp2link(stream); - - if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){ - stream->write_function(stream, "\nMTP3 status: \n"); - cli_ss7_show_all_mtp3link(stream); - - stream->write_function(stream, "\nMTP3 linkset status: \n"); - cli_ss7_show_all_linkset(stream); - -#if 0 - stream->write_function(stream, "\nMTP3 link route status: \n"); - - stream->write_function(stream, "\nISUP status: \n"); -#endif - - stream->write_function(stream, "\nRelay status: \n"); - cli_ss7_show_all_relay(stream); - } - - return FTDM_SUCCESS; -} - -/****************************************************************************** -* Fun: cli_ss7_show_relay_by_id() -* Desc: display all relay channels information -* Param: -* stream : output stream object -* rcId : channel's id -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_relay_by_id(ftdm_stream_handle_t *stream, int rcId) -{ - RyMngmt sta; - - SS7_RELAY_DBG_FUN(cli_ss7_show_relay_by_id); - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - memset(&sta, 0x0, sizeof(sta)); - if (ftmod_ss7_relay_status(g_ftdm_sngss7_data.cfg.relay[rcId].id, &sta)) { - stream->write_function(stream, "Failed to read relay =%s status\n", g_ftdm_sngss7_data.cfg.relay[rcId].name); - return FTDM_FAIL; - } - - stream->write_function(stream, "name=%s|sap=%d|type=%d|port=%d|hostname=%s|procId=%d|status=%s\n", - g_ftdm_sngss7_data.cfg.relay[rcId].name, - g_ftdm_sngss7_data.cfg.relay[rcId].id, - g_ftdm_sngss7_data.cfg.relay[rcId].type, - g_ftdm_sngss7_data.cfg.relay[rcId].port, - g_ftdm_sngss7_data.cfg.relay[rcId].hostname, - g_ftdm_sngss7_data.cfg.relay[rcId].procId, - DECODE_LRY_CHAN_STATUS(sta.t.ssta.rySta.cStatus) - ); - - return FTDM_SUCCESS; -} -/****************************************************************************** -* Fun: cli_ss7_show_relay_by_name() -* Desc: display all relay channels information -* Param: -* stream : output stream object -* rcName: channel's name -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_relay_by_name(ftdm_stream_handle_t *stream, char *name) -{ - int x = 0; - - SS7_RELAY_DBG_FUN(cli_ss7_show_relay_by_name); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - ftdm_assert_return(!ftdm_strlen_zero(name), FTDM_FAIL, "Null relay link name\n"); - - for (x = 1; x < MAX_RELAY_CHANNELS; x++) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.relay[x].name, name)) { - return cli_ss7_show_relay_by_id(stream, x); - } - } - - stream->write_function( stream, "The relay channel with name \'%s\' is not found. \n", name); - return FTDM_FAIL; - -} -/****************************************************************************** -* Fun: cli_ss7_show_all_relay() -* Desc: display all relay channels information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_all_relay(ftdm_stream_handle_t *stream) -{ - int x = 0; - SS7_RELAY_DBG_FUN(cli_ss7_show_relay_by_name); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - - for (x = 1; x < MAX_RELAY_CHANNELS; x++) { - if (!ftdm_strlen_zero(g_ftdm_sngss7_data.cfg.relay[x].name)) { - cli_ss7_show_relay_by_id (stream, x); - } - } - - return FTDM_SUCCESS; -} - - -/****************************************************************************** -* Fun: cli_ss7_show_channel_detail_of_span() -* Desc: display span information of a given id -* Param: -* stream : output stream object -* span_id : span id string received from cli -* chan_id : channel id string received from cli -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_channel_detail_of_span(ftdm_stream_handle_t *stream, char *span_id, char *chan_id) -{ - int x, y; - - SS7_RELAY_DBG_FUN(cli_ss7_show_channel_detail_of_span); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - ftdm_assert_return(span_id != 0, FTDM_FAIL, "Invalid span id\n"); - ftdm_assert_return(chan_id != 0, FTDM_FAIL, "Invalid chan id\n"); - - x = atoi(span_id); - y = atoi(chan_id); - if (!x) { - stream->write_function( stream, "Span \'%s\' does not exist. \n", span_id); - return FTDM_FAIL; - } - - return handle_show_status(stream, x, y, 1); -} - -/****************************************************************************** -* Fun: cli_ss7_show_all_channels_of_span() -* Desc: display span information of a given id -* Param: -* stream : output stream object -* span_id : span id string received from cli -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_all_channels_of_span(ftdm_stream_handle_t *stream, char *span_id) -{ - int x=-1; - SS7_RELAY_DBG_FUN(cli_ss7_show_all_channels_of_span); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - ftdm_assert_return(span_id != 0, FTDM_FAIL, "Invalid span id\n"); - - x = atoi(span_id); - if (!x) { - stream->write_function( stream, "Span \'%s\' does not exist. \n", span_id); - return FTDM_FAIL; - } - return handle_show_status(stream, x, 0, 1); -} - -/****************************************************************************** -* Fun: cli_ss7_show_span_by_id() -* Desc: display span information of a given id -* Param: -* stream : output stream object -* span_id : span id string received from cli -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_span_by_id(ftdm_stream_handle_t *stream, char *span_id) -{ - int x = -1; - - SS7_RELAY_DBG_FUN(cli_ss7_show_span_by_id); - - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - ftdm_assert_return(span_id != 0, FTDM_FAIL, "Invalid span id\n"); - - x = atoi(span_id); - if (!x) { - stream->write_function(stream, "Span \'%s\' does not exist. \n", span_id); - return FTDM_FAIL; - } - -#if 0 - stream->write_function( stream, "JZ: we should display span details here \n" ); -#endif - - cli_ss7_show_all_channels_of_span(stream, span_id); - - return FTDM_FAIL; -} - - -/****************************************************************************** -* Fun: cli_ss7_show_all_spans_detail() -* Desc: display all spans information in detail -* Param: -* stream : output stream object -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_all_spans_detail(ftdm_stream_handle_t *stream) -{ - SS7_RELAY_DBG_FUN(cli_ss7_show_all_spans_detail); - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - return handle_show_status(stream, 0, 0, 1); -} - -/****************************************************************************** -* Fun: cli_ss7_show_all_spans_general() -* Desc: display all spans information in general -* Param: -* stream : output stream object -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: James Zhang -*******************************************************************************/ -static ftdm_status_t cli_ss7_show_all_spans_general(ftdm_stream_handle_t *stream) -{ - SS7_RELAY_DBG_FUN(cli_ss7_show_all_spans_general); - ftdm_assert_return(stream != NULL, FTDM_FAIL, "Null stream\n"); - return FTDM_FAIL; -} - - -/****************************************************************************** -* Fun: handle_show_m2ua_profiles() -* Desc: display all m2ua profile information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ - -static ftdm_status_t handle_show_m2ua_profiles(ftdm_stream_handle_t *stream) -{ - MwMgmt cfm; - MwMgmt rsp; - char buf[2048]; - char* xmlhdr = (char*)""; - int x = 0x00; - int idx = 0x00; - int len = 0x00; - - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - memset((U8 *)&rsp, 0, sizeof(MwMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - len = len + sprintf(buf + len, "\n"); - - if(ftmod_m2ua_ssta_req(STMWGEN, 0x00, &cfm)) { - stream->write_function(stream," Request to layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); -#ifdef BIT_64 - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.genSta.memSize); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.genSta.memAlloc); -#else - len = len + sprintf(buf + len, " %ld \n", cfm.t.ssta.s.genSta.memSize); - len = len + sprintf(buf + len, " %ld \n", cfm.t.ssta.s.genSta.memAlloc); -#endif - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.genSta.nmbClusters); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.genSta.nmbPeers); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.genSta.nmbIntf); - len = len + sprintf(buf + len, "\n"); - } - - /*iterate through all the m2ua links and prints all information */ - x = 1; - while(x\n"); - len = len + sprintf(buf + len, " %s \n", g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[x].name); - - if(ftmod_m2ua_ssta_req(STMWDLSAP,x,&cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_SAP_STATE(cfm.t.ssta.s.dlSapSta.state)); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_LINK_STATE(cfm.t.ssta.s.dlSapSta.lnkState)); - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.rpoEnable); - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.lpoEnable); - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.congLevel); - len = len + sprintf(buf + len, "\n"); - } - - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - if(ftmod_m2ua_ssta_req(STMWCLUSTER,g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[x].clusterId,&cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_CLUSTER_STATE(cfm.t.ssta.s.clusterSta.state)); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.clusterSta.nmbPeer); - len = len + sprintf(buf + len, "\n"); - for(idx = 0; idx < cfm.t.ssta.s.clusterSta.nmbPeer; idx++) - { - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.clusterSta.peerSt[idx].peerId); - len = len + sprintf(buf + len, " %s \n", PRNT_M2UA_PEER_STATE(cfm.t.ssta.s.clusterSta.peerSt[idx].peerState)); - } - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.clusterSta.nmbActPeer); - - len = len + sprintf(buf + len, "\n"); - - memset((U8 *)&rsp, 0, sizeof(MwMgmt)); - memcpy(&rsp, &cfm, sizeof(MwMgmt)); - - - /* loop through configured peers */ - for(idx = 0; idx < rsp.t.ssta.s.clusterSta.nmbPeer; idx++) - { - int peer_id = rsp.t.ssta.s.clusterSta.peerSt[idx].peerId; - - memset(&cfm, 0, sizeof(MwMgmt)); - - if(LMW_PEER_DOWN != rsp.t.ssta.s.clusterSta.peerSt[idx].peerState){ - - if(ftmod_m2ua_ssta_req(STMWPEER, peer_id, &cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n",g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[peer_id].name); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_PEER_STATE(cfm.t.ssta.s.peerSta.state)); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.retryCount); - len = len + sprintf(buf + len, " %d \n", (int)cfm.t.ssta.s.peerSta.assocSta.spAssocId); - len = len + sprintf(buf + len, " %s \n",(cfm.t.ssta.s.peerSta.assocSta.connected)?"CONNECTED":"NOT CONNECTED"); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.flcInProg); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.flcLevel); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.sctpHBeatEnb); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.locOutStrms); - - len = len + sprintf(buf + len, "\n"); - } - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n",g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[peer_id].name); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_PEER_STATE(rsp.t.ssta.s.clusterSta.peerSt[idx].peerState)); - len = len + sprintf(buf + len, "\n"); - } - } - } - - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - if(ftmod_m2ua_ssta_req(STMWSCTSAP,x,&cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_SAP_STATE(cfm.t.ssta.s.sctSapSta.state)); - len = len + sprintf(buf + len," %s \n", (cfm.t.ssta.s.sctSapSta.endpOpen)?"END_POINT_OPENED_SUCCESSFULLY":"END_POINT_NOT_OPEN"); - len = len + sprintf(buf + len," %d \n", (int) cfm.t.ssta.s.sctSapSta.spEndpId); - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.sctSapSta.nmbPrimRetry); - len = len + sprintf(buf + len, "\n"); - } - - len = len + sprintf(buf + len, "\n"); - } - x++; - } - - len = len + sprintf(buf + len, "\n"); - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; - -} - -/****************************************************************************** -* Fun: handle_show_m2ua_profile() -* Desc: display requested m2ua profile information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ - -static ftdm_status_t handle_show_m2ua_profile(ftdm_stream_handle_t *stream, char* m2ua_profile_name) -{ - char* xmlhdr = (char*)""; - char buf[4096]; - int x = 0x00; - int idx = 0x00; - int found = 0x00; - int len = 0x00; - MwMgmt cfm; - MwMgmt rsp; - - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - memset((U8 *)&rsp, 0, sizeof(MwMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - - /*iterate through all the m2ua links and get required profile */ - x = 1; - while(xwrite_function(stream,"Requested M2UA profile[%s] not configured\n", m2ua_profile_name); - return FTDM_FAIL; - } - - - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n", m2ua_profile_name); - - if(ftmod_m2ua_ssta_req(STMWDLSAP,x,&cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_SAP_STATE(cfm.t.ssta.s.dlSapSta.state)); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_LINK_STATE(cfm.t.ssta.s.dlSapSta.lnkState)); - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.rpoEnable); - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.lpoEnable); - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.congLevel); - len = len + sprintf(buf + len, "\n"); - } - - if(ftmod_m2ua_ssta_req(STMWCLUSTER, g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[x].clusterId, &cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_CLUSTER_STATE(cfm.t.ssta.s.clusterSta.state)); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.clusterSta.nmbPeer); - len = len + sprintf(buf + len, "\n"); - for(idx = 0; idx < cfm.t.ssta.s.clusterSta.nmbPeer; idx++) - { - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.clusterSta.peerSt[idx].peerId); - len = len + sprintf(buf + len, " %s \n", PRNT_M2UA_PEER_STATE(cfm.t.ssta.s.clusterSta.peerSt[idx].peerState)); - } - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.clusterSta.nmbActPeer); - - len = len + sprintf(buf + len, "\n"); - } - - memcpy((U8 *)&rsp, &cfm, sizeof(MwMgmt)); - - /* loop through configured peers */ - for(idx = 0; idx < rsp.t.ssta.s.clusterSta.nmbPeer; idx++) - { - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - - if(ftmod_m2ua_ssta_req(STMWPEER, rsp.t.ssta.s.clusterSta.peerSt[idx].peerId, &cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n",g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[rsp.t.ssta.s.clusterSta.peerSt[idx].peerId].name); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_PEER_STATE(cfm.t.ssta.s.peerSta.state)); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.retryCount); -#ifdef BIT_64 - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.peerSta.assocSta.spAssocId); -#else - len = len + sprintf(buf + len, " %ld \n", cfm.t.ssta.s.peerSta.assocSta.spAssocId); -#endif - len = len + sprintf(buf + len, " %s \n",(cfm.t.ssta.s.peerSta.assocSta.connected)?"CONNECTED":"NOT CONNECTED"); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.flcInProg); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.flcLevel); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.sctpHBeatEnb); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.peerSta.assocSta.locOutStrms); - - len = len + sprintf(buf + len, "\n"); - } - } - - if(ftmod_m2ua_ssta_req(STMWSCTSAP,x,&cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_SAP_STATE(cfm.t.ssta.s.sctSapSta.state)); - len = len + sprintf(buf + len," %s \n", (cfm.t.ssta.s.sctSapSta.endpOpen)?"END_POINT_OPENED_SUCCESSFULLY":"END_POINT_NOT_OPEN"); -#ifdef BIT_64 - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.sctSapSta.spEndpId); -#else - len = len + sprintf(buf + len," %ld \n", cfm.t.ssta.s.sctSapSta.spEndpId); -#endif - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.sctSapSta.nmbPrimRetry); - len = len + sprintf(buf + len, "\n"); - } - - len = len + sprintf(buf + len, "\n"); - - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; - -} - -/****************************************************************************** -* Fun: handle_show_sctp_profiles() -* Desc: display all sctp profile information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ -static ftdm_status_t handle_show_sctp_profiles(ftdm_stream_handle_t *stream) -{ - char* xmlhdr = (char*)""; - char buf[4096]; - int x = 0x00; - int len = 0x00; - SbMgmt cfm; - - memset((U8 *)&cfm, 0, sizeof(SbMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - len = len + sprintf(buf + len, "\n"); - - if(ftmod_sctp_ssta_req(STSBGEN, 0x00, &cfm)) { - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); -#ifdef BIT_64 - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.memSize); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.memAlloc); -#else - len = len + sprintf(buf + len, " %ld \n",cfm.t.ssta.s.genSta.memSize); - len = len + sprintf(buf + len, " %ld \n",cfm.t.ssta.s.genSta.memAlloc); -#endif - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.nmbAssoc); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.nmbEndp); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.nmbLocalAddr); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.nmbPeerAddr); - len = len + sprintf(buf + len, "\n"); - } - -#ifdef LSB12 - if(ftmod_sctp_ssta_req(STSBTMR, 0x00, &cfm)) { - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.lifetimeTmr); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.ackDelayTmr); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.cookieTmr); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.keyTmr); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.freezeTmr); -#ifdef LSB4 - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.bundleTmr); -#endif - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.t1InitTmr); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.t2ShutdownTmr); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.hbeat); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.t3rtx); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.tmrSta.tIntTmr); - } - -#endif - - - /*iterate through all the sctp links and prints all information */ - x = 1; - while(x\n"); - - if(ftmod_sctp_ssta_req(STSBSCTSAP,x,&cfm)) { - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_SAP_STATE(cfm.t.ssta.s.sapSta.hlSt)); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_PROTO_SWITCH(cfm.t.ssta.s.sapSta.swtch)); - len = len + sprintf(buf + len, "\n"); - } - - if(ftmod_sctp_ssta_req(STSBTSAP,x,&cfm)) { - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_SAP_STATE(cfm.t.ssta.s.sapSta.hlSt)); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_PROTO_SWITCH(cfm.t.ssta.s.sapSta.swtch)); - len = len + sprintf(buf + len, "\n"); - } - - if(ftmod_sctp_ssta_req(STSBASSOC,x,&cfm)) { - if(LCM_REASON_INVALID_PAR_VAL == cfm.cfm.reason){ - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " SCT_ASSOC_STATE_CLOSED \n"); - len = len + sprintf(buf + len, "\n"); - }else{ - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } - } else { - len = len + sprintf(buf + len, "\n"); - len = len + get_assoc_resp_buf(buf + len, &cfm); - len = len + sprintf(buf + len, "\n"); - } - - /* TODO - STSBDTA */ - - len = len + sprintf(buf + len, "\n"); - } - x++; - } - - len = len + sprintf(buf + len, "\n"); - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; -} - -int get_assoc_resp_buf(char* buf,SbMgmt* cfm) -{ - int len = 0x00; - int idx = 0x00; - char *asciiAddr; - CmInetIpAddr ip; - -#ifdef BIT_64 - len = len + sprintf(buf + len, " %d \n", cfm->t.ssta.s.assocSta.assocId); -#else - len = len + sprintf(buf + len, " %ld \n", cfm->t.ssta.s.assocSta.assocId); -#endif - len = len + sprintf(buf + len, " %s \n", PRNT_SCTP_ASSOC_STATE(cfm->t.ssta.s.assocSta.assocState)); - len = len + sprintf(buf + len, " %d \n", cfm->t.ssta.s.assocSta.dstPort); - len = len + sprintf(buf + len, " %d \n", cfm->t.ssta.s.assocSta.srcPort); - len = len + sprintf(buf + len, " %d \n", cfm->t.ssta.s.assocSta.dstNAddrLst.nmb); - for(idx =0; idx < cfm->t.ssta.s.assocSta.dstNAddrLst.nmb; idx++) - { - len = len + sprintf(buf + len, " \n"); - len = len + sprintf(buf + len, " %s \n", PRNT_CM_ADDR_TYPE(cfm->t.ssta.s.assocSta.dstNAddrLst.nAddr[idx].type)); - if(cfm->t.ssta.s.assocSta.dstNAddrLst.nAddr[idx].type == CM_IPV4ADDR_TYPE) - { - ip = ntohl(cfm->t.ssta.s.assocSta.dstNAddrLst.nAddr[idx].u.ipv4NetAddr); - cmInetNtoa(ip, &asciiAddr); - len = len + sprintf(buf + len, " %s \n",asciiAddr); - } - else - { - len = len + sprintf(buf + len, " %s \n", cfm->t.ssta.s.assocSta.dstNAddrLst.nAddr[idx].u.ipv6NetAddr); - } - len = len + sprintf(buf + len, " \n"); - } - - len = len + sprintf(buf + len, " %d \n", cfm->t.ssta.s.assocSta.srcNAddrLst.nmb); - for(idx =0; idx < cfm->t.ssta.s.assocSta.srcNAddrLst.nmb; idx++) - { - len = len + sprintf(buf + len, " \n"); - len = len + sprintf(buf + len, " %s \n", PRNT_CM_ADDR_TYPE(cfm->t.ssta.s.assocSta.srcNAddrLst.nAddr[idx].type)); - if(cfm->t.ssta.s.assocSta.srcNAddrLst.nAddr[idx].type == CM_IPV4ADDR_TYPE) - { - ip = ntohl(cfm->t.ssta.s.assocSta.srcNAddrLst.nAddr[idx].u.ipv4NetAddr); - cmInetNtoa(ip, &asciiAddr); - len = len + sprintf(buf + len, " %s \n", asciiAddr); - } - else - { - len = len + sprintf(buf + len, " %s \n", cfm->t.ssta.s.assocSta.srcNAddrLst.nAddr[idx].u.ipv6NetAddr); - } - len = len + sprintf(buf + len, " \n"); - } - - len = len + sprintf(buf + len, "\n %s \n", PRNT_CM_ADDR_TYPE(cfm->t.ssta.s.assocSta.priNAddr.type)); - - if(cfm->t.ssta.s.assocSta.priNAddr.type == CM_IPV4ADDR_TYPE) - { - ip = ntohl(cfm->t.ssta.s.assocSta.priNAddr.u.ipv4NetAddr); - cmInetNtoa(ip, &asciiAddr); - len = len + sprintf(buf + len, " %s \n",asciiAddr); - } - else - { - len = len + sprintf(buf + len, " %s \n", cfm->t.ssta.s.assocSta.priNAddr.u.ipv6NetAddr); - } - -#ifdef LSB11 - /* TODO - this flag is not enable as of now.. so later on will convert below prints to XML tags */ - len = len + sprintf(buf + len, " The number of unsent datagrams : %d\n", cfm->t.ssta.s.assocSta.nmbUnsentDgms); - len = len + sprintf(buf + len, " The number of unack datagrams : %d\n", cfm->t.ssta.s.assocSta.nmbUnackDgms); - len = len + sprintf(buf + len, " The number of undelivered datagrams : %d\n", cfm->t.ssta.s.assocSta.nmbUndelDgms); - len = len + sprintf(buf + len, " The number of retransmissions count : %d\n", cfm->t.ssta.s.assocSta.rtxCnt); - len = len + sprintf(buf + len, " The receive window size is: %d\n\n", cfm->t.ssta.s.assocSta.SctWinSize); - for(idx =0; idx < LSB_MAX_TMRS ; idx++) - { - len = len + sprintf(buf + len, " %d) Timer state is %d\n", idx, cfm->t.ssta.s.assocSta.tmr[idx].state); - len = len + sprintf(buf + len, " %d) Timer value is %d\n", idx, cfm->t.ssta.s.assocSta.tmr[idx].tmrVal); - len = len + sprintf(buf + len, " %d) No of paths is %d\n", idx, cfm->t.ssta.s.assocSta.tmr[idx].numPaths); - for(idx1 =0; idx1 < cfm->t.ssta.s.assocSta.tmr[idx].numPaths; idx1++) - { - if( cfm->t.ssta.s.assocSta.tmr[idx].path[idx1].localAddr.type == CM_IPV4ADDR_TYPE) - { - len = len + sprintf(buf + len, " %d) the local Addr is %d\n", idx1, - cfm->t.ssta.s.assocSta.tmr[idx].path[idx1].localAddr.u.ipv4NetAddr); - } - else - { - len = len + sprintf(buf + len, " %d) the local Addr is %s\n", idx1, - cfm->t.ssta.s.assocSta.tmr[idx].path[idx1].localAddr.u.ipv6NetAddr); - } - - if( cfm->t.ssta.s.assocSta.tmr[idx].path[idx1].peerAddr.type == CM_IPV4ADDR_TYPE) - { - len = len + sprintf(buf + len, " %d) the peer Addr is %d\n", idx1, - cfm->t.ssta.s.assocSta.tmr[idx].path[idx1].peerAddr.u.ipv4NetAddr); - } - else - { - len = len + sprintf(buf + len, " %d) the peer Addr is %s\n", idx1, - cfm->t.ssta.s.assocSta.tmr[idx].path[idx1].peerAddr.u.ipv6NetAddr); - } - } /* Loop for paths */ - } /* Loop for timers */ -#endif - - return len; -} - -/****************************************************************************** -* Fun: handle_show_sctp_profile() -* Desc: display requested sctp profile information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ -static ftdm_status_t handle_show_sctp_profile(ftdm_stream_handle_t *stream, char* sctp_profile_name) -{ - char* xmlhdr = (char*)""; - char buf[4096]; - int x = 0x00; - int len = 0x00; - SbMgmt cfm; - int found = 0x00; - - memset((U8 *)&cfm, 0, sizeof(SbMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - - /*iterate through all the sctp links and prints all information */ - x = 1; - while(xwrite_function(stream,"Requested SCTP profile[%s] not configured\n", sctp_profile_name); - return FTDM_FAIL; - } - - len = len + sprintf(buf + len, "\n"); - - if(ftmod_sctp_ssta_req(STSBSCTSAP,x,&cfm)) { - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_SAP_STATE(cfm.t.ssta.s.sapSta.hlSt)); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_PROTO_SWITCH(cfm.t.ssta.s.sapSta.swtch)); - len = len + sprintf(buf + len, "\n"); - } - - if(ftmod_sctp_ssta_req(STSBTSAP,x,&cfm)) { - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_SAP_STATE(cfm.t.ssta.s.sapSta.hlSt)); - len = len + sprintf(buf + len," %s \n", PRNT_SCTP_PROTO_SWITCH(cfm.t.ssta.s.sapSta.swtch)); - len = len + sprintf(buf + len, "\n"); - } - - if(ftmod_sctp_ssta_req(STSBASSOC,x,&cfm)) { - /* it means assoc id not yet allocated */ - if(LCM_REASON_INVALID_PAR_VAL == cfm.cfm.reason){ - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " SCT_ASSOC_STATE_CLOSED \n"); - len = len + sprintf(buf + len, "\n"); - }else{ - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } - } else { - len = len + sprintf(buf + len, "\n"); - len = len + get_assoc_resp_buf(buf + len, &cfm); - len = len + sprintf(buf + len, "\n"); - } - - /* TODO - STSBDTA */ - - len = len + sprintf(buf + len, "\n"); - - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; -} - -/****************************************************************************** -* Fun: handle_show_nif_profiles() -* Desc: display all nif profile information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ -static ftdm_status_t handle_show_nif_profiles(ftdm_stream_handle_t *stream) -{ - char* xmlhdr = (char*)""; - char buf[4096]; - int x = 0x00; - int len = 0x00; - NwMgmt cfm; - - memset((U8 *)&cfm, 0, sizeof(NwMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - len = len + sprintf(buf + len, "\n"); - - if(ftmod_nif_ssta_req(STNWGEN, 0x00, &cfm)) { - stream->write_function(stream," Request to NIF layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); -#ifdef BIT_64 - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.memSize); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.genSta.memAlloc); -#else - len = len + sprintf(buf + len, " %ld \n",cfm.t.ssta.s.genSta.memSize); - len = len + sprintf(buf + len, " %ld \n",cfm.t.ssta.s.genSta.memAlloc); -#endif - len = len + sprintf(buf + len, "\n"); - } - - /*iterate through all the NIF links and prints all information */ - x = 1; - while(x\n"); - - if(ftmod_nif_ssta_req(STNWDLSAP,x,&cfm)) { - stream->write_function(stream," Request to NIF layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_NIF_SAP_STATE(cfm.t.ssta.s.dlSapSta.m2uaState)); - len = len + sprintf(buf + len," %s \n", PRNT_NIF_SAP_STATE(cfm.t.ssta.s.dlSapSta.mtp2State)); -#ifdef BIT_64 - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.nmbRetry); -#else - len = len + sprintf(buf + len," %ld \n", cfm.t.ssta.s.dlSapSta.nmbRetry); -#endif - len = len + sprintf(buf + len, "\n"); - } - - len = len + sprintf(buf + len, "\n"); - } - x++; - } - - len = len + sprintf(buf + len, "\n"); - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; -} - -/****************************************************************************** -* Fun: handle_show_nif_profile() -* Desc: display requested nif profile information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ -static ftdm_status_t handle_show_nif_profile(ftdm_stream_handle_t *stream, char* nif_profile_name) -{ - char* xmlhdr = (char*)""; - char buf[4096]; - int x = 0x00; - int found = 0x00; - int len = 0x00; - NwMgmt cfm; - - memset((U8 *)&cfm, 0, sizeof(NwMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - - /*iterate through all the m2ua links and get required profile */ - x = 1; - while(xwrite_function(stream,"Requested NIF profile[%s] not configured\n", nif_profile_name); - return FTDM_FAIL; - } - - - len = len + sprintf(buf + len, "\n"); - - if(ftmod_nif_ssta_req(STNWDLSAP,x,&cfm)) { - stream->write_function(stream," Request to NIF layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len," %s \n", PRNT_NIF_SAP_STATE(cfm.t.ssta.s.dlSapSta.m2uaState)); - len = len + sprintf(buf + len," %s \n", PRNT_NIF_SAP_STATE(cfm.t.ssta.s.dlSapSta.mtp2State)); -#ifdef BIT_64 - len = len + sprintf(buf + len," %d \n", cfm.t.ssta.s.dlSapSta.nmbRetry); -#else - len = len + sprintf(buf + len," %ld \n", cfm.t.ssta.s.dlSapSta.nmbRetry); -#endif - len = len + sprintf(buf + len, "\n"); - } - - len = len + sprintf(buf + len, "\n"); - - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -/****************************************************************************** -* Fun: handle_show_m2ua_peer_status() -* Desc: display requested m2ua profile peer information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ - -static ftdm_status_t handle_show_m2ua_peer_status(ftdm_stream_handle_t *stream, char* m2ua_profile_name) -{ - char* xmlhdr = (char*)""; - char buf[4096]; - int x = 0x00; - int found = 0x00; - int len = 0x00; - MwMgmt cfm; - SbMgmt sctp_cfm; - sng_m2ua_cluster_cfg_t* clust = NULL; - sng_m2ua_cfg_t* m2ua = NULL; - sng_m2ua_peer_cfg_t* peer = NULL; - int peer_id = 0; - int sctp_id = 0; - - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - memset((U8 *)&sctp_cfm, 0, sizeof(SbMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - - /*iterate through all the m2ua links and get required profile */ - x = 1; - while(xwrite_function(stream,"Requested M2UA profile[%s] not configured\n", m2ua_profile_name); - return FTDM_FAIL; - } - - m2ua = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[x]; - clust = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[m2ua->clusterId]; - - for(x = 0; x < clust->numOfPeers;x++){ - peer_id = clust->peerIdLst[x]; - peer = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[peer_id]; - - if(ftmod_m2ua_ssta_req(STMWPEER, peer_id, &cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n",peer->name); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_PEER_STATE(cfm.t.ssta.s.peerSta.state)); - /*len = len + sprintf(buf + len, " %s \n",(cfm.t.ssta.s.peerSta.assocSta.connected)?"CONNECTED":"NOT CONNECTED");*/ - len = len + sprintf(buf + len, "\n"); - } - - sctp_id = peer->sctpId; - - if(ftmod_sctp_ssta_req(STSBASSOC, sctp_id, &sctp_cfm)) { - if(LMW_PEER_DOWN == cfm.t.ssta.s.peerSta.state){ - /* If there is no association established so far, it will return fail..*/ - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " SCT_ASSOC_STATE_CLOSED \n"); - len = len + sprintf(buf + len, "\n"); - }else{ - stream->write_function(stream," Request to SCTP layer failed \n"); - return FTDM_FAIL; - } - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n", PRNT_SCTP_ASSOC_STATE(sctp_cfm.t.ssta.s.assocSta.assocState)); - len = len + sprintf(buf + len, "\n"); - } - } - - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; -} - -/****************************************************************************** -* Fun: handle_show_m2ua_cluster_status() -* Desc: display requested m2ua profile cluster information -* Ret: FTDM_SUCCESS | FTDM_FAIL -* Note: -* author: Kapil Gupta -*******************************************************************************/ - -static ftdm_status_t handle_show_m2ua_cluster_status(ftdm_stream_handle_t *stream, char* m2ua_profile_name) -{ - char* xmlhdr = (char*)""; - char buf[4096]; - int x = 0x00; - int found = 0x00; - int len = 0x00; - int idx = 0x00; - MwMgmt cfm; - SbMgmt sctp_cfm; - sng_m2ua_cluster_cfg_t* clust = NULL; - sng_m2ua_cfg_t* m2ua = NULL; - - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - memset((U8 *)&sctp_cfm, 0, sizeof(SbMgmt)); - memset(&buf[0], 0, sizeof(buf)); - - len = len + sprintf(buf + len, "%s\n", xmlhdr); - - /*iterate through all the m2ua links and get required profile */ - x = 1; - while(xwrite_function(stream,"Requested M2UA profile[%s] not configured\n", m2ua_profile_name); - return FTDM_FAIL; - } - - m2ua = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[x]; - clust = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[m2ua->clusterId]; - - if(ftmod_m2ua_ssta_req(STMWCLUSTER,g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[x].clusterId,&cfm)) { - stream->write_function(stream," Request to M2UA layer failed \n"); - return FTDM_FAIL; - } else { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n",clust->name); - len = len + sprintf(buf + len," %s \n", PRNT_M2UA_CLUSTER_STATE(cfm.t.ssta.s.clusterSta.state)); - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.clusterSta.nmbPeer); - for(idx = 0; idx < cfm.t.ssta.s.clusterSta.nmbPeer; idx++) - { - len = len + sprintf(buf + len, "\n"); - len = len + sprintf(buf + len, " %s \n", g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[cfm.t.ssta.s.clusterSta.peerSt[idx].peerId].name); - len = len + sprintf(buf + len, " %d \n", cfm.t.ssta.s.clusterSta.peerSt[idx].peerId); - len = len + sprintf(buf + len, " %s \n", PRNT_M2UA_PEER_STATE(cfm.t.ssta.s.clusterSta.peerSt[idx].peerState)); - len = len + sprintf(buf + len, "\n"); - } - len = len + sprintf(buf + len, " %d \n",cfm.t.ssta.s.clusterSta.nmbActPeer); - - len = len + sprintf(buf + len, "\n"); - } - - stream->write_function(stream,"\n%s\n",buf); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c deleted file mode 100644 index 6b12605c6a..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c +++ /dev/null @@ -1,921 +0,0 @@ -/* - * Copyright (c) 2009, Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -int ft_to_sngss7_activate_all(void); - -static int ftmod_ss7_enable_isap(int suId); -static int ftmod_ss7_enable_nsap(int suId); -static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId); - - -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -int ft_to_sngss7_activate_all(void) -{ - int x; - - x = 1; - while (x < (MAX_ISAPS)) { - /* check if this link has already been actived */ - if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) { - - if (ftmod_ss7_enable_isap(x)) { - SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x); - return 1; - } else { - SS7_INFO("ISAP %d Enable: OK\n", x); - } - - /* set the SNGSS7_ACTIVE flag */ - g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_ACTIVE; - } /* if !SNGSS7_ACTIVE */ - - x++; - } /* while (x < (MAX_ISAPS)) */ - - if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){ - x = 1; - while (x < (MAX_NSAPS)) { - /* check if this link has already been actived */ - if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) { - - if (ftmod_ss7_enable_nsap(x)) { - SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x); - return 1; - } else { - SS7_INFO("NSAP %d Enable: OK\n", x); - } - - /* set the SNGSS7_ACTIVE flag */ - g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_ACTIVE; - } /* if !SNGSS7_ACTIVE */ - - x++; - } /* while (x < (MAX_NSAPS)) */ - - if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) { - x = 1; - while (x < (MAX_MTP_LINKSETS+1)) { - /* check if this link has already been actived */ - if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) && - (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) { - - if (ftmod_ss7_enable_mtpLinkSet(x)) { - SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); - return 1; - } else { - SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); - } - - /* set the SNGSS7_ACTIVE flag */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE; - } /* if !SNGSS7_ACTIVE */ - - x++; - } /* while (x < (MAX_MTP_LINKSETS+1)) */ - } - } - - if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){ - return ftmod_ss7_m2ua_start(); - } - - return 0; -} - -/******************************************************************************/ -static int ftmod_ss7_enable_isap(int suId) -{ - CcMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTCC; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(CcMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTCC; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STISAP; - - cntrl.hdr.elmId.elmntInst1 = suId; /* this is the SAP to bind */ - - cntrl.t.cntrl.action = ABND_ENA; /* bind and activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_cc(&pst, &cntrl)); -} - -/******************************************************************************/ -static int ftmod_ss7_enable_nsap(int suId) -{ - SiMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SiMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSI; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STNSAP; - - cntrl.t.cntrl.s.siElmnt.elmntId.sapId = suId; - cntrl.t.cntrl.s.siElmnt.elmntParam.nsap.nsapType = SAP_MTP; - - - cntrl.t.cntrl.action = ABND_ENA; /* bind and activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_isup(&pst, &cntrl)); -} - -/******************************************************************************/ -static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STLNKSET; - cntrl.hdr.elmId.elmntInst1 = lnkSetId; /* this is the linkset to bind */ - - cntrl.t.cntrl.action = ABND_ENA; /* bind and activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_inhibit_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = id; /* the DSLAP to inhibit */ - - cntrl.t.cntrl.action = AINH; /* Inhibit */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_uninhibit_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = id; /* the DSLAP to inhibit */ - - cntrl.t.cntrl.action = AUNINH; /* Inhibit */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_bind_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - cntrl.t.cntrl.action = ABND; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_unbind_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - cntrl.t.cntrl.action = AUBND_DIS; /* unbind and disable */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_activate_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - cntrl.t.cntrl.action = AENA; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_deactivate_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - cntrl.t.cntrl.action = ADISIMM; /* Deactivate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_deactivate2_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - cntrl.t.cntrl.action = ADISIMM_L2; /* Deactivate...layer 2 only */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_activate_mtplinkSet(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STLNKSET; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; - - cntrl.t.cntrl.action = AACTLNKSET; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_deactivate_mtplinkSet(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STLNKSET; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; - - cntrl.t.cntrl.action = ADEACTLNKSET; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STLNKSET; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; - - cntrl.t.cntrl.action = ADEACTLNKSET_L2; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_lpo_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - cntrl.t.cntrl.action = ACTION_LPO; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_lpr_mtp3link(uint32_t id) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - cntrl.t.cntrl.action = ACTION_LPR; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_shutdown_isup(void) -{ - SiMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SiMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSI; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGEN; - - cntrl.t.cntrl.action = ASHUTDOWN; /* shutdown */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_isup(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_shutdown_mtp3(void) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGEN; - - cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp3(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_shutdown_mtp2(void) -{ - SdMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSD; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SdMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSD; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGEN; - - cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_mtp2(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_shutdown_relay(void) -{ - RyMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTRY; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(RyMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTRY; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGEN; - - cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_relay(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_disable_relay_channel(uint32_t chanId) -{ - RyMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTRY; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(RyMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTRY; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGEN; - - - cntrl.hdr.elmId.elmntInst1 = chanId; - - cntrl.t.cntrl.action = ADISIMM; /* Deactivate */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_relay(&pst, &cntrl)); -} - -/******************************************************************************/ -int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGRDLSAP; /* group DLSAP */ - - cntrl.t.cntrl.ctlType.groupKey.dstProcId = procId; /* all SAPS to this ProcId */ - - cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */ - cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ - - if (g_ftdm_sngss7_data.cfg.procId == procId) { - SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId); - return (sng_cntrl_mtp3(&pst, &cntrl)); - } else { - SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n", - g_ftdm_sngss7_data.cfg.procId,procId); - return (sng_cntrl_mtp3_nowait(&pst, &cntrl)); - } - -} - -/******************************************************************************/ -int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId) -{ - SnMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SnMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSN; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGRDLSAP; /* group DLSAP */ - - cntrl.t.cntrl.ctlType.groupKey.dstProcId = procId; /* all SAPS to this ProcId */ - - cntrl.t.cntrl.action = ABND_ENA; /* bind and enable */ - cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ - - if (g_ftdm_sngss7_data.cfg.procId == procId) { - SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId); - return (sng_cntrl_mtp3(&pst, &cntrl)); - } else { - SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n", - g_ftdm_sngss7_data.cfg.procId,procId); - return (sng_cntrl_mtp3_nowait(&pst, &cntrl)); - } - -} - -/******************************************************************************/ -int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId) -{ - SdMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSD; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(cntrl)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSD; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STGRNSAP; /* group NSAP */ - - cntrl.t.cntrl.par.dstProcId = procId; /* all SAPS to this ProcId */ - - cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */ - cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ - - return (sng_cntrl_mtp2(&pst, &cntrl)); - -} - -/******************************************************************************/ -int __ftmod_ss7_block_isup_ckt(uint32_t cktId, ftdm_bool_t wait) -{ - SiMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SiMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSI; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STICIR; - - cntrl.t.cntrl.s.siElmnt.elmntId.circuit = cktId; - cntrl.t.cntrl.s.siElmnt.elmntParam.cir.flag = LSI_CNTRL_CIR_FORCE; - - cntrl.t.cntrl.action = ADISIMM; /* block via BLO */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - if (wait == FTDM_TRUE) { - return (sng_cntrl_isup(&pst, &cntrl)); - } else { - return (sng_cntrl_isup_nowait(&pst, &cntrl)); - } -} - -/******************************************************************************/ -int ftmod_ss7_unblock_isup_ckt(uint32_t cktId) -{ - SiMngmt cntrl; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* initalize the control structure */ - memset(&cntrl, 0x0, sizeof(SiMngmt)); - - /* initalize the control header */ - smHdrInit(&cntrl.hdr); - - cntrl.hdr.msgType = TCNTRL; /* this is a control request */ - cntrl.hdr.entId.ent = ENTSI; - cntrl.hdr.entId.inst = S_INST; - cntrl.hdr.elmId.elmnt = STICIR; - - cntrl.t.cntrl.s.siElmnt.elmntId.circuit = cktId; - cntrl.t.cntrl.s.siElmnt.elmntParam.cir.flag = LSI_CNTRL_CIR_FORCE; - - cntrl.t.cntrl.action = AENA; /* unblock via UBL */ - cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ - - return (sng_cntrl_isup(&pst, &cntrl)); -} -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c deleted file mode 100644 index f120114667..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ /dev/null @@ -1,2750 +0,0 @@ -/* - * Copyright (c) 2009 Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms|with or without - * modification|are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice|this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice|this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT - * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, - * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Ricardo Barroetaveña - * James Zhang - * - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" - -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ - -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); -ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); -ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); -ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); -ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); -ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ - -#define ftdm_running_return(var) if (!ftdm_running()) { SS7_ERROR("Error: ftdm_running is not set! Ignoring\n"); return var; } - -ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - char var[FTDM_DIGITS_LIMIT]; - - memset(var, '\0', sizeof(var)); - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM (glare)\n", sngss7_info->circuit->cic); - } - - /* check if the circuit has a remote block */ - if ((sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { - - /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX_DN); - - /* KONRAD FIX ME : check in case there is a ckt and grp block */ - } - - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX_DN); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_SENT); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX_DN); - sngss7_clear_ckt_flag(sngss7_info, FLAG_FULL_NUMBER); - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case (FTDM_CHANNEL_STATE_DOWN): /* only state it is valid to get IAM (except if there is glare */ - - /* check if there is any reason why we can't use this channel */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) { - /* channel is already requested for use by the ftdm core */ - goto handle_glare; - } else if(ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - /* channel is not inuse but we can't open it...fail the call */ - SS7_ERROR("Failed to open span: %d, chan: %d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); - - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL); - - ftdmchan->caller_data.hangup_cause = 41; - - /* move the state to CANCEL */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - - } else { - - /* fill in the channels SS7 Stack information */ - sngss7_info->suInstId = get_unique_id(); - sngss7_info->spInstId = spInstId; - - /* fill in calling party information */ - if (siConEvnt->cgPtyNum.eh.pres) { - if (siConEvnt->cgPtyNum.addrSig.pres) { - /* fill in cid_num */ - copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig, - ftdmchan->caller_data.cid_num.digits, - siConEvnt->cgPtyNum.oddEven); - - /* fill in cid Name */ - ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits); - - /* fill in ANI */ - ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits); - } - else { - if (g_ftdm_sngss7_data.cfg.force_inr) { - sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT); - } - } - - if (siConEvnt->cgPtyNum.scrnInd.pres) { - /* fill in the screening indication value */ - ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val; - } - - if (siConEvnt->cgPtyNum.presRest.pres) { - /* fill in the presentation value */ - ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val; - } - } else { - if (g_ftdm_sngss7_data.cfg.force_inr) { - sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT); - } - - SS7_INFO_CHAN(ftdmchan,"No Calling party (ANI) information in IAM!%s\n", " "); - } - - /* fill in called party infomation */ - if (siConEvnt->cdPtyNum.eh.pres) { - if (siConEvnt->cdPtyNum.addrSig.pres) { - /* fill in the called number/dnis */ - copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, - ftdmchan->caller_data.dnis.digits, - siConEvnt->cdPtyNum.oddEven); - } - } else { - SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " "); - } - copy_NatureOfConnection_from_sngss7(ftdmchan, &siConEvnt->natConInd); - copy_fwdCallInd_hex_from_sngss7(ftdmchan, &siConEvnt->fwdCallInd); - copy_access_transport_from_sngss7(ftdmchan, &siConEvnt->accTrnspt); - copy_ocn_from_sngss7(ftdmchan, &siConEvnt->origCdNum); - copy_redirgNum_from_sngss7(ftdmchan, &siConEvnt->redirgNum); - copy_redirgInfo_from_sngss7(ftdmchan, &siConEvnt->redirInfo); - copy_genNmb_from_sngss7(ftdmchan, &siConEvnt->genNmb); - - copy_cgPtyCat_from_sngss7(ftdmchan, &siConEvnt->cgPtyCat); - copy_cdPtyNum_from_sngss7(ftdmchan, &siConEvnt->cdPtyNum); - - /* fill in the TMR/bearer capability */ - if (siConEvnt->txMedReq.eh.pres) { - if (siConEvnt->txMedReq.trMedReq.pres) { - /* fill in the bearer type */ - ftdmchan->caller_data.bearer_capability = siConEvnt->txMedReq.trMedReq.val; - } - } else { - SS7_DEBUG_CHAN(ftdmchan,"No TMR/Bearer Cap information in IAM!%s\n", " "); - } - - /* add any special variables for the dialplan */ - sprintf(var, "%d", siConEvnt->cgPtyNum.natAddrInd.val); - sngss7_add_var(sngss7_info, "ss7_clg_nadi", var); - - /* Retrieve the Location Number if present (see ITU Q.763, 3.30) */ - if (siConEvnt->cgPtyNum1.eh.pres) { - if (siConEvnt->cgPtyNum1.addrSig.pres) { - /* fill in the ss7 location address number */ - copy_tknStr_from_sngss7(siConEvnt->cgPtyNum1.addrSig, var, siConEvnt->cgPtyNum1.oddEven); - sngss7_add_var(sngss7_info, "ss7_loc_digits", var); - } - - if (siConEvnt->cgPtyNum1.scrnInd.pres) { - /* fill in the screening indication value */ - sprintf(var, "%d", siConEvnt->cgPtyNum1.scrnInd.val); - sngss7_add_var(sngss7_info, "ss7_loc_screen_ind", var); - } - - if (siConEvnt->cgPtyNum1.presRest.pres) { - /* fill in the presentation value */ - sprintf(var, "%d", siConEvnt->cgPtyNum1.presRest.val); - sngss7_add_var(sngss7_info, "ss7_loc_pres_ind", var); - } - - if (siConEvnt->cgPtyNum1.natAddrInd.pres) { - sprintf(var, "%d", siConEvnt->cgPtyNum1.natAddrInd.val); - sngss7_add_var(sngss7_info, "ss7_loc_nadi", var); - } - } else { - SS7_DEBUG_CHAN(ftdmchan, "No Location Number information in IAM%s\n", " "); - } - - sprintf(var, "%d", sngss7_info->circuit->cic); - sngss7_add_var(sngss7_info, "ss7_cic", var); - - - sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc ); - sngss7_add_var(sngss7_info, "ss7_opc", var); - - if (siConEvnt->callRef.callId.pres) { - ftdmchan->caller_data.call_reference = (unsigned int)siConEvnt->callRef.callId.val; - } else { - ftdmchan->caller_data.call_reference = 0; - } - - if (sngss7_info->circuit->transparent_iam) { - sngss7_save_iam(ftdmchan, siConEvnt); - } - - /* check if a COT test is requested */ - if ((siConEvnt->natConInd.eh.pres) && - (siConEvnt->natConInd.contChkInd.pres) && - (siConEvnt->natConInd.contChkInd.val)) { - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Found COT Request\n", sngss7_info->circuit->cic); - - /* tell the core to loop the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); - - /* move to in loop state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP); - } else { - /* set the state of the channel to collecting...the rest is done by the chan monitor */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - } - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n", - sngss7_info->circuit->cic, - ftdmchan->caller_data.cid_num.digits, - siConEvnt->cgPtyNum.natAddrInd.val, - ftdmchan->caller_data.dnis.digits, - siConEvnt->cdPtyNum.natAddrInd.val); - } /* if (channel is usable */ - - break; - /**************************************************************************/ - case (FTDM_CHANNEL_STATE_DIALING): - case (FTDM_CHANNEL_STATE_TERMINATING): - case (FTDM_CHANNEL_STATE_HANGUP): - case (FTDM_CHANNEL_STATE_HANGUP_COMPLETE): -handle_glare: - /* the core already has plans for this channel...glare */ - SS7_INFO_CHAN(ftdmchan, "Got IAM on channel that is already inuse (state=%s|inuse=%c)...glare!\n", - ftdm_channel_state2str (ftdmchan->state), - ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) ? 'Y' : 'N'); - - /* save the info so that we can use it later on */ - sngss7_info->glare.spInstId = spInstId; - sngss7_info->glare.circuit = circuit; - memcpy(&sngss7_info->glare.iam, siConEvnt, sizeof(*siConEvnt)); - - if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) { - /* glare, throw the flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE); - - /* setup the hangup cause */ - ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */ - - /* move the state of the channel to Terminating to end the call - in TERMINATING state, the release cause is set to REMOTE_REL - in any means. So we don't have to set the release reason here. - */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } - break; - /**************************************************************************/ - default: /* should not have gotten an IAM while in this state */ - SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state)); - - /* throw the TX reset flag */ - if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_tx_reset_restart(sngss7_info); - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - - /* go to RESTART */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) */ - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - switch (evntType) { - /**************************************************************************/ - case (ADDRCMPLT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ACM\n", sngss7_info->circuit->cic); - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - /* KONRAD: should we confirm the instance ids ? */ - - /* need to grab the sp instance id */ - sngss7_info->spInstId = spInstId; - - if ((siCnStEvnt->optBckCalInd.eh.pres) && - (siCnStEvnt->optBckCalInd.inbndInfoInd.pres)) { - - if (siCnStEvnt->optBckCalInd.inbndInfoInd.val) { - /* go to PROGRESS_MEDIA */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { - /* go to PROGRESS */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } /* if (inband) */ - } else { - /* go to PROGRESS_MEDIA */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } - - break; - /**********************************************************************/ - default: /* incorrect state...reset the CIC */ - SS7_ERROR_CHAN(ftdmchan, "RX ACM in invalid state :%s...resetting CIC\n", - ftdm_channel_state2str (ftdmchan->state)); - - /* throw the TX reset flag */ - if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_tx_reset_restart(sngss7_info); - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - - /* go to RESTART */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - break; - /**********************************************************************/ - } /* switch (ftdmchan->state) */ - - break; - /**************************************************************************/ - case (MODIFY): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (MODCMPLT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-COMPLETE\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (MODREJ): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-REJECT\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (PROGRESS): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CPG\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (FRWDTRSFR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FOT\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (INFORMATION): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INF\n", sngss7_info->circuit->cic); - - SS7_DEBUG_CHAN (ftdmchan, "Cancelling T.39 timer %s\n", " "); - /* check if t39 is active */ - if (sngss7_info->t39.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id); - SS7_DEBUG_CHAN (ftdmchan, "T.39 timer has been cancelled upon receiving INF message %s\n", " "); - } - - sngss7_set_ckt_flag(sngss7_info, FLAG_INF_RX_DN); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - case (INFORMATREQ): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INR\n", sngss7_info->circuit->cic); - - ft_to_sngss7_inf(ftdmchan, siCnStEvnt); - - sngss7_set_ckt_flag(sngss7_info, FLAG_INR_RX); - - break; - /**************************************************************************/ - case (SUBSADDR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SAM\n", sngss7_info->circuit->cic); - - /* check the channel state */ - switch (ftdmchan->state) { - /**********************************************************************/ - case (FTDM_CHANNEL_STATE_COLLECT): - - /* confirm that the event contains the subsquent number field */ - if (siCnStEvnt->subNum.eh.pres && siCnStEvnt->subNum.addrSig.pres) { - /* add the digits to the ftdm channel variable */ - append_tknStr_from_sngss7(siCnStEvnt->subNum.addrSig, - ftdmchan->caller_data.dnis.digits, - siCnStEvnt->subNum.oddEven); - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Rx SAM (digits = %s)\n", sngss7_info->circuit->cic, - ftdmchan->caller_data.dnis.digits); - } else { - SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in SAM!%s\n", " "); - } - - /* go to idle so that collect state is processed again */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**********************************************************************/ - default: - SS7_ERROR_CHAN(ftdmchan, "RX SAM in invalid state :%s...ignoring\n", - ftdm_channel_state2str (ftdmchan->state)); - break; - /**********************************************************************/ - } /* switch (ftdmchan->state) */ - - break; - /**************************************************************************/ - case (EXIT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx EXIT\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (NETRESMGT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx NRM\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (IDENTREQ): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IDR\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (IDENTRSP): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IRS\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (MALCLLPRNT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MALICIOUS CALL\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CHARGE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (TRFFCHGE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-TARIFF\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CHARGEACK): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-ACK\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CALLOFFMSG): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-OFFER\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (LOOPPRVNT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LOP\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (TECT_TIMEOUT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ECT-Timeout\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (RINGSEND): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RINGING-SEND\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CALLCLEAR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-LINE Clear\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (PRERELEASE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx PRI\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (APPTRANSPORT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx APM\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (OPERATOR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx OPERATOR\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (METPULSE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx METERING-PULSE\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CLGPTCLR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALLING_PARTY_CLEAR\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (SUBDIRNUM): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUB-DIR\n", sngss7_info->circuit->cic); - break; -#ifdef SANGOMA_SPIROU - case (CHARGE_ACK): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx TXA\n", sngss7_info->circuit->cic); - break; - case (CHARGE_UNIT): - { - uint32_t charging_unit = 0; - uint32_t msg_num = 0; - char val[3]; - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ITX\n", sngss7_info->circuit->cic); - - memset(val, '\0', sizeof(val)); - - if (siCnStEvnt->chargUnitNum.eh.pres == PRSNT_NODEF && - siCnStEvnt->chargUnitNum.chargUnitNum.pres == PRSNT_NODEF) { - - charging_unit = siCnStEvnt->chargUnitNum.chargUnitNum.val; - } - - if (siCnStEvnt->msgNum.eh.pres == PRSNT_NODEF && - siCnStEvnt->msgNum.msgNum.pres == PRSNT_NODEF) { - - msg_num = siCnStEvnt->msgNum.msgNum.val; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Charging Unit:%d Msg Num:%d\n", charging_unit, msg_num); - - sprintf(val, "%d", charging_unit); - sngss7_add_var(sngss7_info, "ss7_itx_charge_unit", val); - - sprintf(val, "%d", msg_num); - sngss7_add_var(sngss7_info, "ss7_itx_msg_num", val); - - if (sngss7_info->circuit->itx_auto_reply) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Auto-reply with TXA msg\n"); - ft_to_sngss7_txa (ftdmchan); - } - } - break; -#endif - /**************************************************************************/ - default: - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Unknown Msg\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM\n", sngss7_info->circuit->cic); - - /* go to UP */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CON\n", sngss7_info->circuit->cic); - - /* go to UP */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* already hangup complete, just ignore it */ - /* - * i.e. collision REL & ANM - * IAM -> - * <- ACM - * REL -> <- ANM (if REL gets processed first, ANM needs to be ignored) - * <- RLC - */ - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON Ignoring it because we already hung up\n", sngss7_info->circuit->cic); - - break; - /**************************************************************************/ - default: /* incorrect state...reset the CIC */ - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic); - - /* throw the TX reset flag */ - if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_tx_reset_restart(sngss7_info); - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - - /* go to RESTART */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - - break; - /**************************************************************************/ - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx REL cause=%d\n", - sngss7_info->circuit->cic, - siRelEvnt->causeDgn.causeVal.val); - - /* check whether the ftdm channel is in a state to release a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - - /* pass the release code up to FTDM */ - if (siRelEvnt->causeDgn.causeVal.pres) { - ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; - } else { - SS7_ERROR("REL does not have a cause code!\n"); - ftdmchan->caller_data.hangup_cause = 0; - } - - /* this is a remote hangup request */ - sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - /* move the state of the channel to CANCEL to end the call */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_UP: - - /* pass the release code up to FTDM */ - if (siRelEvnt->causeDgn.causeVal.pres) { - ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; - } else { - SS7_ERROR("REL does not have a cause ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);code!\n"); - ftdmchan->caller_data.hangup_cause = 0; - } - - /* this is a remote hangup request */ - sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); - - /* move the state of the channel to TERMINATING to end the call */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* ITU Q.764 2.3.1 e) - * Collision of release messages - * - * ITU Q.784 Test Number 3.8 - * Collision of REL messages - */ - SS7_DEBUG_CHAN(ftdmchan, "Collision of REL messages. Rx REL while waiting for RLC.%s\n", " "); - if (sngss7_test_ckt_flag(sngss7_info, FLAG_LOCAL_REL) && - !sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { - /* locally requested hangup completed, wait for remote RLC */ - /* need to perform remote release */ - - /* this is also a remote hangup request */ - sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); - - /* send out the release complete */ - ft_to_sngss7_rlc (ftdmchan); - } else { - SS7_DEBUG_CHAN(ftdmchan, "Collision of REL messages - resetting state.%s\n", " "); - ft_to_sngss7_rlc (ftdmchan); - goto rel_ind_reset; - } - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_IN_LOOP: - - /* inform the core to unloop the channel*/ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - - /* since we need to acknowledge the hang up set the flag for remote release */ - sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); - - /* go to hangup complete to send the RLC */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - - /* save the call info for the RLC */ - sngss7_info->suInstId = get_unique_id(); - sngss7_info->spInstId = spInstId; - - break; - /**************************************************************************/ - default: - -rel_ind_reset: - /* throw the TX reset flag */ - if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_tx_reset_restart(sngss7_info); - - /* go to RESTART */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) */ - - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RLC\n", sngss7_info->circuit->cic); - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* go to DOWN */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - /* do nothing, just drop the message */ - break; - /**************************************************************************/ - default: - /* KONRAD: should just stop the call...but a reset is easier for now (since it does hangup the call) */ - - /* go to RESTART */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**************************************************************************/ - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx DATA IND\n", sngss7_info->circuit->cic); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC\n", sngss7_info->circuit->cic); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC-CON\n", sngss7_info->circuit->cic); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx USER-USER msg\n", sngss7_info->circuit->cic); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Suspend msg\n", sngss7_info->circuit->cic); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; - - ftdm_running_return(FTDM_FAIL); - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Resume msg\n", sngss7_info->circuit->cic); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is active on our side otherwise move to the next circuit */ - if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[circuit], SNGSS7_ACTIVE)) { - SS7_ERROR("[CIC:%d]Rx %s but circuit is not active yet, skipping!\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - return FTDM_FAIL; - } - - switch (evntType) { - /**************************************************************************/ - case SIT_STA_REATTEMPT: /* reattempt indication */ - handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_ERRORIND: /* error indication */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CONTCHK: /* continuity check */ - handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CONTREP: /* continuity report */ - handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_STPCONTIN: /* stop continuity */ - handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CGQRYRSP: /* circuit grp query response from far end forwarded to upper layer by ISUP */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CONFUSION: /* confusion */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LOOPBACKACK: /* loop-back acknowledge */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRRSRVREQ: /* circuit reservation request */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRRSRVACK: /* circuit reservation acknowledgement */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRBLOREQ: /* circuit blocking request */ - handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRBLORSP: /* circuit blocking response */ - handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUBLREQ: /* circuit unblocking request */ - handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUBLRSP: /* circuit unblocking response */ - handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRRESREQ: /* circuit reset request - RSC */ - handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCRES: /* reset initiated locally by the software */ - handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRRESRSP: /* circuit reset response */ - handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CGBREQ: /* CGB request */ - handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CGUREQ: /* CGU request */ - handle_cgu_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CGQRYREQ: /* circuit group query request */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CGBRSP: /* mntc. oriented CGB response */ - SS7_INFO(" Rx CGBA \n"); - break; - /**************************************************************************/ - case SIT_STA_CGURSP: /* mntc. oriented CGU response */ - /*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/ - SS7_INFO(" Rx CGUA \n"); - break; - /**************************************************************************/ - case SIT_STA_GRSREQ: /* circuit group reset request */ - handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ - handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_GRSRSP: /* circuit group reset response */ - handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_PAUSEIND: /* pause indication */ - handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_RESUMEIND: /* resume indication */ - handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_USRPARTA: /* user part available */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_RMTUSRUNAV: /* remote user not available */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG0: /* congestion indication level 0 */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG1: /* congestion indication level 1 */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG2: /* congestion indication level 2 */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG3: /* congestion indication level 3 */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPSTPCONG: /* stop congestion indication level 0 */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCALBLOIND: /* Mngmt local blocking */ - handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCALUBLIND: /* Mngmt local unblocking */ - handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_OVERLOAD: /* Overload */ - handle_olm_msg(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMCGUREQ: /* when LM requests ckt grp unblocking */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMGRSREQ: /* when LM requests ckt grp reset */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CGBINFOIND: /* circuit grp blking ind , no resp req */ -/* handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/ - break; - /**************************************************************************/ - case SIT_STA_LMCQMINFOREQ: /* when LM requests ckt grp query */ -// SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - default: - SS7_INFO("[SNG-CC] Received Unknown indication %d\n", evntType); - break; - } /* switch (evntType) */ - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; - -} - -/******************************************************************************/ -ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { - /* the glare flag is already up so it was caught ... do nothing */ - SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " "); - } else { - int bHangup = 0; - SS7_DEBUG_CHAN(ftdmchan, "Glare flag is not up yet...indicating glare from reattempt!%s\n", " "); - /* glare, throw the flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE); - - /* clear any existing glare data from the channel */ - memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t)); - - if (g_ftdm_sngss7_data.cfg.glareResolution == SNGSS7_GLARE_DOWN) { - /* If I'm in DOWN mode, I will always hangup my call. */ - bHangup = 1; - } - else if (g_ftdm_sngss7_data.cfg.glareResolution == SNGSS7_GLARE_PC) { - /* I'm in PointCode mode. - Case 1: My point code is higher than the other side. - If the CIC number is even, I'm trying to control. - If the CIC number is odd, I'll hangup my call and back off. - Case 2: My point code is lower than the other side. - If the CIC number is odd, I'm trying to control. - If the CIC number is even, I'll hangup my call and back off. - */ - if( g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc > g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc ) - { - if ((sngss7_info->circuit->cic % 2) == 1 ) { - bHangup = 1; - } - } else { - if( (sngss7_info->circuit->cic % 2) == 0 ) { - bHangup = 1; - } - } - } - else { - /* If I'm in CONTROL mode, I will not hangup my call. */ - bHangup = 0; - } - - if (bHangup) { - /* setup the hangup cause */ - ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */ - - /* move the state of the channel to Terminating to end the call - in TERMINATING state, the release cause is set to REMOTE_REL - in any means. So we don't have to set the release reason here. - */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - int infId; - int i; - - ftdm_running_return(FTDM_FAIL); - - /* extract the affected infId from the circuit structure */ - infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; - - /* set the interface to paused */ - sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); - - /* go through all the circuits now and find any other circuits on this infId */ - i = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { - - /* check that the infId matches and that this is not a siglink */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && - (g_ftdm_sngss7_data.cfg.isupCkt[i].type == SNG_CKT_VOICE)) { - - /* confirm that the circuit is active on our side otherwise move to the next circuit */ - if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[i], SNGSS7_ACTIVE)) { - SS7_ERROR("[CIC:%d]Circuit is not active yet, skipping!\n",g_ftdm_sngss7_data.cfg.isupCkt[i].cic); - i++; - continue; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - i++; - continue; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the circuit is fully started */ - if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { - SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", ""); - /* set the pause flag on the channel */ - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* clear the resume flag on the channel */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ - - /* move to the next circuit */ - i++; - - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - int infId; - int i; - - ftdm_running_return(FTDM_FAIL); - - /* extract the affect infId from the circuit structure */ - infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; - - /* set the interface to resumed */ - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); - - /* go through all the circuits now and find any other circuits on this infId */ - i = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { - - /* check that the infId matches and that this is not a siglink */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && - (g_ftdm_sngss7_data.cfg.isupCkt[i].type == SNG_CKT_VOICE)) { - - /* confirm that the circuit is active on our side otherwise move to the next circuit */ - if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[i], SNGSS7_ACTIVE)) { - ftdm_log(FTDM_LOG_DEBUG, "[CIC:%d]Circuit is not active yet, skipping!\n",g_ftdm_sngss7_data.cfg.isupCkt[i].cic); - i++; - continue; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - i++; - continue; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* only resume if we are paused */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { - SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", ""); - - /* set the resume flag on the channel */ - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - - /* clear the paused flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ - - /* move to the next circuit */ - i++; - - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* open the channel if it is not open */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - SS7_ERROR("Failed to open CIC %d for CCR test!\n", sngss7_info->circuit->cic); - /* KONRAD FIX ME */ - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - } - - /* tell the core to loop the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); - - /* switch to the IN_LOOP state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* tell the core to stop looping the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - - /* exit out of the LOOP state to the last state */ - ftdm_set_state(ftdmchan, ftdmchan->last_state); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - switch (ftdmchan->state) { - /**************************************************************************/ - case (FTDM_CHANNEL_STATE_IN_LOOP): - /* tell the core to stop looping the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - - /* exit out of the LOOP state and go to collect */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - - break; - /**************************************************************************/ - default: - /* exit out of the LOOP state to the last state */ - ftdm_set_state(ftdmchan, ftdmchan->last_state); - - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) */ - - if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) { - SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - g_ftdm_sngss7_data.cfg.isupCkt[circuit].span, - g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan, - (siStaEvnt->contInd.contInd.val) ? "PASS" : "FAIL"); - } else { - SS7_ERROR("Recieved Continuity report containing no results!\n"); - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the circuit is already blocked or not */ - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { - SS7_WARN("Received BLO on circuit that is already blocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - - /* set the channel to suspended state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* KONRAD FIX ME */ - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the channel is blocked */ - if (!(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) { - SS7_WARN("Received UBL on circuit that is not blocked! span= %d, chan= %d , flag = %x \n", g_ftdm_sngss7_data.cfg.isupCkt[circuit].span, g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan,sngss7_info->blk_flags ); - } - - /* throw the unblock flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); - - /* clear the block flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX_DN); - - /* set the channel to suspended state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* throw the reset flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* throw the reset flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - if ( sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX) ) { - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #%d, dropping\n", sngss7_info->circuit->cic); - } - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived RSC-RLC in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} -/******************************************************************************/ -ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_span_data_t *sngss7_span = NULL; - int range = 0; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* extract the range value from the event structure */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* fill in the span structure for this circuit */ - sngss7_span = ftdmchan->span->signal_data; - if (sngss7_info->rx_grs.range) { - SS7_CRITICAL("Cannot handle another GRS on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - sngss7_info->rx_grs.circuit = circuit; - sngss7_info->rx_grs.range = range; - - ftdm_set_flag(sngss7_span, SNGSS7_RX_GRS_PENDING); - /* the reset will be started in the main thread by "check_if_rx_grs_started" */ - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_span_data_t *sngss7_span = NULL; - int range = 0; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* extract the range value from the event structure */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received GRA with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* fill in the span structure for this circuit */ - sngss7_span = ftdmchan->span->signal_data; - if (sngss7_info->rx_gra.range) { - SS7_ERROR("Cannot handle another GRA on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - sngss7_info->rx_gra.circuit = circuit; - sngss7_info->rx_gra.range = range; - - /* check if there is a cause value in the GRA */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres == PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - - sngss7_info->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val; - } - - ftdm_set_flag(sngss7_span, SNGSS7_RX_GRA_PENDING); - - /* the reset will be started in the main thread by "check_if_rx_gra_started" */ - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the circuit is already blocked or not */ - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { - SS7_WARN("Received local BLO on circuit that is already blocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); - - /* set the channel to suspended state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the circuit is blocked or not */ - if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { - SS7_WARN("Received local UBL on circuit that is not blocked!\n"); - } - - /* throw the ckt unblock flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); - - /* set the channel to suspended state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_chan_data_t *cinfo = NULL; - sngss7_span_data_t *sngss7_span = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* find out if the cic belongs to one of our GRS requests, if so, - * all circuits in the request must be blocked */ - sngss7_span = ftdmchan->span->signal_data; - iter = ftdm_span_get_chan_iterator(ftdmchan->span, NULL); - curr = iter; - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *fchan = ftdm_iterator_current(curr); - - ftdm_channel_lock(fchan); - - cinfo = fchan->call_data; - if (circuit == cinfo->tx_grs.circuit) { - cinfo->ucic.circuit = cinfo->tx_grs.circuit; - cinfo->ucic.range = cinfo->tx_grs.range; - ftdm_set_flag(sngss7_span, SNGSS7_UCIC_PENDING); - - SS7_WARN("Set span SNGSS7_UCIC_PENDING for ISUP circuit = %d!\n", circuit); - - ftdm_channel_unlock(fchan); - - goto done; - } - - ftdm_channel_unlock(fchan); - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* throw the ckt block flag */ - SS7_DEBUG("Set FLAG_CKT_UCIC_BLOCK for ISUP circuit = %d!\n", circuit); - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); - - /* set the channel to suspended state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); -done: - if (iter) { - ftdm_iterator_free(iter); - } - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_span_data_t *sngss7_span = NULL; - ftdm_channel_t *ftdmchan = NULL; - int range; - uint8_t status[255]; - int blockType = 0; - int byte = 0; - int bit = 0; - int x; - int loop_range=0; - - ftdm_running_return(FTDM_FAIL); - - memset(&status[0], '\0', sizeof(status)); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - /* grab the span info */ - sngss7_span = ftdmchan->span->signal_data; - - /* figure out what type of block needs to be applied */ - if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) { - blockType = siStaEvnt->cgsmti.typeInd.val; - } else { - SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* pull out the range value */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* pull out the status field */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) { - for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { - status[x] = siStaEvnt->rangStat.status.val[x]; - } - } else { - SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* save the circuit, range and status */ - sngss7_span->rx_cgb.circuit = circuit; - sngss7_span->rx_cgb.range = range; - sngss7_span->rx_cgb.type = blockType; - for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { - sngss7_span->rx_cgb.status[x] = status[x]; - } - - /* loop over the cics starting from circuit until range+1 */ - loop_range = circuit + range + 1; - x = circuit; - while( x < loop_range ) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) { - loop_range++; - } - else { - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); - } else { - ftdm_mutex_lock(ftdmchan->mutex); - if (status[byte] & (1 << bit)) { - switch (blockType) { - /**********************************************************************/ - case 0: /* maintenance oriented */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); - break; - /**********************************************************************/ - case 1: /* hardware failure oriented */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - break; - /**********************************************************************/ - case 2: /* reserved for national use */ - break; - /**********************************************************************/ - default: - break; - /**********************************************************************/ - } - } - - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - /* update the bit and byte counter*/ - bit ++; - if (bit == 8) { - byte++; - bit = 0; - } - } - } - x++; - } - - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - ft_to_sngss7_cgba(ftdmchan); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_span_data_t *sngss7_span = NULL; - ftdm_channel_t *ftdmchan = NULL; - int range; - uint8_t status[255]; - int blockType = 0; - int byte = 0; - int bit = 0; - int x; - int loop_range=0; - ftdm_sigmsg_t sigev; - - ftdm_running_return(FTDM_FAIL); - - memset(&sigev, 0, sizeof (sigev)); - memset(&status[0], '\0', sizeof(status)); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* grab the span info */ - sngss7_span = ftdmchan->span->signal_data; - - /* figure out what type of block needs to be applied */ - if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) { - blockType = siStaEvnt->cgsmti.typeInd.val; - } else { - SS7_ERROR("Received CGU with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* pull out the range value */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received CGU with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* pull out the status field */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) { - for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { - status[x] = siStaEvnt->rangStat.status.val[x]; - } - } else { - SS7_ERROR("Received CGU with no status value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - /* save the circuit, range and status */ - sngss7_span->rx_cgu.circuit = circuit; - sngss7_span->rx_cgu.range = range; - sngss7_span->rx_cgu.type = blockType; - for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { - sngss7_span->rx_cgu.status[x] = status[x]; - } - - /* loop over the cics starting from circuit until range+1 */ - loop_range = circuit + range + 1; - x = circuit; - while( x < loop_range ) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) { - loop_range++; - } else { - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); - } - else { - ftdm_mutex_lock(ftdmchan->mutex); - - if (status[byte] & (1 << bit)) { - switch (blockType) { - /**********************************************************************/ - case 0: /* maintenance oriented */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - break; - /**********************************************************************/ - case 1: /* hardware failure oriented */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - break; - /**********************************************************************/ - case 2: /* reserved for national use */ - break; - /**********************************************************************/ - default: - break; - /**********************************************************************/ - } /* switch (blockType) */ - } /* if (status[byte] & (1 << bit)) */ - - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - - /* bring the sig status down */ - if (sngss7_channel_status_clear(sngss7_info)) { - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - } - - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - ftdm_mutex_unlock(ftdmchan->mutex); - - /* update the bit and byte counter*/ - bit ++; - if (bit == 8) { - byte++; - bit = 0; - } - } - } - x++; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - ft_to_sngss7_cgua(ftdmchan); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - ftdm_running_return(FTDM_FAIL); - - /* confirm that the circuit is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("[CIC:%d]Rx %s on non-voice CIC\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } else { - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_FAIL; - } - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx %s\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - } - - /* handle overload */ - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic); - - sng_isup_reg_info_show(); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c deleted file mode 100644 index 95ff402ae8..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Copyright (c) 2009, Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); -void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); -void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); -void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); -void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); -void sngss7_ssp_sta_cfm(uint32_t infId); -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_CON_IND_EVENT; - memcpy(&sngss7_event->event.siConEvnt, siConEvnt, sizeof(*siConEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_CON_CFM_EVENT; - memcpy(&sngss7_event->event.siConEvnt, siConEvnt, sizeof(*siConEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->evntType = evntType; - sngss7_event->event_id = SNGSS7_CON_STA_EVENT; - memcpy(&sngss7_event->event.siCnStEvnt, siCnStEvnt, sizeof(*siCnStEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_REL_IND_EVENT; - memcpy(&sngss7_event->event.siRelEvnt, siRelEvnt, sizeof(*siRelEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_REL_CFM_EVENT; - memcpy(&sngss7_event->event.siRelEvnt, siRelEvnt, sizeof(*siRelEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_DAT_IND_EVENT; - memcpy(&sngss7_event->event.siInfoEvnt, siInfoEvnt, sizeof(*siInfoEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->evntType = evntType; - sngss7_event->event_id = SNGSS7_FAC_IND_EVENT; - memcpy(&sngss7_event->event.siFacEvnt, siFacEvnt, sizeof(*siFacEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->evntType = evntType; - sngss7_event->event_id = SNGSS7_FAC_CFM_EVENT; - memcpy(&sngss7_event->event.siFacEvnt, siFacEvnt, sizeof(*siFacEvnt)); - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -/******************************************************************************/ -void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_UMSG_IND_EVENT; - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - -} -/* GENERAL STATUS *************************************************************/ -void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - uint32_t intfId; - int x; - - - - /* check if the eventType is a pause/resume */ - switch (evntType) { - /**************************************************************************/ - case (SIT_STA_PAUSEIND): - case (SIT_STA_RESUMEIND): - /* the circuit may or may not be on the local system so we have to find - * circuit with the same intfId. The circuit specified might also be - * a non-voice cic so we also need to find the first voice cic on this - * system with the same intfId. - */ - intfId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_DEBUG("Rx %s on circuit that is not a voice CIC (%d) finding a new circuit\n", - DECODE_LCC_EVENT(evntType), - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic); - } - - x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1; - while ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) && - (g_ftdm_sngss7_data.cfg.isupCkt[x].id < ((g_ftdm_sngss7_data.cfg.procId + 1) * MAX_CIC_MAP_LENGTH))) { - /**********************************************************************/ - /* confirm this is a voice channel and not a gap/sig (no ftdmchan there) */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - /* compare the intfIds */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].infId == intfId) { - /* we have a match, setup the pointers to the correct values */ - circuit = x; - - /* confirm that the circuit is active on our side otherwise move to the next circuit */ - if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[circuit], SNGSS7_ACTIVE)) { - SS7_DEBUG("[CIC:%d]Rx %s but circuit is not active yet, skipping!\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - DECODE_LCC_EVENT(evntType)); - x++; - continue; - } - - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* bounce out of the loop */ - break; - } - } - - x++; - /**********************************************************************/ - } - - /* check if we found any circuits that are on the intfId, drop the message - * if none are found */ - if (!ftdmchan) { - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - break; - /**************************************************************************/ - default: - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - ftdm_log(FTDM_LOG_DEBUG, "Rx %s on circuit that is not a voice CIC (%d) (circuit:%d)\n", - DECODE_LCC_EVENT(evntType), g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - break; - /**************************************************************************/ - } /* switch (evntType) */ - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->globalFlg = globalFlg; - sngss7_event->evntType = evntType; - sngss7_event->event_id = SNGSS7_STA_IND_EVENT; - if (siStaEvnt != NULL) { - memcpy(&sngss7_event->event.siStaEvnt, siStaEvnt, sizeof(*siStaEvnt)); - } - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); -} - -/******************************************************************************/ -void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_SUSP_IND_EVENT; - if (siSuspEvnt != NULL) { - memcpy(&sngss7_event->event.siSuspEvnt, siSuspEvnt, sizeof(*siSuspEvnt)); - } - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - -} - -/******************************************************************************/ -void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { - SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_RESM_IND_EVENT; - if (siResmEvnt != NULL) { - memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt)); - } - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - -} - -/******************************************************************************/ -void sngss7_ssp_sta_cfm(uint32_t infId) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); -#if 0 - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - - /* initalize the sngss7_event */ - sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); - if (sngss7_event == NULL) { - SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; - } - memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - - /* fill in the sngss7_event struct */ - sngss7_event->spInstId = spInstId; - sngss7_event->suInstId = suInstId; - sngss7_event->circuit = circuit; - sngss7_event->event_id = SNGSS7_RESM_IND_EVENT; - if (siSuspEvnt != NULL) { - memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt)); - } - - /* enqueue this event */ - ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); -#endif - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - -} -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c deleted file mode 100644 index a4c064a323..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ /dev/null @@ -1,1155 +0,0 @@ -/* - * Copyright (c) 2009|Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms|with or without - * modification|are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice|this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice|this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT - * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, - * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -void handle_sng_log(uint8_t level, char *fmt,...); -void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta); -void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); -void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta); -void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta); -void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta); -void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta); - -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -void handle_sng_log(uint8_t level, char *fmt,...) -{ - char *data; - int ret; - va_list ap; - - va_start(ap, fmt); - ret = vasprintf(&data, fmt, ap); - if (ret == -1) { - return; - } - - switch (level) { - /**************************************************************************/ - case SNG_LOGLEVEL_DEBUG: - ftdm_log(FTDM_LOG_DEBUG, "sng_ss7->%s", data); - break; - /**************************************************************************/ - case SNG_LOGLEVEL_WARN: - ftdm_log(FTDM_LOG_WARNING, "sng_ss7->%s", data); - break; - /**************************************************************************/ - case SNG_LOGLEVEL_INFO: - ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data); - break; - /**************************************************************************/ - case SNG_LOGLEVEL_NOTICE: - ftdm_log(FTDM_LOG_NOTICE, "sng_ss7->%s", data); - break; - /**************************************************************************/ - case SNG_LOGLEVEL_ERROR: - ftdm_log(FTDM_LOG_ERROR, "sng_ss7->%s", data); - break; - /**************************************************************************/ - case SNG_LOGLEVEL_CRIT: - /*printf("%s",data);*/ - ftdm_log(FTDM_LOG_CRIT, "sng_ss7->%s", data); - break; - /**************************************************************************/ - default: - ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data); - break; - /**************************************************************************/ - } - - return; -} - -/******************************************************************************/ -void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta) -{ - - -} /* handle_mtp1_alarm */ - -/******************************************************************************/ -void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) -{ - char buf[50]; - int x = 1; - int log_level = FTDM_LOG_LEVEL_DEBUG; - - memset(buf, '\0', sizeof(buf)); - - switch (sta->t.usta.alarm.category) { - /**************************************************************************/ - case (LCM_CATEGORY_PROTOCOL): - case (LCM_CATEGORY_INTERFACE): - - switch (sta->t.usta.alarm.event) { - /**********************************************************************/ - case (LSD_EVENT_ENTR_CONG): - case (LSD_EVENT_EXIT_CONG): - case (LSD_EVENT_PROT_ST_UP): - case (LSD_EVENT_PROT_ST_DN): - case (LSD_EVENT_LINK_ALIGNED): - case (LSD_EVENT_REMOTE_CONG_START): - case (LSD_EVENT_REMOTE_CONG_END): - case (LSD_EVENT_RX_REMOTE_SIPO): - - /* find the name for the sap in question */ - x = 1; - while (x < (MAX_MTP_LINKS+1)) { - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { - break; - } - x++; - } - - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { - sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); - } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); - } - - - switch (sta->t.usta.alarm.cause) { - case (LCM_CAUSE_MGMT_INITIATED): - ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s[MGMT] cause:%s event:%s\n", - buf, - DECODE_LCM_CAUSE(sta->t.usta.alarm.cause), - DECODE_LSD_EVENT(sta->t.usta.alarm.event)); - break; - case (LCM_CAUSE_UNKNOWN): - default: - { - if ((LSD_EVENT_ALIGN_LOST == sta->t.usta.alarm.event) || - (LSD_EVENT_PROT_ST_DN == sta->t.usta.alarm.event)) { - log_level = FTDM_LOG_LEVEL_WARNING; - } else if ((LSD_EVENT_LINK_ALIGNED == sta->t.usta.alarm.event) || - (LSD_EVENT_PROT_ST_UP == sta->t.usta.alarm.event)){ - log_level = FTDM_LOG_LEVEL_INFO; - } else { - log_level = FTDM_LOG_LEVEL_WARNING; - } - ftdm_log(FTDM_PRE, log_level,"[MTP2]%s cause:%s event:%s\n", - buf, - DECODE_LCM_CAUSE(sta->t.usta.alarm.cause), - DECODE_LSD_EVENT(sta->t.usta.alarm.event)); - break; - } - /******************************************************************/ - } /* switch (sta->t.usta.alarm.cause) */ - break; - /**********************************************************************/ - case (LSD_EVENT_PROT_ERR): - - /* find the name for the sap in question */ - x = 1; - while (x < (MAX_MTP_LINKS+1)) { - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { - break; - } - x++; - } - - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { - sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); - } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); - } - - ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %s\n", - buf, - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - DECODE_LSD_CAUSE(sta->t.usta.alarm.cause)); - break; - /**********************************************************************/ - case (LSD_EVENT_ALIGN_LOST): - - /* find the name for the sap in question */ - x = 1; - while (x < (MAX_MTP_LINKS+1)) { - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { - break; - } - x++; - } - - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { - sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); - } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); - } - - ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %s\n", - buf, - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - DECODE_DISC_REASON(sta->t.usta.evntParm[1])); - break; - /**********************************************************************/ - case (LSD_EVENT_RTB_FULL): - case (LSD_EVENT_RTB_FULL_OVER): - - /* find the name for the sap in question */ - x = 1; - while (x < (MAX_MTP_LINKS+1)) { - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { - break; - } - x++; - } - - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { - sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); - } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); - } - - ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n", - buf, - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - sta->t.usta.evntParm[1], - sta->t.usta.evntParm[2], - sta->t.usta.evntParm[3], - sta->t.usta.evntParm[4]); - break; - /**********************************************************************/ - case (LSD_EVENT_NEG_ACK): - - /* find the name for the sap in question */ - x = 1; - while (x < (MAX_MTP_LINKS+1)) { - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { - break; - } - x++; - } - - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { - sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); - } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); - } - - ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : RTB Queue Len(%d)\n", - buf, - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - sta->t.usta.evntParm[1]); - break; - /**********************************************************************/ - case (LSD_EVENT_DAT_CFM_SDT): - - /* find the name for the sap in question */ - x = 1; - while (x < (MAX_MTP_LINKS+1)) { - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { - break; - } - x++; - } - - if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { - sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); - } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); - } - - ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %s\n", - buf, - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - DECODE_DISC_REASON(sta->t.usta.evntParm[1])); - break; - /**********************************************************************/ - case (LCM_EVENT_UI_INV_EVT): - case (LCM_EVENT_LI_INV_EVT): - ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d) : Primitive (%d)\n", - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - sta->t.usta.alarm.event, - DECODE_LCM_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.alarm.cause, - sta->t.usta.evntParm[0]); - break; - /**********************************************************************/ - case (LCM_EVENT_INV_EVT): - - switch (sta->t.usta.alarm.cause) { - /******************************************************************/ - case (LCM_CAUSE_UNKNOWN): - case (LCM_CAUSE_SWVER_NAVAIL): - ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s : %s : Event (%d)\n", - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - DECODE_LCM_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.evntParm[0]); - break; - /******************************************************************/ - case (LCM_CAUSE_DECODE_ERR): - ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s : %s : Primitive (%d)|Version (%d)\n", - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - DECODE_LCM_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.evntParm[0], - sta->t.usta.evntParm[1]); - break; - /******************************************************************/ - default: - ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d)\n", - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - sta->t.usta.alarm.event, - DECODE_LSD_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.alarm.cause); - break; - /******************************************************************/ - } /* switch (sta->t.usta.alarm.cause) */ - break; - /**********************************************************************/ - default: - ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d)\n", - DECODE_LSD_EVENT(sta->t.usta.alarm.event), - sta->t.usta.alarm.event, - DECODE_LSD_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.alarm.cause); - break; - /**********************************************************************/ - } /* switch (sta->t.usta.alarm.event) */ - break; - /**************************************************************************/ - default: - ftdm_log(FTDM_LOG_ERROR,"[MTP2] Unknown alarm category %d\n", - sta->t.usta.alarm.category); - break; - /**************************************************************************/ - } /* switch(sta->t.usta.alarm.category) */ - - return; -} /* handle_mtp2_alarm */ - -/******************************************************************************/ -void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) -{ - char buf[50]; - int x = 1; - - SS7_RELAY_DBG_FUN(handle_sng_mtp3_alarm); - - memset(buf, '\0', sizeof(buf)); - - switch (sta->hdr.elmId.elmnt) { - /**************************************************************************/ - case (STDLSAP): - - /* find the name for the sap in question */ - x = 1; - while (x < (MAX_MTP_LINKS+1)) { - if (g_ftdm_sngss7_data.cfg.mtp3Link[x].id == sta->hdr.elmId.elmntInst1) { - break; - } - x++; - } - - if (g_ftdm_sngss7_data.cfg.mtp3Link[x].id == 0) { - sprintf(buf, "[SAPID:%d]", sta->hdr.elmId.elmntInst1); - } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp3Link[x].name); - } - - switch (sta->t.usta.alarm.event) { - /**********************************************************************/ - case (LSN_EVENT_INV_OPC_OTHER_END): - - ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n", - buf, - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.evntParm[3], - sta->t.usta.evntParm[2], - sta->t.usta.evntParm[1], - sta->t.usta.evntParm[0]); - break; - /**********************************************************************/ - case (LSN_EVENT_INV_SLC_OTHER_END): - ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s : %s : SLC(%d)\n", - buf, - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.evntParm[0]); - break; - /**********************************************************************/ - default: - ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s(%d) : %s(%d)\n", - buf, - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - sta->t.usta.alarm.event, - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.alarm.cause); - break; - /**********************************************************************/ - } /* sta->t.usta.alarm.event */ - break; - /**************************************************************************/ - case (STNSAP): - ftdm_log(FTDM_LOG_WARNING,"[MTP3][SAPID:%d] %s : %s\n", - sta->hdr.elmId.elmntInst1, - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause)); - break; - /**************************************************************************/ - case (STLNKSET): - ftdm_log(FTDM_LOG_DEBUG,"[MTP3][LNKSET:%d] %s : %s\n", - sta->hdr.elmId.elmntInst1, - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause)); - break; - /**************************************************************************/ - case (STROUT): - switch (sta->t.usta.alarm.event) { - /**********************************************************************/ - case (LSN_EVENT_RX_TRANSFER_MSG): - switch (sta->t.usta.evntParm[5]) { - /******************************************************************/ - case (0x23): - ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFC\n"); - break; - /******************************************************************/ - case (0x34): - ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR\n"); - break; - /******************************************************************/ - case (0x54): - ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA\n"); - break; - /******************************************************************/ - case (0x14): - ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP\n"); - break; - /******************************************************************/ - case (0x24): - ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP (cluster)\n"); - break; - /******************************************************************/ - case (0x64): - ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA (cluster)\n"); - break; - /******************************************************************/ - case (0x44): - ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR (cluster)\n"); - break; - /******************************************************************/ - } /* switch (sta->t.usta.evntParm[5]) */ - break; - /**********************************************************************/ - default: - ftdm_log(FTDM_LOG_WARNING,"[MTP3][DPC:0x%X%X%X%X] %s : %s\n", - sta->t.usta.evntParm[0], - sta->t.usta.evntParm[1], - sta->t.usta.evntParm[2], - sta->t.usta.evntParm[3], - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause)); - break; - /**********************************************************************/ - } /* switch (sta->t.usta.alarm.event) */ - break; - /**************************************************************************/ - default: - ftdm_log(FTDM_LOG_ERROR,"[MTP3] %s(%d) : %s(%d)\n", - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - sta->t.usta.alarm.event, - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), - sta->t.usta.alarm.cause); - break; - /**************************************************************************/ - } /* switch (sta->hdr.elmId.elmnt) */ - - return; -} /* handle_mtp3_alarm */ - -/******************************************************************************/ -void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta) -{ - char msg[250]; - char tmp[25]; - char *p = NULL; - int x = 0; - - SS7_RELAY_DBG_FUN(handle_sng_isup_alarm); - - /* initalize the msg variable to NULLs */ - memset(&msg[0], '\0', sizeof(&msg)); - - /* if the event is REMOTE/LOCAL we don't need to print these */ - if ((sta->t.usta.alarm.event == LSI_EVENT_REMOTE) || - (sta->t.usta.alarm.event == LSI_EVENT_LOCAL)) { - return; - } - - /* point p to the first spot in msg */ - p = &msg[0]; - - p = strcat(p, "[ISUP]"); - - /* go through the dgnVals */ - for (x = 0; x < 5; x++) { - switch (sta->t.usta.dgn.dgnVal[x].type) { - /**********************************************************************/ - case (LSI_USTA_DGNVAL_NONE): - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_EVENT): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[EVENT:%d]",sta->t.usta.dgn.dgnVal[x].t.event); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_SPID): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[SPID:%d]",sta->t.usta.dgn.dgnVal[x].t.spId); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_SUID): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[SUID:%d]",sta->t.usta.dgn.dgnVal[x].t.suId); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_SPINSTID): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[SPINSTID:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.spInstId); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_SUINSTID): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[SUINSTID:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.suInstId); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_CIRCUIT): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[CKT:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.cirId); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_CIC): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[CIC:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.cic); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_INTF): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[INTF:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.intfId); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_DPC): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[DPC:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.dpc); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_ADDRS): -#if 0 - /* - *typedef struct addrs - *{ - *U8 length; - *U8 strg[ADRLEN]; - *} Addrs; - */ - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[ADDRS:%d]",sta->t.usta.dgn.dgnVal[x].t.); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); -#endif - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_SWTCH): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[SWTCH:%d]",sta->t.usta.dgn.dgnVal[x].t.swtch); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_RANGE): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[RANGE:0x%X]",sta->t.usta.dgn.dgnVal[x].t.range); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_STATUS_OCTS): -#if 0 - /* - *typedef struct addrs - *{ - *U8 length; - *U8 strg[ADRLEN]; - *} Addrs; - */ - /* init tmp with NULLs */ - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[STATUS_OCT:0x%X]",sta->t.usta.dgn.dgnVal[x].t.); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); -#endif - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_VER): -#ifdef SI_RUG - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[VER:%d]",sta->t.usta.dgn.dgnVal[x].t.intfVer); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); -#endif - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_TIMER): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[TIMER:0x%X]",sta->t.usta.dgn.dgnVal[x].t.tmrInfo); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_MSGTYPE): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[MSGTYPE:%d]",sta->t.usta.dgn.dgnVal[x].t.msgType); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - case (LSI_USTA_DGNVAL_STATE): - /* init tmp with NULLs */ - memset(&tmp[0], '\0', sizeof(&tmp)); - - /* fill in the dgn val to tmp */ - sprintf(&tmp[0], "[STATE:%d]",sta->t.usta.dgn.dgnVal[x].t.state); - - /* concat tmp to msg */ - p = strcat(p, &tmp[0]); - break; - /**********************************************************************/ - default: - break; - /**********************************************************************/ - } /* switch (sta->t.usta.dgn.dgnVal[x].t.type) */ - } /* for (x = 0; x < 5; x++) */ - - ftdm_log(FTDM_LOG_WARNING,"%s %s : %s\n", - msg, - DECODE_LSI_EVENT(sta->t.usta.alarm.event), - DECODE_LSI_CAUSE(sta->t.usta.alarm.cause)); - - return; - -} /* handle_isup_alarm */ - -/******************************************************************************/ -void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta) -{ - - SS7_RELAY_DBG_FUN(handle_sng_cc_alarm); - return; -} /* handle_cc_alarm */ - -/******************************************************************************/ -void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta) -{ - - SS7_RELAY_DBG_FUN(handle_sng_relay_alarm); - - switch (sta->hdr.elmId.elmnt) { - /**************************************************************************/ - case (LRY_USTA_ERR): /* ERROR */ - ftdm_log(FTDM_LOG_WARNING,"[RELAY] Error: tx procId %d: err procId %d: channel %d: seq %s: reason %s\n", - sta->t.usta.s.ryErrUsta.sendPid, - sta->t.usta.s.ryErrUsta.errPid, - sta->t.usta.s.ryErrUsta.id, - DECODE_LRY_SEQ(sta->t.usta.s.ryErrUsta.sequence), - DECODE_LRY_REASON(sta->t.usta.s.ryErrUsta.reason)); - - /* process the event */ - switch (sta->t.usta.s.ryErrUsta.reason) { - /**********************************************************************/ - case (LRYRSNMGMTREQ): - /* do nothing since this is a shutdown */ - break; - /**********************************************************************/ - default: - /* handle the error */ - handle_relay_disconnect_on_error(sta); - break; - /**********************************************************************/ - } /* switch (sta->t.usta.s.ryErrUsta.reason) */ - - break; - /**************************************************************************/ - case (LRY_USTA_CNG): /* Congestion */ - ftdm_log(FTDM_LOG_WARNING,"[RELAY] Congestion: tx procId %d: rem procId %d: channel %d: %s\n", - sta->t.usta.s.ryCongUsta.sendPid, - sta->t.usta.s.ryCongUsta.remPid, - sta->t.usta.s.ryCongUsta.id, - DECODE_LRY_CONG_FLAGS(sta->t.usta.s.ryCongUsta.flags)); - break; - /**************************************************************************/ - case (LRY_USTA_UP): /* channel up */ - ftdm_log(FTDM_LOG_INFO,"[RELAY] Channel UP: tx procId %d: channel %d\n", - sta->t.usta.s.ryUpUsta.sendPid, - sta->t.usta.s.ryUpUsta.id); - - /* process the event */ - handle_relay_connect(sta); - - break; - /**************************************************************************/ - case (LRY_USTA_DN): /* channel down */ - ftdm_log(FTDM_LOG_WARNING,"[RELAY] Channel DOWN: tx procId %d: channel %d\n", - sta->t.usta.s.ryUpUsta.sendPid, - sta->t.usta.s.ryUpUsta.id); - - /* process the event */ - handle_relay_disconnect_on_down(sta); - - break; - /**************************************************************************/ - case (LRY_USTA_TCP_CONN_FAILED): - ftdm_log(FTDM_LOG_WARNING,"[RELAY] TCP connection failed \n" ); - - break; - /**************************************************************************/ - default: - ftdm_log(FTDM_LOG_ERROR,"Unknown Relay Alram\n"); - break; - /**************************************************************************/ - } /* switch (sta->hdr.elmId.elmnt) */ - - return; -} - -/******************************************************************************/ -void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta) -{ - /* To print the general information */ - ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from M2UA layer \n\n"); - ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d\n", - sta->t.usta.alarm.category, sta->t.usta.alarm.event, sta->t.usta.alarm.cause); - - - /* To print the affected element value */ - switch(sta->hdr.elmId.elmnt) - { - case STMWDLSAP: - { - ftdm_log(FTDM_LOG_INFO," STMWDLSAP: with lnkNmb (%d) \n\n", - sta->t.usta.s.lnkNmb); - break; - } - case STMWSCTSAP: - { - ftdm_log(FTDM_LOG_INFO," STMWSCTSAP: suId (%d) \n\n", - sta->t.usta.s.suId); - break; - } - case STMWPEER: - { - ftdm_log(FTDM_LOG_INFO," STMWPEER: peerId (%d) \n\n", - sta->t.usta.s.peerId); - break; - } - case STMWCLUSTER: - { - ftdm_log(FTDM_LOG_INFO," STMWCLUSTER: clusterId (%d) \n\n", - sta->t.usta.s.peerId); - break; - } - default: - { - ftdm_log(FTDM_LOG_ERROR, "[MW_USTA]: Invalid element \n\n"); - break; - } - } - - /* To print the event specific information */ - switch(sta->t.usta.alarm.event) - { - case LMW_EVENT_TERM_OK: - { - ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_TERM_OK: Association Terminated with PeerId[%d] \n",sta->t.usta.s.peerId); - break; - } - case LMW_EVENT_ENDPOPEN_OK: - { - ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ENDPOPEN_OK: \n"); - break; - } - case LMW_EVENT_ESTABLISH_OK: - { - ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ESTABLISH_OK Event raised on peerId[%d]\n",sta->t.usta.s.peerId); - break; - } - case LMW_EVENT_ESTABLISH_FAIL: - { - ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ESTABLISH_FAIL Event raised on peerId[%d]\n",sta->t.usta.s.peerId); - break; - } - case LMW_EVENT_ASPM: - { - ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ASPM Event raised with peerId (%d)," - " msgType (%d)\n\n",sta->t.usta.s.peerId, - sta->t.usta.t.aspm.msgType); - break; - } - case LMW_EVENT_CLUSTER: - { - ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_CLUSTER Event raised on clusterId (%d), state (%d)\n\n", - sta->t.usta.s.clusterId, sta->t.usta.t.cluster.state); - - break; - } - case LMW_EVENT_NOTIFY: - { - ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_NOTIFY: peerId (%d), aspId (%u), ntfy status type (%d)," - " ntfy status id (%d)\n\n", sta->t.usta.s.peerId, - (uint32_t) sta->t.usta.t.ntfy.aspId, sta->t.usta.t.ntfy.stType, - sta->t.usta.t.ntfy.stId); - - break; - } - - - case LMW_EVENT_M2UA_PROTO_ERROR: - { - ftdm_log(FTDM_LOG_ERROR, " M2UA : LMW_EVENT_M2UA_PROTO_ERROR with errorCode (%u)\n\n", - (uint32_t) sta->t.usta.t.error.errCode); - break; - } - default: - break; - } - -} /* handle_sng_m2ua_alarm */ - -/******************************************************************************/ -void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta) -{ - /* To print the general information */ - ftdm_log(FTDM_LOG_INFO," Recieved a status indication from NIF layer\n"); - ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d\n", sta->t.usta.alarm.category, - sta->t.usta.alarm.event, sta->t.usta.alarm.cause); - - switch(sta->hdr.elmId.elmnt) - { - case STNWDLSAP: - { - ftdm_log(FTDM_LOG_INFO," Recieved STNWDLSAP status indication for suId (%d) \n", sta->t.usta.suId); - switch(sta->t.usta.alarm.event) - { - case LCM_EVENT_LI_INV_EVT: - { - switch(sta->t.usta.alarm.cause) - { - case LCM_CAUSE_INV_SAP: - { - ftdm_log(FTDM_LOG_ERROR, " LCM_CAUSE_INV_SAP Alarm \n"); - break; - } - case LCM_CAUSE_INV_STATE: - { - ftdm_log(FTDM_LOG_ERROR, " LCM_CAUSE_INV_STATE Alarm \n"); - break; - } - default: - break; - } - break; - } - case LCM_EVENT_BND_OK: - { - ftdm_log(FTDM_LOG_INFO," NIF: LCM_EVENT_BND_OK Alarm \n"); - break; - } - case LCM_EVENT_BND_FAIL: - { - ftdm_log(FTDM_LOG_INFO," NIF: LCM_EVENT_BND_FAIL Alarm \n"); - break; - } - default: - break; - } - break; - } - default: - break; - } -} /* handle_sng_nif_alarm */ - -/******************************************************************************/ -void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta) -{ - /* To print the general information */ - ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from TUCL layer \n\n"); - ftdm_log(FTDM_LOG_INFO, " Category = %d , event = %d , cause = %d\n", - sta->t.usta.alarm.category, - sta->t.usta.alarm.event, sta->t.usta.alarm.cause); - - switch(sta->t.usta.alarm.event) - { - case LCM_EVENT_INV_EVT: - { - ftdm_log(FTDM_LOG_INFO," [HI_USTA]: LCM_EVENT_INV_EVT with type (%d)\n\n", - sta->t.usta.info.type); - break; - } - case LHI_EVENT_BNDREQ: - { - ftdm_log(FTDM_LOG_INFO," [HI_USTA]: LHI_EVENT_BNDREQ with type (%d) spId (%d)\n\n", - sta->t.usta.info.type, sta->t.usta.info.spId); - break; - } - case LHI_EVENT_SERVOPENREQ: - case LHI_EVENT_DATREQ: - case LHI_EVENT_UDATREQ: - case LHI_EVENT_CONREQ: - case LHI_EVENT_DISCREQ: -#if(defined(HI_TLS) && defined(HI_TCP_TLS)) - case LHI_EVENT_TLS_ESTREQ: -#endif - { - ftdm_log(FTDM_LOG_INFO," [HI_USTA]: partype (%d) type(%d)\n\n", - sta->t.usta.info.inf.parType, sta->t.usta.info.type); - break; - } - case LCM_EVENT_DMEM_ALLOC_FAIL: - case LCM_EVENT_SMEM_ALLOC_FAIL: - { - ftdm_log(FTDM_LOG_ERROR," [HI_USTA]: MEM_ALLOC_FAIL with region(%d) pool (%d) type(%d)\n\n", - sta->t.usta.info.inf.mem.region, sta->t.usta.info.inf.mem.pool, - sta->t.usta.info.type); - break; - } - default: - break; - } - -} /* handle_sng_tucl_alarm */ - -/******************************************************************************/ -void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta) -{ - ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from SCTP layer \n\n"); - ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d " - " [SB_USTA]: sapId (%d) and swtch (%d)\n", - sta->t.usta.alarm.category, - sta->t.usta.alarm.event, sta->t.usta.alarm.cause, - sta->t.usta.sapId, sta->t.usta.swtch); - - switch(sta->t.usta.alarm.category) - { - case LCM_CATEGORY_INTERFACE: - { - switch(sta->t.usta.alarm.cause) - { - case LCM_CAUSE_INV_SPID: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SPID Alarm \n"); - break; - } - case LCM_CAUSE_SWVER_NAVAIL: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_SWVER_NAVAIL Alarm\n"); - break; - } - case LCM_CAUSE_INV_PAR_VAL: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_PAR_VAL Alarm\n"); - break; - } - case LCM_CAUSE_INV_SUID: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SUID Alarm\n"); - break; - } - case LCM_CAUSE_INV_SAP: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SAP Alarm\n"); - break; - } - default: - break; - } - - break; - } - case LCM_CATEGORY_RESOURCE: - { - switch(sta->t.usta.alarm.cause) - { - case LCM_CAUSE_MEM_ALLOC_FAIL: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_MEM_ALLOC_FAIL Alarm \n"); - break; - } - case LSB_CAUSE_NUM_ADDR_EXCEED: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_NUM_ADDR_EXCEED Alarm\n"); - break; - } - default: - break; - } - break; - } - case LCM_CATEGORY_PROTOCOL: - { - switch(sta->t.usta.alarm.cause) - { - case LSB_CAUSE_PATH_FAILURE: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_PATH_FAILURE Alarm \n"); - break; - } - case LSB_CAUSE_PATH_ACTIVE: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_PATH_ACTIVE Alarm \n"); - break; - } - case LSB_CAUSE_UNRSLVD_ADDR: - { - ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_UNRSLVD_ADDR Alarm \n"); - break; - } - default: - break; - } - break; - } - default: - break; - } - -} /* handle_sng_sctp_alarm */ -/******************************************************************************/ - - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c deleted file mode 100644 index 810c5a2902..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c +++ /dev/null @@ -1,1773 +0,0 @@ -/* - * Copyright (c) 2012, Kapil Gupta - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributors: - * - * - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ -/* FUNCTION PROTOTYPES ********************************************************/ -static int ftmod_tucl_gen_config(void); -static int ftmod_tucl_sap_config(int id); -static int ftmod_sctp_gen_config(void); -static int ftmod_cfg_sctp(void); -static int ftmod_sctp_config(int id); -static ftdm_status_t ftmod_sctp_sap_config(int id); -static ftdm_status_t ftmod_sctp_tsap_config(int id); -static int ftmod_m2ua_gen_config(void); -static int ftmod_m2ua_sctsap_config(int sct_sap_id, int sctp_id); -static int ftmod_m2ua_peer_config(int id); -static int ftmod_m2ua_peer_config1(int m2ua_inf_id, int peer_id); -static int ftmod_m2ua_cluster_config(int idx); -static int ftmod_m2ua_dlsap_config(int idx); -static int ftmod_nif_gen_config(void); -static int ftmod_nif_dlsap_config(int idx); -static int ftmod_sctp_tucl_tsap_bind(int idx); -static int ftmod_m2ua_sctp_sctsap_bind(int idx); -static int ftmod_open_endpoint(int idx); -static int ftmod_init_sctp_assoc(int peer_id); -static int ftmod_nif_m2ua_dlsap_bind(int id); -static int ftmod_nif_mtp2_dlsap_bind(int id); -static int ftmod_m2ua_debug(int action); -static int ftmod_tucl_debug(int action); -static int ftmod_sctp_debug(int action); - -static int ftmod_ss7_sctp_shutdown(void); -static int ftmod_ss7_m2ua_shutdown(void); -static int ftmod_ss7_tucl_shutdown(void); - - -/******************************************************************************/ -ftdm_status_t ftmod_ss7_m2ua_init(void) -{ - /****************************************************************************************************/ - if (sng_isup_init_nif()) { - ftdm_log (FTDM_LOG_ERROR , "Failed to start NIF\n"); - return FTDM_FAIL; - } else { - ftdm_log (FTDM_LOG_INFO ,"Started NIF!\n"); - } - /****************************************************************************************************/ - - if (sng_isup_init_m2ua()) { - ftdm_log (FTDM_LOG_ERROR ,"Failed to start M2UA\n"); - return FTDM_FAIL; - } else { - ftdm_log (FTDM_LOG_INFO ,"Started M2UA!\n"); - } - /****************************************************************************************************/ - - if (sng_isup_init_sctp()) { - ftdm_log (FTDM_LOG_ERROR ,"Failed to start SCTP\n"); - return FTDM_FAIL; - } else { - ftdm_log (FTDM_LOG_INFO ,"Started SCTP!\n"); - } - /****************************************************************************************************/ - - if (sng_isup_init_tucl()) { - ftdm_log (FTDM_LOG_ERROR ,"Failed to start TUCL\n"); - return FTDM_FAIL; - } else { - ftdm_log (FTDM_LOG_INFO ,"Started TUCL!\n"); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_TUCL_PRESENT); - } - /****************************************************************************************************/ - - if(ftmod_tucl_gen_config()){ - ftdm_log (FTDM_LOG_ERROR ,"TUCL GEN configuration: NOT OK\n"); - return FTDM_FAIL; - } else { - ftdm_log (FTDM_LOG_INFO ,"TUCL GEN configuration: OK\n"); - } - /****************************************************************************************************/ - if(ftmod_sctp_gen_config()){ - ftdm_log (FTDM_LOG_ERROR ,"SCTP GEN configuration: NOT OK\n"); - return FTDM_FAIL; - } else { - ftdm_log (FTDM_LOG_INFO ,"SCTP GEN configuration: OK\n"); - } - /****************************************************************************************************/ - if(ftmod_m2ua_gen_config()) { - ftdm_log (FTDM_LOG_ERROR ,"M2UA General configuration: NOT OK\n"); - return FTDM_FAIL; - }else { - ftdm_log (FTDM_LOG_INFO ,"M2UA General configuration: OK\n"); - } - /****************************************************************************************************/ - if(ftmod_nif_gen_config()){ - ftdm_log (FTDM_LOG_ERROR ,"NIF General configuration: NOT OK\n"); - return FTDM_FAIL; - }else { - ftdm_log (FTDM_LOG_INFO ,"NIF General configuration: OK\n"); - } - /****************************************************************************************************/ - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -void ftmod_ss7_m2ua_free() -{ - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_M2UA_PRESENT)) { - ftmod_ss7_m2ua_shutdown(); - sng_isup_free_m2ua(); - } - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SCTP_PRESENT)) { - ftmod_ss7_sctp_shutdown(); - sng_isup_free_sctp(); - } - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_TUCL_PRESENT)) { - ftmod_ss7_tucl_shutdown(); - sng_isup_free_tucl(); - } -} - -/******************************************************************************/ -static int ftmod_ss7_tucl_shutdown() -{ - Pst pst; - HiMngmt cntrl; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(HiMngmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTHI; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTHI; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STGEN; /* General */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = ASHUTDOWN; - - return (sng_cntrl_tucl (&pst, &cntrl)); -} -/******************************************************************************/ -static int ftmod_ss7_m2ua_shutdown() -{ - Pst pst; - MwMgmt cntrl; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(MwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTMW; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STMWGEN; /* General */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = ASHUTDOWN; - - return (sng_cntrl_m2ua (&pst, &cntrl)); -} -/***********************************************************************************************************************/ -static int ftmod_ss7_sctp_shutdown() -{ - Pst pst; - SbMgmt cntrl; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(SbMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTSB; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTSB; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STSBGEN; /* General */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = ASHUTDOWN; - - return (sng_cntrl_sctp (&pst, &cntrl)); -} - -/******************************************************************************/ - - - -ftdm_status_t ftmod_ss7_m2ua_cfg(void) -{ - int x=0; - - /* SCTP configuration */ - if(ftmod_cfg_sctp()){ - ftdm_log (FTDM_LOG_ERROR ,"SCTP Configuration : NOT OK\n"); - return FTDM_FAIL; - } else { - ftdm_log (FTDM_LOG_INFO ,"SCTP Configuration : OK\n"); - } - - /****************************************************************************************************/ - /* M2UA SCTP SAP configurations */ - x = 1; - while(xspId = k->id ; /* each SCTP link there will be one tucl sap */ - pCfg->uiSel = 0x00; /*loosley coupled */ - pCfg->flcEnb = TRUE; - pCfg->txqCongStrtLim = HI_SAP_TXN_QUEUE_CONG_START_LIMIT; - pCfg->txqCongDropLim = HI_SAP_TXN_QUEUE_CONG_DROP_LIMIT; - pCfg->txqCongStopLim = HI_SAP_TXN_QUEUE_CONG_STOP_LIMIT; - pCfg->numBins = 10; - - pCfg->uiMemId.region = S_REG; - pCfg->uiMemId.pool = S_POOL; - pCfg->uiPrior = PRIOR0; - pCfg->uiRoute = RTESPEC; - - return(sng_cfg_tucl(&pst, &cfg)); -} - -/****************************************************************************************************/ - -static int ftmod_sctp_gen_config(void) -{ - SbMgmt cfg; - Pst pst; - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSB; - - /* clear the configuration structure */ - memset(&cfg, 0, sizeof(cfg)); - - /* fill in the post structure */ - smPstInit(&cfg.t.cfg.s.genCfg.smPst); - /*fill in the specific fields of the header */ - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSB; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STSBGEN; - -#ifdef SB_IPV6_SUPPORTED - /* U8 ipv6SrvcReqdFlg; */ /* IPV6 service required for sctp */ -#endif - - cfg.t.cfg.s.genCfg.serviceType = HI_SRVC_RAW_SCTP; /* Usr packetized TCP Data */ /* TUCL transport protocol (IP/UDP) */ - cfg.t.cfg.s.genCfg.maxNmbSctSaps = SB_MAX_SCT_SAPS; /* max no. SCT SAPS */ - cfg.t.cfg.s.genCfg.maxNmbTSaps = SB_MAX_T_SAPS; /* max no. Transport SAPS */ - cfg.t.cfg.s.genCfg.maxNmbEndp = SB_MAX_NUM_OF_ENDPOINTS; /* max no. endpoints */ - cfg.t.cfg.s.genCfg.maxNmbAssoc = SB_MAX_NUM_OF_ASSOC; /* max no. associations */ - cfg.t.cfg.s.genCfg.maxNmbDstAddr = SB_MAX_NUM_OF_DST_ADDR; /* max no. dest. addresses */ - cfg.t.cfg.s.genCfg.maxNmbSrcAddr = SB_MAX_NUM_OF_SRC_ADDR; /* max no. src. addresses */ - cfg.t.cfg.s.genCfg.maxNmbTxChunks = SB_MAX_NUM_OF_TX_CHUNKS; - cfg.t.cfg.s.genCfg.maxNmbRxChunks = SB_MAX_NUM_OF_RX_CHUNKS; - cfg.t.cfg.s.genCfg.maxNmbInStrms = SB_MAX_INC_STREAMS; - cfg.t.cfg.s.genCfg.maxNmbOutStrms = SB_MAX_OUT_STREAMS; - cfg.t.cfg.s.genCfg.initARwnd = SB_MAX_RWND_SIZE; - cfg.t.cfg.s.genCfg.mtuInitial = SB_MTU_INITIAL; - cfg.t.cfg.s.genCfg.mtuMinInitial = SB_MTU_MIN_INITIAL; - cfg.t.cfg.s.genCfg.mtuMaxInitial = SB_MTU_MAX_INITIAL; - cfg.t.cfg.s.genCfg.performMtu = FALSE; - cfg.t.cfg.s.genCfg.timeRes = 1; - sprintf((char*)cfg.t.cfg.s.genCfg.hostname, "www.sangoma.com"); /* DAVIDY - Fix this later, probably ignored */ - cfg.t.cfg.s.genCfg.useHstName = FALSE; /* Flag whether hostname is to be used in INIT and INITACK msg */ - cfg.t.cfg.s.genCfg.reConfig.maxInitReTx = 8; - cfg.t.cfg.s.genCfg.reConfig.maxAssocReTx = 10; - cfg.t.cfg.s.genCfg.reConfig.maxPathReTx = 10; - cfg.t.cfg.s.genCfg.reConfig.altAcceptFlg = TRUE; - cfg.t.cfg.s.genCfg.reConfig.keyTm = 600; /* initial value for MD5 Key expiry timer */ - cfg.t.cfg.s.genCfg.reConfig.alpha = 12; - cfg.t.cfg.s.genCfg.reConfig.beta = 25; -#ifdef SB_ECN - cfg.t.cfg.s.genCfg.reConfig.ecnFlg = TRUE; -#endif - - return(sng_cfg_sctp(&pst, &cfg)); -} - -/****************************************************************************************************/ -static int ftmod_cfg_sctp(void) -{ - int x=0; - - x = 1; - while(xid; - - c = &cfg.t.cfg.s.tSapCfg; - c->swtch = LSB_SW_RFC_REL0; - c->suId = k->id; - c->sel = 0; - c->ent = ENTHI; - c->inst = S_INST; - c->procId = g_ftdm_sngss7_data.cfg.procId; - c->memId.region = S_REG; - c->memId.pool = S_POOL; - c->prior = PRIOR1; - c->route = RTESPEC; - c->srcNAddrLst.nmb = k->numSrcAddr; - for (i=0; i <= (k->numSrcAddr-1); i++) { - c->srcNAddrLst.nAddr[i].type = CM_NETADDR_IPV4; - c->srcNAddrLst.nAddr[i].u.ipv4NetAddr = k->srcAddrList[i+1]; - } - - c->reConfig.spId = k->id; - c->reConfig.maxBndRetry = 3; - c->reConfig.tIntTmr = 200; - - ret = sng_cfg_sctp(&pst, &cfg); - if (0 == ret) { - SS7_INFO("SCTP TSAP [%d] configuration DONE!\n", id); - return FTDM_SUCCESS; - } else { - SS7_CRITICAL("SCTP TSAP [%d] configuration FAILED!\n", id); - return FTDM_FAIL; - } -} - -/****************************************************************************************************/ - -ftdm_status_t ftmod_sctp_sap_config(int id) -{ - Pst pst; - SbMgmt cfg; - SbSctSapCfg *c; - - int ret = -1; - sng_sctp_link_t *k = &g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[id]; - - smPstInit(&pst); - pst.dstEnt = ENTSB; - - memset(&cfg, 0x0, sizeof(cfg)); - smHdrInit(&cfg.hdr); - - cfg.hdr.msgType = TCFG; - cfg.hdr.entId.ent = ENTSB; - cfg.hdr.entId.inst = S_INST; - cfg.hdr.elmId.elmnt = STSBSCTSAP; - cfg.hdr.elmId.elmntInst1 = k->id; - - c = &cfg.t.cfg.s.sctSapCfg; - c->swtch = LSB_SW_RFC_REL0; - c->spId = k->id; /* Service Provider SAP Id */ - c->sel = 0; - c->memId.region = S_REG; - c->memId.pool = S_POOL; - c->prior = PRIOR1; - c->route = RTESPEC; - - /* Maximum time to wait before the SCTP layer must send a Selective Acknowledgement (SACK) message. Valid range is 1 -165535. */ - c->reConfig.maxAckDelayTm = 200; - /* Maximum number of messages to receive before the SCTP layer must send a SACK message. Valid range is 1 - 165535. */ - c->reConfig.maxAckDelayDg = 2; - /* Initial value of the retransmission timer (RTO). The SCTP layer retransmits data after waiting for feedback during this time period. Valid range is 1 - 65535. */ - c->reConfig.rtoInitial = 3000; - /* Minimum value used for the RTO. If the computed value of RTO is less than rtoMin, the computed value is rounded up to this value. */ - c->reConfig.rtoMin = 1000; - /* Maxiumum value used for RTO. If the computed value of RTO is greater than rtoMax, the computed value is rounded down to this value. */ - c->reConfig.rtoMax = 10000; - /* Default Freeze timer value */ - c->reConfig.freezeTm = 3000; - /* Base cookie lifetime for the cookie in the Initiation Acknowledgement (INIT ACK) message. */ - c->reConfig.cookieLife = 60000; - /* Default heartbeat interval timer. Valid range is 1 - 65535. */ - c->reConfig.intervalTm = 3000; - /* Maximum burst value. Valid range is 1 - 65535. */ - c->reConfig.maxBurst = 4; - /*Maximum number of heartbeats sent at each retransmission timeout (RTO). Valid range is 1 - 65535. */ - c->reConfig.maxHbBurst = 1; - /*Shutdown guard timer value for graceful shutdowns. */ - c->reConfig.t5SdownGrdTm = 15000; - /* Action to take when the receiver's number of incoming streams is less than the sender's number of outgoing streams. Valid values are: - TRUE = Accept incoming stream and continue association. - FALSE = Abort the association. - */ - c->reConfig.negAbrtFlg = FALSE; - /* Whether to enable or disable heartbeat by default. Valid values are: - TRUE = Enable heartbeat. - FALSE = Disable heartbeat. - */ - c->reConfig.hBeatEnable = TRUE; - /* Flow control start threshold. When the number of messages in SCTPÂ’s message queue reaches this value, flow control starts. */ - c->reConfig.flcUpThr = 8; - /* Flow control stop threshold. When the number of messages in SCTPÂ’s message queue reaches this value, flow control stops. */ - c->reConfig.flcLowThr = 6; - - c->reConfig.handleInitFlg = FALSE; - - ret = sng_cfg_sctp(&pst, &cfg); - if (0 == ret) { - SS7_INFO("SCTP SAP [%d] configuration DONE!\n", id); - return FTDM_SUCCESS; - } else { - SS7_CRITICAL("SCTP SAP [%d] configuration FAILED!\n", id); - return FTDM_FAIL; - } -} - -/**********************************************************************************************/ -/* M2UA - General configuration */ -static int ftmod_m2ua_gen_config(void) -{ - Pst pst; - MwMgmt cfg; - - memset((U8 *)&cfg, 0, sizeof(MwMgmt)); - memset((U8 *)&pst, 0, sizeof(Pst)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cfg.hdr.msgType = TCFG; /* message type */ - cfg.hdr.entId.ent = ENTMW; /* entity */ - cfg.hdr.entId.inst = 0; /* instance */ - cfg.hdr.elmId.elmnt = STMWGEN; /* General */ - cfg.hdr.transId = 0; /* transaction identifier */ - - cfg.hdr.response.selector = 0; - cfg.hdr.response.prior = PRIOR0; - cfg.hdr.response.route = RTESPEC; - cfg.hdr.response.mem.region = S_REG; - cfg.hdr.response.mem.pool = S_POOL; - - - - cfg.t.cfg.s.genCfg.nodeType = LMW_TYPE_SGP; /* NodeType == SGP or ASP */ - cfg.t.cfg.s.genCfg.maxNmbIntf = MW_MAX_NUM_OF_INTF; - cfg.t.cfg.s.genCfg.maxNmbCluster = MW_MAX_NUM_OF_CLUSTER; - cfg.t.cfg.s.genCfg.maxNmbPeer = MW_MAX_NUM_OF_PEER; - cfg.t.cfg.s.genCfg.maxNmbSctSap = MW_MAX_NUM_OF_SCT_SAPS; - cfg.t.cfg.s.genCfg.timeRes = 1; /* timer resolution */ - cfg.t.cfg.s.genCfg.maxClusterQSize = MW_MAX_CLUSTER_Q_SIZE; - cfg.t.cfg.s.genCfg.maxIntfQSize = MW_MAX_INTF_Q_SIZE; - -#ifdef LCMWMILMW - cfg.t.cfg.s.genCfg.reConfig.smPst.selector = 0; /* selector */ -#else /* LCSBMILSB */ - cfg.t.cfg.s.genCfg.reConfig.smPst.selector = 1; /* selector */ -#endif /* LCSBMILSB */ - - cfg.t.cfg.s.genCfg.reConfig.smPst.region = S_REG; /* region */ - cfg.t.cfg.s.genCfg.reConfig.smPst.pool = S_POOL; /* pool */ - cfg.t.cfg.s.genCfg.reConfig.smPst.prior = PRIOR0; /* priority */ - cfg.t.cfg.s.genCfg.reConfig.smPst.route = RTESPEC; /* route */ - - cfg.t.cfg.s.genCfg.reConfig.smPst.dstEnt = ENTSM; /* dst entity */ - cfg.t.cfg.s.genCfg.reConfig.smPst.dstInst = S_INST; /* dst inst */ - cfg.t.cfg.s.genCfg.reConfig.smPst.dstProcId = SFndProcId(); /* src proc id */ - - cfg.t.cfg.s.genCfg.reConfig.smPst.srcEnt = ENTMW; /* src entity */ - cfg.t.cfg.s.genCfg.reConfig.smPst.srcInst = S_INST; /* src inst */ - cfg.t.cfg.s.genCfg.reConfig.smPst.srcProcId = SFndProcId(); /* src proc id */ - - cfg.t.cfg.s.genCfg.reConfig.tmrFlcPoll.enb = TRUE; /* SCTP Flc Poll timer */ - cfg.t.cfg.s.genCfg.reConfig.tmrFlcPoll.val = 10; - -#ifdef MWASP - cfg.t.cfg.s.genCfg.reConfig.tmrAspm.enb = TRUE; /* ASPM timer */ - cfg.t.cfg.s.genCfg.reConfig.tmrAspm.val = 10; - cfg.t.cfg.s.genCfg.reConfig.tmrHeartBeat.enb = TRUE; /* Heartbeat timer */ - cfg.t.cfg.s.genCfg.reConfig.tmrHeartBeat.val = 10; -#endif - -#ifdef MWSG - cfg.t.cfg.s.genCfg.reConfig.tmrAsPend.enb = TRUE; /* AS-PENDING timer */ - cfg.t.cfg.s.genCfg.reConfig.tmrAsPend.val = 10; - cfg.t.cfg.s.genCfg.reConfig.tmrCongPoll.enb = TRUE; /* SS7 Congestion poll timer */ - cfg.t.cfg.s.genCfg.reConfig.tmrCongPoll.val = 10; - cfg.t.cfg.s.genCfg.reConfig.tmrHeartBeat.enb = FALSE; /* HBtimer only at ASP */ -#endif - cfg.t.cfg.s.genCfg.reConfig.aspmRetry = 5; - - return (sng_cfg_m2ua (&pst, &cfg)); -} - -/**********************************************************************************************/ -static int ftmod_m2ua_peer_config(int id) -{ - int x = 0; - int peer_id = 0; - sng_m2ua_cfg_t* m2ua = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[id]; - sng_m2ua_cluster_cfg_t* clust = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[m2ua->clusterId]; - sng_m2ua_peer_cfg_t* peer = NULL; - - if((clust->flags & SNGSS7_CONFIGURED)){ - ftdm_log (FTDM_LOG_INFO, " ftmod_m2ua_peer_config: Cluster [%s] is already configured \n", clust->name); - return 0x00; - } - - /*NOTE : SCTSAP is based on per source address , so if we have same Cluster / peer shared across many then - * we dont have do configuration for each time */ - - /* loop through peer list from cluster to configure SCTSAP */ - - for(x = 0; x < clust->numOfPeers;x++){ - peer_id = clust->peerIdLst[x]; - peer = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[peer_id]; - if(ftmod_m2ua_sctsap_config(id, peer->sctpId)){ - ftdm_log (FTDM_LOG_ERROR, " ftmod_m2ua_sctsap_config: M2UA SCTSAP for M2UA Intf Id[%d] config FAILED \n", id); - return 0x01; - }else{ - ftdm_log (FTDM_LOG_INFO, " ftmod_m2ua_sctsap_config: M2UA SCTSAP for M2UA Intf Id[%d] config SUCCESS \n", id); - } - if(ftmod_m2ua_peer_config1(id, peer_id)){ - ftdm_log (FTDM_LOG_ERROR, " ftmod_m2ua_peer_config1: M2UA Peer[%d] configuration for M2UA Intf Id[%d] config FAILED \n", peer_id, id); - return 0x01; - }else{ - ftdm_log (FTDM_LOG_INFO, " ftmod_m2ua_peer_config1: M2UA Peer[%d] configuration for M2UA Intf Id[%d] config SUCCESS \n", peer_id, id); - } - - clust->sct_sap_id = id; - - /* set configured flag for cluster and peer */ - clust->flags |= SNGSS7_CONFIGURED; - peer->flags |= SNGSS7_CONFIGURED; - } - - return 0x0;; -} - - -static int ftmod_m2ua_sctsap_config(int sct_sap_id, int sctp_id) -{ - int i; - int ret; - Pst pst; - MwMgmt cfg; - MwMgmt cfm; - sng_sctp_link_t *sctp = &g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[sctp_id]; - - - - memset((U8 *)&cfg, 0, sizeof(MwMgmt)); - memset((U8 *)&cfm, 0, sizeof(MwMgmt)); - memset((U8 *)&pst, 0, sizeof(Pst)); - - /* check is sct_sap is already configured */ - if(!ftmod_m2ua_ssta_req(STMWSCTSAP, sct_sap_id, &cfm )){ - ftdm_log (FTDM_LOG_INFO, " ftmod_m2ua_sctsap_config: SCT SAP [%s] is already configured \n", sctp->name); - return 0x00; - } - - if(LCM_REASON_INVALID_SAP == cfm.cfm.reason){ - ftdm_log (FTDM_LOG_INFO, " ftmod_m2ua_sctsap_config: SCT SAP [%s] is not configured..configuring now \n", sctp->name); - } - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cfg.hdr.msgType = TCFG; /* message type */ - cfg.hdr.entId.ent = ENTMW; /* entity */ - cfg.hdr.entId.inst = 0; /* instance */ - cfg.hdr.elmId.elmnt = STMWSCTSAP; /* SCTSAP */ - cfg.hdr.transId = 0; /* transaction identifier */ - - cfg.hdr.response.selector = 0; - cfg.hdr.response.prior = PRIOR0; - cfg.hdr.response.route = RTESPEC; - cfg.hdr.response.mem.region = S_REG; - cfg.hdr.response.mem.pool = S_POOL; - - cfg.t.cfg.s.sctSapCfg.reConfig.selector = 0; - - /* service user SAP ID */ - cfg.t.cfg.s.sctSapCfg.suId = sct_sap_id; - /* service provider ID */ - cfg.t.cfg.s.sctSapCfg.spId = sctp_id; - /* source port number */ - cfg.t.cfg.s.sctSapCfg.srcPort = sctp->port; - /* interface address */ - /*For multiple IP address support */ -#ifdef SCT_ENDP_MULTI_IPADDR - cfg.t.cfg.s.sctSapCfg.srcAddrLst.nmb = sctp->numSrcAddr; - for (i=0; i <= (sctp->numSrcAddr-1); i++) { - cfg.t.cfg.s.sctSapCfg.srcAddrLst.nAddr[i].type = CM_NETADDR_IPV4; - cfg.t.cfg.s.sctSapCfg.srcAddrLst.nAddr[i].u.ipv4NetAddr = sctp->srcAddrList[i+1]; - } -#else - /* for single ip support ,src address will always be one */ - cfg.t.cfg.s.sctSapCfg.intfAddr.type = CM_NETADDR_IPV4; - cfg.t.cfg.s.sctSapCfg.intfAddr.u.ipv4NetAddr = sctp->srcAddrList[1]; -#endif - - /* lower SAP primitive timer */ - cfg.t.cfg.s.sctSapCfg.reConfig.tmrPrim.enb = TRUE; - cfg.t.cfg.s.sctSapCfg.reConfig.tmrPrim.val = 10; - /* Association primitive timer */ - cfg.t.cfg.s.sctSapCfg.reConfig.tmrAssoc.enb = TRUE; - cfg.t.cfg.s.sctSapCfg.reConfig.tmrAssoc.val = 10; - /* maxnumber of retries */ - cfg.t.cfg.s.sctSapCfg.reConfig.nmbMaxPrimRetry = 5; - /* Life Time of Packets */ - cfg.t.cfg.s.sctSapCfg.reConfig.lifeTime = 200; - /* priority */ - cfg.t.cfg.s.sctSapCfg.reConfig.prior = PRIOR0; - /* route */ - cfg.t.cfg.s.sctSapCfg.reConfig.route = RTESPEC; - cfg.t.cfg.s.sctSapCfg.reConfig.ent = ENTSB; - cfg.t.cfg.s.sctSapCfg.reConfig.inst = 0; - cfg.t.cfg.s.sctSapCfg.reConfig.procId = SFndProcId(); - /* memory region and pool ID */ - cfg.t.cfg.s.sctSapCfg.reConfig.mem.region = S_REG; - cfg.t.cfg.s.sctSapCfg.reConfig.mem.pool = S_POOL; - - if (0 == (ret = sng_cfg_m2ua (&pst, &cfg))){ - sctp->flags |= SNGSS7_CONFIGURED; - } - - return ret; -} - -/****************************************************************************************************/ - -/* M2UA - Peer configuration */ -static int ftmod_m2ua_peer_config1(int m2ua_inf_id, int peer_id) -{ - int i; - Pst pst; - MwMgmt cfg; - sng_m2ua_peer_cfg_t* peer = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[peer_id]; - sng_sctp_link_t *sctp = &g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[peer->sctpId]; - - memset((U8 *)&cfg, 0, sizeof(MwMgmt)); - memset((U8 *)&pst, 0, sizeof(Pst)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cfg.hdr.msgType = TCFG; /* message type */ - cfg.hdr.entId.ent = ENTMW; /* entity */ - cfg.hdr.entId.inst = 0; /* instance */ - cfg.hdr.elmId.elmnt = STMWPEER; /* Peer */ - cfg.hdr.transId = 0; /* transaction identifier */ - - cfg.hdr.response.selector = 0; - cfg.hdr.response.prior = PRIOR0; - cfg.hdr.response.route = RTESPEC; - cfg.hdr.response.mem.region = S_REG; - cfg.hdr.response.mem.pool = S_POOL; - - - - cfg.t.cfg.s.peerCfg.peerId = peer->id; /* peer id */ - cfg.t.cfg.s.peerCfg.aspIdFlag = peer->aspIdFlag; /* aspId flag */ -#ifdef MWASP - cfg.t.cfg.s.peerCfg.selfAspId = peer->selfAspId; /* aspId */ -#endif - cfg.t.cfg.s.peerCfg.assocCfg.suId = peer->sctpId; /* SCTSAP ID */ - cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nmb = peer->numDestAddr; - for (i=0; i <= (peer->numDestAddr); i++) { - cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[i].type = CM_NETADDR_IPV4; - cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[i].u.ipv4NetAddr = peer->destAddrList[i]; - } -#ifdef MW_CFG_DSTPORT - cfg.t.cfg.s.peerCfg.assocCfg.dstPort = peer->port; /* Port on which M2UA runs */ -#endif - cfg.t.cfg.s.peerCfg.assocCfg.srcAddrLst.nmb = sctp->numSrcAddr; /* source address list */ - for (i=0; i <= (sctp->numSrcAddr-1); i++) { - cfg.t.cfg.s.peerCfg.assocCfg.srcAddrLst.nAddr[i].type = CM_NETADDR_IPV4; - cfg.t.cfg.s.peerCfg.assocCfg.srcAddrLst.nAddr[i].u.ipv4NetAddr = sctp->srcAddrList[i+1]; - } - - cfg.t.cfg.s.peerCfg.assocCfg.priDstAddr.type = CM_NETADDR_IPV4; - cfg.t.cfg.s.peerCfg.assocCfg.priDstAddr.u.ipv4NetAddr = cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[0].u.ipv4NetAddr; - - cfg.t.cfg.s.peerCfg.assocCfg.locOutStrms = peer->locOutStrms; -#ifdef SCT3 - cfg.t.cfg.s.peerCfg.assocCfg.tos = 0; -#endif - - return (sng_cfg_m2ua (&pst, &cfg)); -} -/**********************************************************************************************/ -/* M2UA - Cluster configuration */ -static int ftmod_m2ua_cluster_config(int id) -{ - int i; - Pst pst; - MwMgmt cfg; - sng_m2ua_cfg_t* m2ua = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[id]; - sng_m2ua_cluster_cfg_t* clust = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[m2ua->clusterId]; - - memset((U8 *)&cfg, 0, sizeof(MwMgmt)); - memset((U8 *)&pst, 0, sizeof(Pst)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cfg.hdr.msgType = TCFG; /* message type */ - cfg.hdr.entId.ent = ENTMW; /* entity */ - cfg.hdr.entId.inst = 0; /* instance */ - cfg.hdr.elmId.elmnt = STMWCLUSTER; /* Cluster */ - cfg.hdr.transId = 0; /* transaction identifier */ - - cfg.hdr.response.selector = 0; - cfg.hdr.response.prior = PRIOR0; - cfg.hdr.response.route = RTESPEC; - cfg.hdr.response.mem.region = S_REG; - cfg.hdr.response.mem.pool = S_POOL; - - - cfg.t.cfg.s.clusterCfg.clusterId = clust->id; - cfg.t.cfg.s.clusterCfg.trfMode = clust->trfMode; - cfg.t.cfg.s.clusterCfg.loadshareMode = clust->loadShareAlgo; - cfg.t.cfg.s.clusterCfg.reConfig.nmbPeer = clust->numOfPeers; - for(i=0; i<(clust->numOfPeers);i++) { - cfg.t.cfg.s.clusterCfg.reConfig.peer[i] = clust->peerIdLst[i]; - } - - return (sng_cfg_m2ua (&pst, &cfg)); -} - -/**********************************************************************************************/ - -/* M2UA - DLSAP configuration */ -static int ftmod_m2ua_dlsap_config(int id) -{ - Pst pst; - MwMgmt cfg; - sng_m2ua_cfg_t* m2ua = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[id]; - - memset((U8 *)&cfg, 0, sizeof(MwMgmt)); - memset((U8 *)&pst, 0, sizeof(Pst)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cfg.hdr.msgType = TCFG; /* message type */ - cfg.hdr.entId.ent = ENTMW; /* entity */ - cfg.hdr.entId.inst = 0; /* instance */ - cfg.hdr.elmId.elmnt = STMWDLSAP; /* DLSAP */ - cfg.hdr.transId = 0; /* transaction identifier */ - - cfg.hdr.response.selector = 0; - cfg.hdr.response.prior = PRIOR0; - cfg.hdr.response.route = RTESPEC; - cfg.hdr.response.mem.region = S_REG; - cfg.hdr.response.mem.pool = S_POOL; - - - cfg.t.cfg.s.dlSapCfg.lnkNmb = id; /* SapId */ - cfg.t.cfg.s.dlSapCfg.intfId.type = LMW_INTFID_INT; - cfg.t.cfg.s.dlSapCfg.intfId.id.intId = m2ua->iid; - - cfg.t.cfg.s.dlSapCfg.swtch = LMW_SAP_ITU; - - cfg.t.cfg.s.dlSapCfg.reConfig.clusterId = m2ua->clusterId; - cfg.t.cfg.s.dlSapCfg.reConfig.selector = 0; /* Loosely couple mode */ - /* memory region and pool id*/ - cfg.t.cfg.s.dlSapCfg.reConfig.mem.region = S_REG; - cfg.t.cfg.s.dlSapCfg.reConfig.mem.pool = S_POOL; - /* priority */ - cfg.t.cfg.s.dlSapCfg.reConfig.prior = PRIOR0; - /* route */ - cfg.t.cfg.s.dlSapCfg.reConfig.route = RTESPEC; - - return (sng_cfg_m2ua (&pst, &cfg)); - -} -/*****************************************************************************/ -/* NIF - General configuration */ -static int ftmod_nif_gen_config(void) -{ - Pst pst; - NwMgmt cfg; - - memset((U8 *)&cfg, 0, sizeof(NwMgmt)); - memset((U8 *)&pst, 0, sizeof(Pst)); - - smPstInit(&pst); - - pst.dstEnt = ENTNW; - - /* prepare header */ - cfg.hdr.msgType = TCFG; /* message type */ - cfg.hdr.entId.ent = ENTNW; /* entity */ - cfg.hdr.entId.inst = 0; /* instance */ - cfg.hdr.elmId.elmnt = STNWGEN; /* DLSAP */ - cfg.hdr.transId = 0; /* transaction identifier */ - - cfg.hdr.response.selector = 0; - cfg.hdr.response.prior = PRIOR0; - cfg.hdr.response.route = RTESPEC; - cfg.hdr.response.mem.region = S_REG; - cfg.hdr.response.mem.pool = S_POOL; - - cfg.t.cfg.s.genCfg.maxNmbDlSap = NW_MAX_NUM_OF_DLSAPS; - cfg.t.cfg.s.genCfg.timeRes = 1; /* timer resolution */ - - cfg.t.cfg.s.genCfg.reConfig.maxNmbRetry = NW_MAX_NUM_OF_RETRY; - cfg.t.cfg.s.genCfg.reConfig.tmrRetry.enb = TRUE; /* SS7 Congestion poll timer */ - cfg.t.cfg.s.genCfg.reConfig.tmrRetry.val = NW_RETRY_TMR_VALUE; - -#ifdef LCNWMILNW - cfg.t.cfg.s.genCfg.reConfig.smPst.selector = 0; /* selector */ -#else /* LCSBMILSB */ - cfg.t.cfg.s.genCfg.reConfig.smPst.selector = 1; /* selector */ -#endif /* LCSBMILSB */ - - cfg.t.cfg.s.genCfg.reConfig.smPst.region = S_REG; /* region */ - cfg.t.cfg.s.genCfg.reConfig.smPst.pool = S_POOL; /* pool */ - cfg.t.cfg.s.genCfg.reConfig.smPst.prior = PRIOR0; /* priority */ - cfg.t.cfg.s.genCfg.reConfig.smPst.route = RTESPEC; /* route */ - - cfg.t.cfg.s.genCfg.reConfig.smPst.dstEnt = ENTSM; /* dst entity */ - cfg.t.cfg.s.genCfg.reConfig.smPst.dstInst = 0; /* dst inst */ - cfg.t.cfg.s.genCfg.reConfig.smPst.dstProcId = SFndProcId(); /* src proc id */ - - cfg.t.cfg.s.genCfg.reConfig.smPst.srcEnt = ENTNW; /* src entity */ - cfg.t.cfg.s.genCfg.reConfig.smPst.srcInst = 0; /* src inst */ - cfg.t.cfg.s.genCfg.reConfig.smPst.srcProcId = SFndProcId(); /* src proc id */ - - return (sng_cfg_nif (&pst, &cfg)); - -} - -/*****************************************************************************/ - -/* NIF - DLSAP configuration */ -static int ftmod_nif_dlsap_config(int id) -{ - Pst pst; - NwMgmt cfg; - sng_nif_cfg_t* nif = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[id]; - - memset((U8 *)&cfg, 0, sizeof(NwMgmt)); - memset((U8 *)&pst, 0, sizeof(Pst)); - - smPstInit(&pst); - - pst.dstEnt = ENTNW; - - /* prepare header */ - cfg.hdr.msgType = TCFG; /* message type */ - cfg.hdr.entId.ent = ENTNW; /* entity */ - cfg.hdr.entId.inst = 0; /* instance */ - cfg.hdr.elmId.elmnt = STNWDLSAP; /* DLSAP */ - cfg.hdr.transId = 0; /* transaction identifier */ - - cfg.hdr.response.selector = 0; - cfg.hdr.response.prior = PRIOR0; - cfg.hdr.response.route = RTESPEC; - cfg.hdr.response.mem.region = S_REG; - cfg.hdr.response.mem.pool = S_POOL; - cfg.t.cfg.s.dlSapCfg.suId = nif->id; - cfg.t.cfg.s.dlSapCfg.m2uaLnkNmb = nif->m2uaLnkNmb; - cfg.t.cfg.s.dlSapCfg.mtp2LnkNmb = nif->mtp2LnkNmb; - - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.selector = 0; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.region = S_REG; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.pool = S_POOL; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.route = RTESPEC; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.prior = PRIOR0; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.srcEnt = ENTNW; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.srcInst = 0; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.srcProcId = SFndProcId(); - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.dstEnt = ENTMW; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.dstInst = 0; - cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.dstProcId = SFndProcId(); - - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.selector = 0; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.region = S_REG; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.pool = S_POOL; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.route = RTESPEC; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.prior = PRIOR0; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.srcEnt = ENTNW; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.srcInst = 0; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.srcProcId = SFndProcId(); - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.dstEnt = ENTSD; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.dstInst = 0; - cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.dstProcId = SFndProcId(); - - return (sng_cfg_nif (&pst, &cfg)); -} - -/*****************************************************************************/ -uint32_t iptoul(const char *ip) -{ - char i,*tmp; - int strl; - char strIp[16]; - unsigned long val=0, cvt; - if (!ip) - return 0; - - memset(strIp, 0, sizeof(char)*16); - strl = strlen(ip); - strncpy(strIp, ip, strl>=15?15:strl); - - - tmp=strtok(strIp, "."); - for (i=0;i<4;i++) - { - sscanf(tmp, "%lu", &cvt); - val <<= 8; - val |= (unsigned char)cvt; - tmp=strtok(NULL,"."); - } - return (uint32_t)val; -} -/***********************************************************************************************************************/ -void ftmod_ss7_enable_m2ua_sg_logging(void){ - - /* Enable DEBUGs*/ - ftmod_sctp_debug(AENA); - ftmod_m2ua_debug(AENA); - ftmod_tucl_debug(AENA); -} - -/***********************************************************************************************************************/ -void ftmod_ss7_disable_m2ua_sg_logging(void){ - - /* DISABLE DEBUGs*/ - ftmod_sctp_debug(ADISIMM); - ftmod_m2ua_debug(ADISIMM); - ftmod_tucl_debug(ADISIMM); -} - -/***********************************************************************************************************************/ -int ftmod_ss7_m2ua_start(void){ - int x=0; - -/***********************************************************************************************************************/ - x = 1; - while(xclusterId]; - - if(clust->flags & SNGSS7_M2UA_EP_OPENED) { - ftdm_log (FTDM_LOG_INFO ," END-POINT already opened\n"); - return ret; - } - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(MwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTMW; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STMWSCTSAP; /* General */ - cntrl.hdr.transId = 1; /* transaction identifier */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - - cntrl.t.cntrl.action = AMWENDPOPEN; - cntrl.t.cntrl.s.suId = m2ua->id; /* M2UA sct sap Id */ - - - if(0 == (ret = sng_cntrl_m2ua (&pst, &cntrl))){ - clust->flags |= SNGSS7_M2UA_EP_OPENED; - } - return ret; - -} - -/***********************************************************************************************************************/ -static int ftmod_init_sctp_assoc(int peer_id) -{ - - Pst pst; - MwMgmt cntrl; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(MwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTMW; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STMWPEER; /* General */ - cntrl.hdr.transId = 1; /* transaction identifier */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - - cntrl.t.cntrl.action = AMWESTABLISH; - /*cntrl.t.cntrl.s.suId = 1;*/ - - cntrl.t.cntrl.s.peerId = (MwPeerId) peer_id; - - return (sng_cntrl_m2ua (&pst, &cntrl)); -} - -/***********************************************************************************************************************/ -static int ftmod_sctp_tucl_tsap_bind(int id) -{ - Pst pst; - SbMgmt cntrl; - sng_sctp_link_t *k = &g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[id]; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(SbMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTSB; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTSB; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STSBTSAP; /* General */ - cntrl.hdr.transId = 1; /* transaction identifier */ - - cntrl.hdr.response.selector = 0; - - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = ABND_ENA; - cntrl.t.cntrl.sapId = k->id; /* SCT sap id configured at SCTP layer */ - - return (sng_cntrl_sctp (&pst, &cntrl)); -} -/***********************************************************************************************************************/ - -static int ftmod_m2ua_sctp_sctsap_bind(int id) -{ - int ret = 0x00; - Pst pst; - MwMgmt cntrl; - sng_m2ua_cfg_t* m2ua = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[id]; - sng_m2ua_cluster_cfg_t* clust = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[m2ua->clusterId]; - - if(clust->flags & SNGSS7_ACTIVE) { - ftdm_log (FTDM_LOG_INFO ," SCT-SAP is already enabled\n"); - return ret; - } - - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(MwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTMW; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STMWSCTSAP; /* General */ - cntrl.hdr.transId = 1; /* transaction identifier */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = ABND; - cntrl.t.cntrl.s.suId = m2ua->id; - - if(0 == (ret = sng_cntrl_m2ua (&pst, &cntrl))){ - clust->flags |= SNGSS7_ACTIVE; - } - return ret; -} -/***********************************************************************************************************************/ -static int ftmod_nif_m2ua_dlsap_bind(int id) -{ - Pst pst; - NwMgmt cntrl; - sng_nif_cfg_t* nif = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[id]; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(NwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTNW; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTNW; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STNWDLSAP; /* General */ - cntrl.hdr.transId = 1; /* transaction identifier */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = ABND; - cntrl.t.cntrl.suId = nif->id; /* NIF DL sap Id */ - cntrl.t.cntrl.entity = ENTMW; /* M2UA */ - - return (sng_cntrl_nif (&pst, &cntrl)); - -} - -/***********************************************************************************************************************/ -static int ftmod_nif_mtp2_dlsap_bind(int id) -{ - Pst pst; - NwMgmt cntrl; - sng_nif_cfg_t* nif = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[id]; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(NwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTNW; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTNW; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STNWDLSAP; /* General */ - cntrl.hdr.transId = 1; /* transaction identifier */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = ABND; - cntrl.t.cntrl.suId = nif->id; /* NIF DL sap Id */ - cntrl.t.cntrl.entity = ENTSD; /* MTP2 */ - - return (sng_cntrl_nif (&pst, &cntrl)); - -} - -/***********************************************************************************************************************/ -static int ftmod_sctp_debug(int action) -{ - Pst pst; - SbMgmt cntrl; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(SbMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTSB; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTSB; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STSBGEN; /* General */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = action; - cntrl.t.cntrl.subAction = SADBG; - cntrl.t.cntrl.dbgMask = 0xFFFF; - - return (sng_cntrl_sctp (&pst, &cntrl)); -} -/***********************************************************************************************************************/ - -static int ftmod_m2ua_debug(int action) -{ - Pst pst; - MwMgmt cntrl; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(MwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTMW; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STMWGEN; /* General */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = action; - cntrl.t.cntrl.subAction = SADBG; - cntrl.t.cntrl.s.dbgMask = 0xFFFF; - - return (sng_cntrl_m2ua (&pst, &cntrl)); -} -/***********************************************************************************************************************/ -static int ftmod_tucl_debug(int action) -{ - Pst pst; - HiMngmt cntrl; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&cntrl, 0, sizeof(HiMngmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTHI; - - /* prepare header */ - cntrl.hdr.msgType = TCNTRL; /* message type */ - cntrl.hdr.entId.ent = ENTHI; /* entity */ - cntrl.hdr.entId.inst = 0; /* instance */ - cntrl.hdr.elmId.elmnt = STGEN; /* General */ - - cntrl.hdr.response.selector = 0; - cntrl.hdr.response.prior = PRIOR0; - cntrl.hdr.response.route = RTESPEC; - cntrl.hdr.response.mem.region = S_REG; - cntrl.hdr.response.mem.pool = S_POOL; - - cntrl.t.cntrl.action = action; - cntrl.t.cntrl.subAction = SADBG; - cntrl.t.cntrl.ctlType.hiDbg.dbgMask = 0xFFFF; - - return (sng_cntrl_tucl (&pst, &cntrl)); -} -/***********************************************************************************************************************/ - -/***********************************************************************************************************************/ -int ftmod_sctp_ssta_req(int elemt, int id, SbMgmt* cfm) -{ - SbMgmt ssta; - Pst pst; - sng_sctp_link_t *k = &g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[id]; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&ssta, 0, sizeof(SbMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTSB; - - /* prepare header */ - ssta.hdr.msgType = TSSTA; /* message type */ - ssta.hdr.entId.ent = ENTSB; /* entity */ - ssta.hdr.entId.inst = 0; /* instance */ - ssta.hdr.elmId.elmnt = elemt; /* STSBGEN */ /* Others are STSBTSAP, STSBSCTSAP, STSBASSOC, STSBDTA, STSBTMR */ - ssta.hdr.transId = 1; /* transaction identifier */ - - ssta.hdr.response.selector = 0; - ssta.hdr.response.prior = PRIOR0; - ssta.hdr.response.route = RTESPEC; - ssta.hdr.response.mem.region = S_REG; - ssta.hdr.response.mem.pool = S_POOL; - - if((ssta.hdr.elmId.elmnt == STSBSCTSAP) || (ssta.hdr.elmId.elmnt == STSBTSAP)) - { - ssta.t.ssta.sapId = k->id; /* SapId */ - } - if(ssta.hdr.elmId.elmnt == STSBASSOC) - { - /*TODO - how to get assoc Id*/ - ssta.t.ssta.s.assocSta.assocId = 0; /* association id */ - } - return(sng_sta_sctp(&pst,&ssta,cfm)); -} - -int ftmod_m2ua_ssta_req(int elemt, int id, MwMgmt* cfm) -{ - MwMgmt ssta; - Pst pst; - sng_m2ua_cfg_t* m2ua = NULL; - sng_m2ua_cluster_cfg_t* clust = NULL; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&ssta, 0, sizeof(MwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTMW; - - /* prepare header */ - ssta.hdr.msgType = TSSTA; /* message type */ - ssta.hdr.entId.ent = ENTMW; /* entity */ - ssta.hdr.entId.inst = 0; /* instance */ - ssta.hdr.elmId.elmnt = elemt; /*STMWGEN */ /* Others are STMWSCTSAP, STMWCLUSTER, STMWPEER,STMWSID, STMWDLSAP */ - ssta.hdr.transId = 1; /* transaction identifier */ - - ssta.hdr.response.selector = 0; - ssta.hdr.response.prior = PRIOR0; - ssta.hdr.response.route = RTESPEC; - ssta.hdr.response.mem.region = S_REG; - ssta.hdr.response.mem.pool = S_POOL; - - switch(ssta.hdr.elmId.elmnt) - { - case STMWSCTSAP: - { - m2ua = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[id]; - clust = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[m2ua->clusterId]; - ssta.t.ssta.id.suId = clust->sct_sap_id ; /* lower sap Id */ - break; - } - case STMWDLSAP: - { - ssta.t.ssta.id.lnkNmb = id ; /* upper sap Id */ - break; - } - case STMWPEER: - { - ssta.t.ssta.id.peerId = id ; /* peer Id */ - break; - } - case STMWCLUSTER: - { - clust = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[id]; - ssta.t.ssta.id.clusterId = clust->id ; /* cluster Id */ - break; - } - default: - break; - } - - return(sng_sta_m2ua(&pst,&ssta,cfm)); -} - -int ftmod_nif_ssta_req(int elemt, int id, NwMgmt* cfm) -{ - NwMgmt ssta; - Pst pst; - sng_nif_cfg_t* nif = &g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[id]; - - memset((U8 *)&pst, 0, sizeof(Pst)); - memset((U8 *)&ssta, 0, sizeof(NwMgmt)); - - smPstInit(&pst); - - pst.dstEnt = ENTNW; - - /* prepare header */ - ssta.hdr.msgType = TSSTA; /* message type */ - ssta.hdr.entId.ent = ENTNW; /* entity */ - ssta.hdr.entId.inst = 0; /* instance */ - ssta.hdr.elmId.elmnt = elemt; - - ssta.hdr.response.selector = 0; - ssta.hdr.response.prior = PRIOR0; - ssta.hdr.response.route = RTESPEC; - ssta.hdr.response.mem.region = S_REG; - ssta.hdr.response.mem.pool = S_POOL; - ssta.t.ssta.suId = nif->id; /* Lower sapId */ - - return(sng_sta_nif(&pst,&ssta,cfm)); -} diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.h deleted file mode 100644 index 8bb564d284..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2012, Kapil Gupta - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributors: - * - */ -/******************************************************************************/ -#ifndef __FTMOD_SNG_SS7_M2UA_H__ -#define __FTMOD_SNG_SS7_M2UA_H__ -/******************************************************************************/ -#include "private/ftdm_core.h" - -#define MAX_NAME_LEN 25 - -typedef struct sng_nif_cfg{ - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; - uint32_t m2uaLnkNmb; - uint32_t mtp2LnkNmb; -}sng_nif_cfg_t; - -typedef enum{ - SNG_M2UA_NODE_TYPE_SGP = 1, /* type SG */ - SNG_M2UA_NODE_TYPE_ASP = 2, /* type ASP */ -}sng_m2ua_node_types_e; - -typedef struct sng_m2ua_cfg{ - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; /* ID */ - uint32_t iid; /* ID */ - uint8_t nodeType; /*Node Type SG/ASP */ - uint8_t end_point_opened; /* flag to check is end-point already opened */ - uint16_t clusterId; /* idx to m2ua_cluster profile */ -}sng_m2ua_cfg_t; - -typedef struct sng_m2ua_peer_cfg{ - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; /* ID */ - uint8_t aspIdFlag; /* Flag used to indicate whether include the ASP ID in the ASP UP message */ - uint16_t selfAspId; /* Self ASP ID. ASP identifier for this ASP node if the aspIdFlag is TRUE. */ - uint32_t numDestAddr; /* Number of destination address defined */ - uint16_t sctpId; /* idx to sctp profile */ - uint16_t port; - uint32_t destAddrList[SCT_MAX_NET_ADDRS+1]; /* Destination adddress list */ - uint16_t locOutStrms; /*Number of outgoing streams supported by this association*/ - int init_sctp_assoc; /* flag to tell if we need to initiate SCTP association */ -}sng_m2ua_peer_cfg_t; - -typedef enum{ - SNG_M2UA_LOAD_SHARE_ALGO_RR = 0x1, /* Round Robin Mode*/ - SNG_M2UA_LOAD_SHARE_ALGO_LS = 0x2, /* Link Specified */ - SNG_M2UA_LOAD_SHARE_ALGO_CS = 0x3, /* Customer Specified */ -}sng_m2ua_load_share_algo_types_e; - - -/* Possible values of Traffic mode */ -typedef enum{ - SNG_M2UA_TRF_MODE_OVERRIDE = 0x1, /* Override Mode */ - SNG_M2UA_TRF_MODE_LOADSHARE = 0x2, /* Loadshare Mode */ - SNG_M2UA_TRF_MODE_BROADCAST = 0x3, /* Broadcast Mode */ - SNG_M2UA_TRF_MODE_ANY = 0x0, /* ANY Mode */ -}sng_m2ua_traffic_mode_types_e; - -typedef struct sng_m2ua_cluster_cfg{ - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; /* ID */ - uint32_t sct_sap_id; /* Internal - sct_sap_id */ - uint8_t trfMode; /* Traffic mode. This parameter defines the mode in which this m2ua cluster is supposed to work */ - uint8_t loadShareAlgo; /* This parameter defines the M2UA load share algorithm which is used to distribute the traffic */ - uint16_t numOfPeers; /* idx to m2ua_peer profile */ - uint16_t peerIdLst[MW_MAX_NUM_OF_PEER]; /* idx to m2ua_peer profile */ -}sng_m2ua_cluster_cfg_t; - -typedef struct sng_m2ua_gbl_cfg{ - sng_nif_cfg_t nif[MW_MAX_NUM_OF_INTF+1]; - sng_m2ua_cfg_t m2ua[MW_MAX_NUM_OF_INTF+1]; - sng_m2ua_peer_cfg_t m2ua_peer[MW_MAX_NUM_OF_PEER+1]; - sng_m2ua_cluster_cfg_t m2ua_clus[MW_MAX_NUM_OF_CLUSTER+1]; -}sng_m2ua_gbl_cfg_t; - -/* m2ua xml parsing APIs */ -int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces); -int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces); -int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces); -int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_clust_interfaces); -int ftmod_ss7_parse_sctp_links(ftdm_conf_node_t *node); -uint32_t iptoul(const char *ip); - -int ftmod_ss7_m2ua_start(void); -void ftmod_ss7_m2ua_free(void); - -ftdm_status_t ftmod_ss7_m2ua_cfg(void); -ftdm_status_t ftmod_ss7_m2ua_init(void); - -int ftmod_sctp_ssta_req(int elemt, int id, SbMgmt* cfm); -int ftmod_m2ua_ssta_req(int elemt, int id, MwMgmt* cfm); -int ftmod_nif_ssta_req(int elemt, int id, NwMgmt* cfm); -void ftmod_ss7_enable_m2ua_sg_logging(void); -void ftmod_ss7_disable_m2ua_sg_logging(void); - - -#endif /*__FTMOD_SNG_SS7_M2UA_H__*/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c deleted file mode 100644 index bb011c364e..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Copyright (c) 2012, Kapil Gupta - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributors: - * - * - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface); -static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface); -static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface); -static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_clust_interface); -static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface); -static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface); -static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_face); -static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_face); - -static int ftmod_ss7_parse_sctp_link(ftdm_conf_node_t *node); - -/******************************************************************************/ -int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces) -{ - ftdm_conf_node_t *nif_interface = NULL; - - /* confirm that we are looking at sng_nif_interfaces */ - if (strcasecmp(nif_interfaces->name, "sng_nif_interfaces")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_nif_interfaces\"!\n",nif_interfaces->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"nif_interfaces\"...\n"); - } - - /* extract the isup_interfaces */ - nif_interface = nif_interfaces->child; - - while (nif_interface != NULL) { - /* parse the found mtp_route */ - if (ftmod_ss7_parse_nif_interface(nif_interface)) { - SS7_ERROR("Failed to parse \"nif_interface\"\n"); - return FTDM_FAIL; - } - - /* go to the next nif_interface */ - nif_interface = nif_interface->next; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface) -{ - sng_nif_cfg_t sng_nif; - ftdm_conf_parameter_t *parm = nif_interface->parameters; - int num_parms = nif_interface->n_parameters; - int i; - - /* initalize the nif intf and isap structure */ - memset(&sng_nif, 0x0, sizeof(sng_nif)); - - if(!nif_interface){ - SS7_ERROR("ftmod_ss7_parse_nif_interface: Null XML Node pointer \n"); - return FTDM_FAIL; - } - - /* confirm that we are looking at an nif_interface */ - if (strcasecmp(nif_interface->name, "sng_nif_interface")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"nif_interface\"!\n",nif_interface->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"nif_interface\"...\n"); - } - - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - /* try to match the parameter to what we expect */ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)sng_nif.name, parm->val); - SS7_DEBUG("Found an nif_interface named = %s\n", sng_nif.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - sng_nif.id = atoi(parm->val); - SS7_DEBUG("Found an nif id = %d\n", sng_nif.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "m2ua-interface-id")) { - /**********************************************************************/ - sng_nif.m2uaLnkNmb = atoi(parm->val); - SS7_DEBUG("Found an nif m2ua-interface-id = %d\n", sng_nif.m2uaLnkNmb); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2-interface-id")) { - /**********************************************************************/ - sng_nif.mtp2LnkNmb=atoi(parm->val); - - SS7_DEBUG("Found an nif mtp2-interface-id = %d\n", sng_nif.mtp2LnkNmb); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter %s!\n", parm->var); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parameter */ - parm = parm + 1; - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* fill in the nif interface */ - ftmod_ss7_fill_in_nif_interface(&sng_nif); - - return FTDM_SUCCESS; -} -/******************************************************************************/ -static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface) -{ - int i = nif_iface->id; - - strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].name, (char *)nif_iface->name, MAX_NAME_LEN-1); - - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].id = nif_iface->id; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].m2uaLnkNmb = nif_iface->m2uaLnkNmb; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].mtp2LnkNmb = nif_iface->mtp2LnkNmb; - - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_NIF_PRESENT); - - return 0; -} - -/******************************************************************************/ -int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces) -{ - ftdm_conf_node_t *m2ua_interface = NULL; - - /* confirm that we are looking at sng_m2ua_interfaces */ - if (strcasecmp(m2ua_interfaces->name, "sng_m2ua_interfaces")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_nif_interfaces\"!\n",m2ua_interfaces->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"m2ua_interfaces\"...\n"); - } - - /* extract the isup_interfaces */ - m2ua_interface = m2ua_interfaces->child; - - while (m2ua_interface != NULL) { - /* parse the found mtp_route */ - if (ftmod_ss7_parse_m2ua_interface(m2ua_interface)) { - SS7_ERROR("Failed to parse \"m2ua_interface\"\n"); - return FTDM_FAIL; - } - - /* go to the next m2ua_interface */ - m2ua_interface = m2ua_interface->next; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface) -{ - sng_m2ua_cfg_t sng_m2ua; - ftdm_conf_parameter_t *parm = m2ua_interface->parameters; - int num_parms = m2ua_interface->n_parameters; - int i; - - /* initalize the m2ua intf */ - memset(&sng_m2ua, 0x0, sizeof(sng_m2ua)); - - if(!m2ua_interface){ - SS7_ERROR("ftmod_ss7_parse_m2ua_interface: Null XML Node pointer \n"); - return FTDM_FAIL; - } - - /* confirm that we are looking at an nif_interface */ - if (strcasecmp(m2ua_interface->name, "sng_m2ua_interface")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_interface\"!\n",m2ua_interface->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"m2ua_interface\"...\n"); - } - - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - /* try to match the parameter to what we expect */ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)sng_m2ua.name, parm->val); - SS7_DEBUG("Found an m2ua_interface named = %s\n", sng_m2ua.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - sng_m2ua.id = atoi(parm->val); - SS7_DEBUG("Found an m2ua id = %d\n", sng_m2ua.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "m2ua-cluster-interface-id")) { - /**********************************************************************/ - sng_m2ua.clusterId=atoi(parm->val); - - SS7_DEBUG("Found an m2ua cluster_id = %d\n", sng_m2ua.clusterId); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "interface-identifier")) { - /**********************************************************************/ - sng_m2ua.iid=atoi(parm->val); - - SS7_DEBUG("Found an m2ua interface-identifier = %d\n", sng_m2ua.iid); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter %s!\n", parm->var); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parameter */ - parm = parm + 1; - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - sng_m2ua.nodeType = SNG_M2UA_NODE_TYPE_SGP; - - /* fill in the nif interface */ - ftmod_ss7_fill_in_m2ua_interface(&sng_m2ua); - - return FTDM_SUCCESS; -} -/******************************************************************************/ -static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface) -{ - int i = m2ua_iface->id; - - strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].name, (char *)m2ua_iface->name, MAX_NAME_LEN-1); - - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].id = m2ua_iface->id; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].nodeType = m2ua_iface->nodeType; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].clusterId = m2ua_iface->clusterId; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].iid = m2ua_iface->iid; - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_M2UA_PRESENT); - - return 0; -} - -/******************************************************************************/ -int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces) -{ - ftdm_conf_node_t *m2ua_peer_interface = NULL; - - /* confirm that we are looking at m2ua_peer_interfaces */ - if (strcasecmp(m2ua_peer_interfaces->name, "sng_m2ua_peer_interfaces")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interfaces\"!\n",m2ua_peer_interfaces->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"m2ua_peer_interfaces\"...\n"); - } - - /* extract the m2ua_peer_interfaces */ - m2ua_peer_interface = m2ua_peer_interfaces->child; - - while (m2ua_peer_interface != NULL) { - /* parse the found mtp_route */ - if (ftmod_ss7_parse_m2ua_peer_interface(m2ua_peer_interface)) { - SS7_ERROR("Failed to parse \"m2ua_peer_interface\"\n"); - return FTDM_FAIL; - } - - /* go to the next m2ua_peer_interface */ - m2ua_peer_interface = m2ua_peer_interface->next; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface) -{ - sng_m2ua_peer_cfg_t sng_m2ua_peer; - ftdm_conf_parameter_t *parm = m2ua_peer_interface->parameters; - int num_parms = m2ua_peer_interface->n_parameters; - int i; - - /* initalize the m2ua intf */ - memset(&sng_m2ua_peer, 0x0, sizeof(sng_m2ua_peer)); - - if(!m2ua_peer_interface){ - SS7_ERROR("ftmod_ss7_parse_m2ua_peer_interface: Null XML Node pointer \n"); - return FTDM_FAIL; - } - - /* confirm that we are looking at an m2ua_peer_interface */ - if (strcasecmp(m2ua_peer_interface->name, "sng_m2ua_peer_interface")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interface\"!\n",m2ua_peer_interface->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"m2ua_peer_interface\"...\n"); - } - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - /* try to match the parameter to what we expect */ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)sng_m2ua_peer.name, parm->val); - SS7_DEBUG("Found an sng_m2ua_peer named = %s\n", sng_m2ua_peer.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - sng_m2ua_peer.id = atoi(parm->val); - SS7_DEBUG("Found an sng_m2ua_peer id = %d\n", sng_m2ua_peer.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "include-asp-identifier")) { - /**********************************************************************/ - if(!strcasecmp(parm->val, "TRUE")){ - sng_m2ua_peer.aspIdFlag = 0x01; - } else if(!strcasecmp(parm->val, "FALSE")){ - sng_m2ua_peer.aspIdFlag = 0x00; - } else { - SS7_ERROR("Found an invalid aspIdFlag Parameter Value[%s]\n", parm->val); - return FTDM_FAIL; - } - SS7_DEBUG("Found an sng_m2ua_peer aspIdFlag = %d\n", sng_m2ua_peer.aspIdFlag); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "asp-identifier")) { - /**********************************************************************/ - sng_m2ua_peer.selfAspId=atoi(parm->val); - - SS7_DEBUG("Found an sng_m2ua_peer self_asp_id = %d\n", sng_m2ua_peer.selfAspId); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "sctp-interface-id")) { - /**********************************************************************/ - sng_m2ua_peer.sctpId = atoi(parm->val); - - SS7_DEBUG("Found an sng_m2ua_peer sctp_id = %d\n", sng_m2ua_peer.sctpId); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "destination-port")) { - /**********************************************************************/ - sng_m2ua_peer.port = atoi(parm->val); - - SS7_DEBUG("Found an sng_m2ua_peer port = %d\n", sng_m2ua_peer.port); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "address")) { - /**********************************************************************/ - if (sng_m2ua_peer.numDestAddr < SCT_MAX_NET_ADDRS) { - sng_m2ua_peer.destAddrList[sng_m2ua_peer.numDestAddr] = iptoul (parm->val); - sng_m2ua_peer.numDestAddr++; - SS7_DEBUG("sng_m2ua_peer - Parsing with dest IP Address = %s \n", parm->val); - } else { - SS7_ERROR("sng_m2ua_peer - too many dest address configured. dropping %s \n", parm->val); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "number-of-outgoing-streams")) { - /**********************************************************************/ - sng_m2ua_peer.locOutStrms=atoi(parm->val); - - SS7_DEBUG("Found an sng_m2ua_peer number-of-outgoing-streams = %d\n", sng_m2ua_peer.locOutStrms); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "init-sctp-association")) { - /**********************************************************************/ - if(!strcasecmp(parm->val, "TRUE")){ - sng_m2ua_peer.init_sctp_assoc = 0x01; - } else if(!strcasecmp(parm->val, "FALSE")){ - sng_m2ua_peer.init_sctp_assoc = 0x00; - } else { - SS7_ERROR("Found an invalid init_sctp_assoc Parameter Value[%s]\n", parm->val); - return FTDM_FAIL; - } - - SS7_DEBUG("Found an sng_m2ua_peer init_sctp_assoc = %d\n", sng_m2ua_peer.init_sctp_assoc); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter %s!\n", parm->var); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parameter */ - parm = parm + 1; - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* fill in the sng_m2ua_peer interface */ - ftmod_ss7_fill_in_m2ua_peer_interface(&sng_m2ua_peer); - - return FTDM_SUCCESS; -} -/******************************************************************************/ -static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_iface) -{ - int k = 0x00; - int i = m2ua_peer_iface->id; - - strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].name, (char *)m2ua_peer_iface->name, MAX_NAME_LEN-1); - - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].id = m2ua_peer_iface->id; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].aspIdFlag = m2ua_peer_iface->aspIdFlag; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].selfAspId = m2ua_peer_iface->selfAspId; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].locOutStrms = m2ua_peer_iface->locOutStrms; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].numDestAddr = m2ua_peer_iface->numDestAddr; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].sctpId = m2ua_peer_iface->sctpId; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].port = m2ua_peer_iface->port; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].init_sctp_assoc = m2ua_peer_iface->init_sctp_assoc; - for (k=0; knumDestAddr; k++) { - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].destAddrList[k] = m2ua_peer_iface->destAddrList[k]; - } - - - return 0; -} - -/******************************************************************************/ -int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_cluster_interfaces) -{ - ftdm_conf_node_t *m2ua_cluster_interface = NULL; - - /* confirm that we are looking at m2ua_cluster_interfaces */ - if (strcasecmp(m2ua_cluster_interfaces->name, "sng_m2ua_cluster_interfaces")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interfaces\"!\n",m2ua_cluster_interfaces->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"m2ua_cluster_interfaces\"...\n"); - } - - /* extract the m2ua_cluster_interfaces */ - m2ua_cluster_interface = m2ua_cluster_interfaces->child; - - while (m2ua_cluster_interface != NULL) { - /* parse the found m2ua_cluster_interface */ - if (ftmod_ss7_parse_m2ua_clust_interface(m2ua_cluster_interface)) { - SS7_ERROR("Failed to parse \"m2ua_cluster_interface\"\n"); - return FTDM_FAIL; - } - - /* go to the next m2ua_cluster_interface */ - m2ua_cluster_interface = m2ua_cluster_interface->next; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_cluster_interface) -{ - sng_m2ua_cluster_cfg_t sng_m2ua_cluster; - ftdm_conf_parameter_t *parm = m2ua_cluster_interface->parameters; - int num_parms = m2ua_cluster_interface->n_parameters; - int i; - - /* initalize the m2ua_cluster_interface */ - memset(&sng_m2ua_cluster, 0x0, sizeof(sng_m2ua_cluster)); - - if (!m2ua_cluster_interface){ - SS7_ERROR("ftmod_ss7_parse_m2ua_clust_interface - NULL XML Node pointer \n"); - return FTDM_FAIL; - } - - /* confirm that we are looking at an m2ua_cluster_interface */ - if (strcasecmp(m2ua_cluster_interface->name, "sng_m2ua_cluster_interface")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interface\"!\n",m2ua_cluster_interface->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"m2ua_cluster_interface\"...\n"); - } - - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - /* try to match the parameter to what we expect */ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)sng_m2ua_cluster.name, parm->val); - SS7_DEBUG("Found an sng_m2ua_cluster named = %s\n", sng_m2ua_cluster.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - sng_m2ua_cluster.id = atoi(parm->val); - SS7_DEBUG("Found an sng_m2ua_cluster id = %d\n", sng_m2ua_cluster.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "traffic-mode")) { - /**********************************************************************/ - if(!strcasecmp(parm->val, "loadshare")){ - sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_LOADSHARE; - } else if(!strcasecmp(parm->val, "override")){ - sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_OVERRIDE; - } else if(!strcasecmp(parm->val, "broadcast")){ - sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_BROADCAST; - } else { - SS7_ERROR("Found an invalid trfMode Parameter Value[%s]..adding default one[ANY]\n", parm->val); - sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_ANY; - } - SS7_DEBUG("Found an sng_m2ua_cluster.trfMode = %d\n", sng_m2ua_cluster.trfMode); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "load-share-algorithm")) { - /**********************************************************************/ - if(!strcasecmp(parm->val, "roundrobin")){ - sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_RR; - } else if(!strcasecmp(parm->val, "linkspecified")){ - sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_LS; - } else if(!strcasecmp(parm->val, "customerspecified")){ - sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_CS; - } else { - SS7_ERROR("Found an invalid loadShareAlgo Parameter Value[%s]\n", parm->val); - return FTDM_FAIL; - } - - SS7_DEBUG("Found an sng_m2ua_cluster.loadShareAlgo = %d\n", sng_m2ua_cluster.loadShareAlgo); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "m2ua-peer-interface-id")) { - /**********************************************************************/ - if(sng_m2ua_cluster.numOfPeers < MW_MAX_NUM_OF_PEER) { - sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers] = atoi(parm->val); - SS7_DEBUG("Found an sng_m2ua_cluster peerId[%d], Total numOfPeers[%d] \n", - sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers], - sng_m2ua_cluster.numOfPeers+1); - sng_m2ua_cluster.numOfPeers++; - }else{ - SS7_ERROR("Peer List excedding max[%d] limit \n", MW_MAX_NUM_OF_PEER); - return FTDM_FAIL; - } - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter %s!\n", parm->var); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parameter */ - parm = parm + 1; - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* fill in the sng_m2ua_peer interface */ - ftmod_ss7_fill_in_m2ua_clust_interface(&sng_m2ua_cluster); - - return FTDM_SUCCESS; -} -/******************************************************************************/ -static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_iface) -{ - int k = 0x00; - int i = m2ua_cluster_iface->id; - - strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].name, (char *)m2ua_cluster_iface->name, MAX_NAME_LEN-1); - - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].id = m2ua_cluster_iface->id; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].trfMode = m2ua_cluster_iface->trfMode; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].loadShareAlgo = m2ua_cluster_iface->loadShareAlgo; - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].numOfPeers = m2ua_cluster_iface->numOfPeers; - for(k=0;knumOfPeers;k++){ - g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].peerIdLst[k] = m2ua_cluster_iface->peerIdLst[k]; - } - - return 0; -} - -/******************************************************************************/ -int ftmod_ss7_parse_sctp_links(ftdm_conf_node_t *node) -{ - ftdm_conf_node_t *node_sctp_link = NULL; - - if (!node) - return FTDM_FAIL; - - if (strcasecmp(node->name, "sng_sctp_interfaces")) { - SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at !\n", node->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("SCTP - Parsing configurations\n"); - } - - for (node_sctp_link = node->child; node_sctp_link != NULL; node_sctp_link = node_sctp_link->next) { - if (ftmod_ss7_parse_sctp_link(node_sctp_link) != FTDM_SUCCESS) { - SS7_ERROR("SCTP - Failed to parse . \n"); - return FTDM_FAIL; - } - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_sctp_link(ftdm_conf_node_t *node) -{ - ftdm_conf_parameter_t *param = NULL; - int num_params = 0; - int i=0; - - if (!node){ - SS7_ERROR("SCTP - NULL XML Node pointer \n"); - return FTDM_FAIL; - } - - param = node->parameters; - num_params = node->n_parameters; - - sng_sctp_link_t t_link; - memset (&t_link, 0, sizeof(sng_sctp_link_t)); - - if (strcasecmp(node->name, "sng_sctp_interface")) { - SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at !\n", node->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("SCTP - Parsing configurations\n"); - } - - for (i=0; ivar, "name")) { - int n_strlen = strlen(param->val); - strncpy((char*)t_link.name, param->val, (n_strlen>MAX_NAME_LEN)?MAX_NAME_LEN:n_strlen); - SS7_DEBUG("SCTP - Parsing with name = %s\n", param->val); - } - else if (!strcasecmp(param->var, "id")) { - t_link.id = atoi(param->val); - SS7_DEBUG("SCTP - Parsing with id = %s\n", param->val); - } - else if (!strcasecmp(param->var, "address")) { - if (t_link.numSrcAddr < SCT_MAX_NET_ADDRS) { - t_link.srcAddrList[t_link.numSrcAddr+1] = iptoul (param->val); - t_link.numSrcAddr++; - SS7_DEBUG("SCTP - Parsing with source IP Address = %s\n", param->val); - } else { - SS7_ERROR("SCTP - too many source address configured. dropping %s \n", param->val); - } - } else if (!strcasecmp(param->var, "source-port")) { - t_link.port = atoi(param->val); - SS7_DEBUG("SCTP - Parsing with port = %s\n", param->val); - } - else { - SS7_ERROR("SCTP - Found an unknown parameter <%s>. Skipping it.\n", param->var); - } - } - - g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].id = t_link.id; - g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].port = t_link.port; - strncpy((char*)g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].name, t_link.name, strlen(t_link.name) ); - g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].numSrcAddr = t_link.numSrcAddr; - for (i=1; i<=t_link.numSrcAddr; i++) { - g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].srcAddrList[i] = t_link.srcAddrList[i]; - } - - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SCTP_PRESENT); - - return FTDM_SUCCESS; -} -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c deleted file mode 100644 index 47c88c29c5..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ /dev/null @@ -1,2766 +0,0 @@ -/* - * Copyright (c) 2009, Sangoma Technologies - * Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * David Yat Sin - * James Zhang - * - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -static sng_isup_event_interface_t sng_event; -static ftdm_io_interface_t g_ftdm_sngss7_interface; -ftdm_sngss7_data_t g_ftdm_sngss7_data; -ftdm_sngss7_opr_mode g_ftdm_operating_mode; - -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj); -static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event); -static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, sngss7_event_data_t *sngss7_event); - -static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span); -static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span); -/******************************************************************************/ - - -/* STATE MAP ******************************************************************/ -ftdm_state_map_t sangoma_ss7_state_map = { - { - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_DOWN, - FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_COLLECT, - FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, - FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, - FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN, - FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING, - FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, - FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_INBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - /**************************************************************************/ - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_DOWN, - FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_DIALING, - FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, - FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_CANCEL, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, - FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IDLE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_PROGRESS_MEDIA ,FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END} - }, - { - ZSD_OUTBOUND, - ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_END}, - {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_END} - }, - } -}; - -static void handle_hw_alarm(ftdm_event_t *e) -{ - sngss7_chan_data_t *ss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - int x = 0; - - ftdm_assert(e != NULL, "Null event!\n"); - - SS7_DEBUG("handle_hw_alarm event [%d/%d]\n",e->channel->physical_span_id,e->channel->physical_chan_id); - - for (x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1; g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0; x++) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - - /* NC. Its possible for alarms to come in the middle of configuration - especially on large systems */ - if (!ss7_info || !ss7_info->ftdmchan) { - SS7_DEBUG("handle_hw_alarm: span=%i chan=%i ckt=%i x=%i - ss7_info=%p ftdmchan=%p\n", - ftdmchan->physical_span_id,ftdmchan->physical_chan_id, - g_ftdm_sngss7_data.cfg.isupCkt[x].id,x, - ss7_info,ss7_info?ss7_info->ftdmchan:NULL); - continue; - } - - ftdmchan = ss7_info->ftdmchan; - - if (e->channel->physical_span_id == ftdmchan->physical_span_id && - e->channel->physical_chan_id == ftdmchan->physical_chan_id) { - SS7_DEBUG_CHAN(ftdmchan,"handle_hw_alarm: span=%i chan=%i ckt=%i x=%i\n", - ftdmchan->physical_span_id,ftdmchan->physical_chan_id,g_ftdm_sngss7_data.cfg.isupCkt[x].id,x); - if (e->enum_id == FTDM_OOB_ALARM_TRAP) { - SS7_DEBUG_CHAN(ftdmchan,"handle_hw_alarm: Set FLAG_GRP_HW_BLOCK_TX %s\n", " "); - sngss7_set_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX); - if (ftdmchan->state != FTDM_CHANNEL_STATE_SUSPENDED) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - } else if (e->enum_id == FTDM_OOB_ALARM_CLEAR) { - SS7_DEBUG_CHAN(ftdmchan,"handle_hw_alarm: Clear %s \n", " "); - sngss7_clear_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX); - sngss7_clear_ckt_blk_flag(ss7_info, FLAG_GRP_HW_UNBLK_TX); - if (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX_DN)) { - sngss7_set_ckt_blk_flag(ss7_info, FLAG_GRP_HW_UNBLK_TX); - SS7_DEBUG_CHAN(ftdmchan,"handle_hw_alarm: Setting FLAG_GRP_HW_UNBLK_TX %s\n"," "); - if (ftdmchan->state != FTDM_CHANNEL_STATE_SUSPENDED) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - } - } - } - } - } -} - - -static void check_span_oob_events(ftdm_span_t *ftdmspan) -{ - ftdm_event_t *event = NULL; - /* Poll for events, e.g HW DTMF */ - switch (ftdm_span_poll_event(ftdmspan, 0, NULL)) { - /**********************************************************************/ - case FTDM_SUCCESS: - while (ftdm_span_next_event(ftdmspan, &event) == FTDM_SUCCESS) { - if (event->e_type == FTDM_EVENT_OOB) { - handle_hw_alarm(event); - } - } - break; - /**********************************************************************/ - case FTDM_TIMEOUT: - /* No events pending */ - break; - /**********************************************************************/ - default: - SS7_ERROR("%s:Failed to poll span event\n", ftdmspan->name); - /**********************************************************************/ - } -} - -/* MONITIOR THREADS ***********************************************************/ -static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) -{ - ftdm_interrupt_t *ftdm_sangoma_ss7_int[2]; - ftdm_span_t *ftdmspan = (ftdm_span_t *) obj; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *sngss7_event = NULL; - sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data; - - int b_alarm_test = 1; - sngss7_chan_data_t *ss7_info=NULL; - - ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id); - - /* set IN_THREAD flag so that we know this thread is running */ - ftdm_set_flag (ftdmspan, FTDM_SPAN_IN_THREAD); - - - - /* get an interrupt queue for this span for channel state changes */ - if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int[0]) != FTDM_SUCCESS) { - SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for channel state changes!\n", ftdmspan->span_id); - goto ftdm_sangoma_ss7_run_exit; - } - - /* get an interrupt queue for this span for Trillium events */ - if (ftdm_queue_get_interrupt (sngss7_span->event_queue, &ftdm_sangoma_ss7_int[1]) != FTDM_SUCCESS) { - SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for Trillium event queue!\n", ftdmspan->span_id); - goto ftdm_sangoma_ss7_run_exit; - } - - if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){ - ftdm_log (FTDM_LOG_INFO, "FreeTDM running as M2UA_SG mode, freetdm dont have to do anything \n"); - - while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) { - - switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, ftdm_array_len(ftdm_sangoma_ss7_int), 100))) { - - case FTDM_SUCCESS: /* process all pending state changes */ - - SS7_DEVEL_DEBUG ("ftdm_interrupt_wait FTDM_SUCCESS on span = %d\n",ftdmspan->span_id); - - /**********************************************************************/ - case FTDM_TIMEOUT: - SS7_DEVEL_DEBUG ("ftdm_interrupt_wait timed-out on span = %d\n",ftdmspan->span_id); - - break; - /**********************************************************************/ - case FTDM_FAIL: - SS7_ERROR ("ftdm_interrupt_wait returned error!\non span = %d\n", ftdmspan->span_id); - - break; - /**********************************************************************/ - default: - SS7_ERROR("ftdm_interrupt_wait returned with unknown code on span = %d\n",ftdmspan->span_id); - - break; - /**********************************************************************/ - } - check_span_oob_events(ftdmspan); - - /* signal the core that sig events are queued for processing */ - ftdm_span_trigger_signals(ftdmspan); - } - goto ftdm_sangoma_ss7_stop; - } - - while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) { - int x = 0; - if (b_alarm_test) { - b_alarm_test = 0; - for (x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1; - g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0; x++) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; - if (!ftdmchan) { - continue; - } - - if (ftdmchan->alarm_flags != 0) { /* we'll send out block */ - sngss7_set_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX ); - } else { /* we'll send out reset */ - if (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX )) { - sngss7_clear_ckt_blk_flag( ss7_info, FLAG_GRP_HW_BLOCK_TX ); - sngss7_clear_ckt_blk_flag( ss7_info, FLAG_GRP_HW_BLOCK_TX_DN ); - sngss7_set_ckt_blk_flag (ss7_info, FLAG_GRP_HW_UNBLK_TX); - SS7_DEBUG("b_alarm_test FLAG_GRP_HW_UNBLK_TX\n"); - } - } - } - usleep(50); - } - ftdmchan = NULL; - } - - /* check the channel state queue for an event*/ - switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, ftdm_array_len(ftdm_sangoma_ss7_int), 100))) { - /**********************************************************************/ - case FTDM_SUCCESS: /* process all pending state changes */ - - /* clean out all pending channel state changes */ - while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) { - sngss7_chan_data_t *chan_info = ftdmchan->call_data; - - /*first lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* process state changes for this channel until they are all done */ - ftdm_channel_advance_states(ftdmchan); - - if (chan_info->peer_data) { - /* clean out all pending stack events in the peer channel */ - while ((sngss7_event = ftdm_queue_dequeue(chan_info->event_queue))) { - ftdm_sangoma_ss7_process_peer_stack_event(ftdmchan, sngss7_event); - ftdm_safe_free(sngss7_event); - } - } - - /* unlock the channel */ - ftdm_mutex_unlock (ftdmchan->mutex); - } - - /* clean out all pending stack events */ - while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) { - ftdm_sangoma_ss7_process_stack_event(sngss7_event); - ftdm_safe_free(sngss7_event); - } - - /* signal the core that sig events are queued for processing */ - ftdm_span_trigger_signals(ftdmspan); - - break; - /**********************************************************************/ - case FTDM_TIMEOUT: - SS7_DEVEL_DEBUG ("ftdm_interrupt_wait timed-out on span = %d\n",ftdmspan->span_id); - - break; - /**********************************************************************/ - case FTDM_FAIL: - SS7_ERROR ("ftdm_interrupt_wait returned error!\non span = %d\n", ftdmspan->span_id); - - break; - /**********************************************************************/ - default: - SS7_ERROR("ftdm_interrupt_wait returned with unknown code on span = %d\n",ftdmspan->span_id); - - break; - /**********************************************************************/ - } - - /* check if there is a GRA to proccess on the span */ - if (ftdm_test_flag(sngss7_span, SNGSS7_RX_GRA_PENDING)) { - check_if_rx_gra_started(ftdmspan); - } - - /* check if there is a GRS being processed on the span */ - if (ftdm_test_flag(sngss7_span, SNGSS7_RX_GRS_PENDING)) { - /* check if the rx_grs has started */ - check_if_rx_grs_started(ftdmspan); - - /* check if the rx_grs has cleared */ - check_if_rx_grs_processed(ftdmspan); - } - - /* check if there is a UCIC to be processed on the span */ - if (ftdm_test_flag(sngss7_span, SNGSS7_UCIC_PENDING)) { - /* process the span wide UCIC */ - process_span_ucic(ftdmspan); - } - - /* check each channel on the span to see if there is an un-procressed SUS/RES flag */ - check_for_res_sus_flag(ftdmspan); - - /* check each channel on the span to see if it needs to be reconfigured */ - check_for_reconfig_flag(ftdmspan); - - check_span_oob_events(ftdmspan); - } -ftdm_sangoma_ss7_stop: - - /* clear the IN_THREAD flag so that we know the thread is done */ - ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD); - - - ftdm_log (FTDM_LOG_INFO,"ftmod_sangoma_ss7 monitor thread for span=%u stopping.\n",ftdmspan->span_id); - - return NULL; - -ftdm_sangoma_ss7_run_exit: - - /* clear the IN_THREAD flag so that we know the thread is done */ - ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD); - - ftdm_log (FTDM_LOG_INFO,"ftmod_sangoma_ss7 monitor thread for span=%u stopping due to error.\n",ftdmspan->span_id); - - ftdm_sangoma_ss7_stop (ftdmspan); - - return NULL; -} - -/******************************************************************************/ -static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event) -{ - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_event_data_t *event_clone = NULL; - int clone_event = 0; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", sngss7_event->circuit); - return; - } - - /* now that we have the right channel ... put a lock on it so no-one else can use it */ - ftdm_channel_lock(ftdmchan); - - /* while there's a state change present on this channel process it */ - ftdm_channel_advance_states(ftdmchan); - - if (sngss7_event->event_id == SNGSS7_CON_IND_EVENT) { - clone_event++; - } - - /* If the call has already started (we only bridge events related to calls) - * and the event is not a release confirmation, then clone the event. - * We do not clone release cfm events because that is the only event (final event) that is not - * bridged to the other leg, the first Spirou customer we had explicitly requested to send - * release confirm as soon as the release is received and therefore not wait for the other leg - * to send release confirm (hence, not need to clone and enqueue in the other leg) */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED) && sngss7_event->event_id != SNGSS7_REL_CFM_EVENT) { - clone_event++; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { - - if (sngss7_event->event_id == SNGSS7_SUSP_IND_EVENT) { - sngss7_set_ckt_flag(sngss7_info, FLAG_SUS_RECVD); - sngss7_clear_ckt_flag(sngss7_info, FLAG_T6_CANCELED); - } - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) && - !sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) { - if (sng_cancel_isup_tmr(sngss7_info->suInstId, ISUP_T6i) == RFAILED ) { - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not stop timer T6 \n", sngss7_info->circuit->cic); - } else { - sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic); - } - } - } - - /* clone the event and save it for later usage, we do not clone RLC messages */ - if (clone_event) { - event_clone = ftdm_calloc(1, sizeof(*sngss7_event)); - if (event_clone) { - memcpy(event_clone, sngss7_event, sizeof(*sngss7_event)); - /* if we have already a peer channel then enqueue the event in their queue */ - if (sngss7_info->peer_data) { - ftdm_span_t *peer_span = sngss7_info->peer_data->ftdmchan->span; - if (sngss7_info->peer_event_transfer_cnt) { - sngss7_event_data_t *peer_event = NULL; - int qi = 0; - /* looks like for the first time we found our peer, transfer any messages we enqueued */ - for (qi = 0; qi < sngss7_info->peer_event_transfer_cnt; qi++) { - peer_event = ftdm_queue_dequeue(sngss7_info->event_queue); - if (peer_event) { - ftdm_queue_enqueue(sngss7_info->peer_data->event_queue, peer_event); - } else { - /* This should never happen! */ - SS7_CRIT_CHAN(ftdmchan,"[CIC:%d]What!? someone stole my messages!\n", sngss7_info->circuit->cic); - } - } - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Transferred %d messages into my peer's queue\n", - sngss7_info->circuit->cic, sngss7_info->peer_event_transfer_cnt); - sngss7_info->peer_event_transfer_cnt = 0; - } - /* we already have a peer attached, wake him up */ - ftdm_queue_enqueue(sngss7_info->peer_data->event_queue, event_clone); - ftdm_queue_enqueue(peer_span->pendingchans, sngss7_info->peer_data->ftdmchan); - } else { - /* we don't have a peer yet, save the event on our own queue for later - * only the first event in this queue is directly consumed by our peer (IAM), subsequent events - * must be transferred by us to their queue as soon as we find our peer */ - ftdm_queue_enqueue(sngss7_info->event_queue, event_clone); - if (sngss7_event->event_id != SNGSS7_CON_IND_EVENT) { - /* This could be an SAM, save it for transfer once we know who our peer is (if we ever find that) */ - sngss7_info->peer_event_transfer_cnt++; - } - } - } - } - - /* we could test for sngss7_info->peer_data too, bit this flag is set earlier, the earlier we know the better */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { - /* most messages are simply relayed in sig bridge mode, except for hangup which requires state changing */ - switch (sngss7_event->event_id) { - case SNGSS7_REL_IND_EVENT: - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - case SNGSS7_REL_CFM_EVENT: - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - default: - break; - } - goto done; - } - - /* figure out the type of event and send it to the right handler */ - switch (sngss7_event->event_id) { - /**************************************************************************/ - case (SNGSS7_CON_IND_EVENT): - handle_con_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siConEvnt); - break; - /**************************************************************************/ - case (SNGSS7_CON_CFM_EVENT): - handle_con_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siConEvnt); - break; - /**************************************************************************/ - case (SNGSS7_CON_STA_EVENT): - handle_con_sta(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siCnStEvnt, sngss7_event->evntType); - break; - /**************************************************************************/ - case (SNGSS7_REL_IND_EVENT): - handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); - break; - /**************************************************************************/ - case (SNGSS7_REL_CFM_EVENT): - handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); - break; - /**************************************************************************/ - case (SNGSS7_DAT_IND_EVENT): - handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt); - break; - /**************************************************************************/ - case (SNGSS7_FAC_IND_EVENT): - handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); - break; - /**************************************************************************/ - case (SNGSS7_FAC_CFM_EVENT): - handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); - break; - /**************************************************************************/ - case (SNGSS7_UMSG_IND_EVENT): - handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit); - break; - /**************************************************************************/ - case (SNGSS7_STA_IND_EVENT): - handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt); - break; - /**************************************************************************/ - case (SNGSS7_SUSP_IND_EVENT): - handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt); - break; - /**************************************************************************/ - case (SNGSS7_RESM_IND_EVENT): - handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt); - break; - /**************************************************************************/ - case (SNGSS7_SSP_STA_CFM_EVENT): - SS7_ERROR("dazed and confused ... hu?!\n"); - break; - /**************************************************************************/ - default: - SS7_ERROR("Unknown Event Id!\n"); - break; - /**************************************************************************/ - } - -done: - /* while there's a state change present on this channel process it */ - ftdm_channel_advance_states(ftdmchan); - - /* unlock the channel */ - ftdm_channel_unlock(ftdmchan); - -} - -FTDM_ENUM_NAMES(SNG_EVENT_TYPE_NAMES, SNG_EVENT_TYPE_STRINGS) -FTDM_STR2ENUM(ftdm_str2sngss7_event, ftdm_sngss7_event2str, sng_event_type_t, SNG_EVENT_TYPE_NAMES, SNGSS7_INVALID_EVENT) -static void ftdm_sangoma_ss7_process_peer_stack_event (ftdm_channel_t *ftdmchan, sngss7_event_data_t *sngss7_event) -{ - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - if (ftdmchan->state < FTDM_CHANNEL_STATE_UP && ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - ftdm_channel_advance_states(ftdmchan); - } - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Receiving message %s from bridged peer (our state = %s)\n", - sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id), ftdm_channel_state2str(ftdmchan->state)); - - switch (sngss7_event->event_id) { - - case (SNGSS7_CON_IND_EVENT): - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx IAM while bridged??\n", sngss7_info->circuit->cic); - break; - - case (SNGSS7_CON_CFM_EVENT): - /* send the ANM request to LibSngSS7 */ - sng_cc_con_response(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &sngss7_event->event.siConEvnt, - 5); - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Tx peer ANM\n", sngss7_info->circuit->cic); - break; - - case (SNGSS7_CON_STA_EVENT): - switch (sngss7_event->evntType) { - /**************************************************************************/ - case (ADDRCMPLT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ACM\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (MODIFY): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (MODCMPLT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY-COMPLETE\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (MODREJ): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MODIFY-REJECT\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (PROGRESS): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CPG\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (FRWDTRSFR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer FOT\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (INFORMATION): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer INF\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (INFORMATREQ): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer INR\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (SUBSADDR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer SAM\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (EXIT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer EXIT\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (NETRESMGT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer NRM\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (IDENTREQ): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer IDR\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (IDENTRSP): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer IRS\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (MALCLLPRNT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer MALICIOUS CALL\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CHARGE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (TRFFCHGE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG-TARIFF\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CHARGEACK): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CRG-ACK\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CALLOFFMSG): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALL-OFFER\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (LOOPPRVNT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer LOP\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (TECT_TIMEOUT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ECT-Timeout\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (RINGSEND): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer RINGING-SEND\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CALLCLEAR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALL-LINE Clear\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (PRERELEASE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer PRI\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (APPTRANSPORT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer APM\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (OPERATOR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer OPERATOR\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (METPULSE): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer METERING-PULSE\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (CLGPTCLR): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer CALLING_PARTY_CLEAR\n", sngss7_info->circuit->cic); - break; - /**************************************************************************/ - case (SUBDIRNUM): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer SUB-DIR\n", sngss7_info->circuit->cic); - break; -#ifdef SANGOMA_SPIROU - case (CHARGE_ACK): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer TXA\n", sngss7_info->circuit->cic); - break; - case (CHARGE_UNIT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer ITX\n", sngss7_info->circuit->cic); - break; -#endif - /**************************************************************************/ - default: - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer Unknown Msg %d\n", sngss7_info->circuit->cic, sngss7_event->evntType); - break; - /**************************************************************************/ - } - sng_cc_con_status (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &sngss7_event->event.siCnStEvnt, - sngss7_event->evntType); - - break; - /**************************************************************************/ - case (SNGSS7_REL_IND_EVENT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer REL cause=%d\n", sngss7_info->circuit->cic, sngss7_event->event.siRelEvnt.causeDgn.causeVal.val); - - //handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); - sng_cc_rel_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &sngss7_event->event.siRelEvnt); - break; - - /**************************************************************************/ - case (SNGSS7_REL_CFM_EVENT): - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer RLC\n", sngss7_info->circuit->cic); - sng_cc_rel_response (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &sngss7_event->event.siRelEvnt); - //handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); - break; - - /**************************************************************************/ - case (SNGSS7_DAT_IND_EVENT): - //handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); - sng_cc_dat_request(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &sngss7_event->event.siInfoEvnt); - break; - /**************************************************************************/ - case (SNGSS7_FAC_IND_EVENT): - //handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, - //&sngss7_event->event.siFacEvnt); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s -> %d\n", sngss7_info->circuit->cic, - ftdm_sngss7_event2str(sngss7_event->event_id), sngss7_event->evntType); - sng_cc_fac_request(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - sngss7_event->evntType, - &sngss7_event->event.siFacEvnt); - - break; - /**************************************************************************/ - case (SNGSS7_FAC_CFM_EVENT): - //handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, - //sngss7_event->evntType, &sngss7_event->event.siFacEvnt); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s -> %d\n", sngss7_info->circuit->cic, - ftdm_sngss7_event2str(sngss7_event->event_id), sngss7_event->evntType); - sng_cc_fac_response(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - sngss7_event->evntType, - &sngss7_event->event.siFacEvnt); - break; - /**************************************************************************/ - case (SNGSS7_UMSG_IND_EVENT): - //handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); - sng_cc_umsg_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id); - break; - /**************************************************************************/ - case (SNGSS7_STA_IND_EVENT): - //handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt); - break; - /**************************************************************************/ - case (SNGSS7_SUSP_IND_EVENT): - //handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); - sng_cc_susp_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &sngss7_event->event.siSuspEvnt); - break; - /**************************************************************************/ - case (SNGSS7_RESM_IND_EVENT): - //handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx peer %s\n", sngss7_info->circuit->cic, ftdm_sngss7_event2str(sngss7_event->event_id)); - sng_cc_resm_request(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &sngss7_event->event.siResmEvnt); - break; - /**************************************************************************/ - case (SNGSS7_SSP_STA_CFM_EVENT): - SS7_CRITICAL("dazed and confused ... hu?!\n"); - break; - /**************************************************************************/ - default: - SS7_ERROR("Failed to relay unknown event id %d!\n", sngss7_event->event_id); - break; - /**************************************************************************/ - } - - if ((sngss7_event->event_id == SNGSS7_SUSP_IND_EVENT)) { - sngss7_set_ckt_flag(sngss7_info, FLAG_SUS_RECVD); - } - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_SUS_RECVD) && - !sngss7_test_ckt_flag(sngss7_info, FLAG_T6_CANCELED)) { - if (sng_cancel_isup_tmr(sngss7_info->suInstId, ISUP_T6i) == RFAILED ) { - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]could not stop timer T6 \n", sngss7_info->circuit->cic); - } else { - sngss7_set_ckt_flag(sngss7_info, FLAG_T6_CANCELED); - SS7_ERROR_CHAN(ftdmchan,"[CIC:%d] isup timer T6 has been cancelled. \n", sngss7_info->circuit->cic); - } - } -} - -static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan); -static ftdm_status_t ftdm_sangoma_ss7_native_bridge_state_change(ftdm_channel_t *ftdmchan) -{ - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - ftdm_channel_complete_state(ftdmchan); - - switch (ftdmchan->state) { - - case FTDM_CHANNEL_STATE_DOWN: - { - ftdm_channel_t *close_chan = ftdmchan; - sngss7_clear_ckt_flag(sngss7_info, FLAG_SUS_RECVD); - sngss7_clear_ckt_flag(sngss7_info, FLAG_T6_CANCELED); - sngss7_clear_ckt_flag (sngss7_info, FLAG_SENT_ACM); - sngss7_clear_ckt_flag (sngss7_info, FLAG_SENT_CPG); - - sngss7_flush_queue(sngss7_info->event_queue); - sngss7_info->peer_data = NULL; - ftdm_channel_close (&close_chan); - } - break; - - case FTDM_CHANNEL_STATE_UP: - { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_UP); - } - } - break; - - case FTDM_CHANNEL_STATE_TERMINATING: - { - /* Release confirm is sent immediately, since Spirou customer asked us not to wait for the second call leg - * to come back with a release confirm ... */ - /* when receiving REL we move to TERMINATING and notify the user that the bridge is ending */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } else { - /* Notify the user and wait for their ack before sending RLC */ - sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_STOP); - } - } - break; - - case FTDM_CHANNEL_STATE_HANGUP: - { - ft_to_sngss7_rlc(ftdmchan); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - break; - - default: - break; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan) -{ - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - sng_isup_inf_t *isup_intf = NULL; - int state_flag = 1; - int i = 0; - - SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s: ckt=0x%X, blk=0x%X\n", - ftdm_channel_state2str (ftdmchan->state), - sngss7_info->ckt_flags, - sngss7_info->blk_flags); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { - /* DIALING is the only state we process normally when doing an outgoing call that is natively bridged, - * all other states are run by a different state machine (and the freetdm core does not do any checking) */ - if (ftdmchan->state != FTDM_CHANNEL_STATE_DIALING) { - return ftdm_sangoma_ss7_native_bridge_state_change(ftdmchan); - } - } - - /*check what state we are supposed to be in */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_COLLECT: /* IAM received but wating on digits */ - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - while (ftdmchan->caller_data.dnis.digits[i] != '\0'){ - i++; - } - - /* kill t10 if active */ - if (sngss7_info->t10.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id); - } - - /* check if the end of pulsing (ST) character has arrived or the right number of digits */ - if (ftdmchan->caller_data.dnis.digits[i-1] == 'F' - || sngss7_test_ckt_flag(sngss7_info, FLAG_FULL_NUMBER) ) - { - SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", ""); - - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_FULL_NUMBER)) { - /* remove the ST */ - ftdmchan->caller_data.dnis.digits[i-1] = '\0'; - sngss7_set_ckt_flag(sngss7_info, FLAG_FULL_NUMBER); - } - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INR_TX)) { - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_INR_SENT) ) { - ft_to_sngss7_inr(ftdmchan); - sngss7_set_ckt_flag(sngss7_info, FLAG_INR_SENT); - - SS7_DEBUG_CHAN (ftdmchan, "Scheduling T.39 timer %s \n", " "); - - /* start ISUP t39 */ - if (ftdm_sched_timer (sngss7_info->t39.sched, - "t39", - sngss7_info->t39.beat, - sngss7_info->t39.callback, - &sngss7_info->t39, - &sngss7_info->t39.hb_timer_id)) - { - - SS7_ERROR ("Unable to schedule timer T39, hanging up call!\n"); - - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; - sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - - /* end the call */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - } - }else { - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - } else { - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - } else if (i >= sngss7_info->circuit->min_digits) { - SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, sngss7_info->circuit->min_digits); - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INR_TX)) { - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_INR_SENT) ) { - ft_to_sngss7_inr(ftdmchan); - sngss7_set_ckt_flag(sngss7_info, FLAG_INR_SENT); - - SS7_DEBUG_CHAN (ftdmchan, "Scheduling T.39 timer %s\n", " " ); - - /* start ISUP t39 */ - if (ftdm_sched_timer (sngss7_info->t39.sched, - "t39", - sngss7_info->t39.beat, - sngss7_info->t39.callback, - &sngss7_info->t39, - &sngss7_info->t39.hb_timer_id)) - { - - SS7_ERROR ("Unable to schedule timer T39, hanging up call!\n"); - - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; - sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - - /* end the call */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - } - - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - }else { - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INF_RX_DN) ) { - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - } - } else { - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - } - } else { - /* if we are coming from idle state then we have already been here once before */ - if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) { - SS7_INFO_CHAN(ftdmchan, "Received %d out of %d so far: %s...starting T35\n", - i, - sngss7_info->circuit->min_digits, - ftdmchan->caller_data.dnis.digits); - - /* start ISUP t35 */ - if (ftdm_sched_timer (sngss7_info->t35.sched, - "t35", - sngss7_info->t35.beat, - sngss7_info->t35.callback, - &sngss7_info->t35, - &sngss7_info->t35.hb_timer_id)) { - - SS7_ERROR ("Unable to schedule timer, hanging up call!\n"); - - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; - - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - - /* end the call */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - } - } - - /* start ISUP t10 */ - if (ftdm_sched_timer (sngss7_info->t10.sched, - "t10", - sngss7_info->t10.beat, - sngss7_info->t10.callback, - &sngss7_info->t10, - &sngss7_info->t10.hb_timer_id)) { - - SS7_ERROR ("Unable to schedule timer, hanging up call!\n"); - - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; - - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - - /* end the call */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - } - } - - break; - - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RING: /*incoming call request */ - - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX_DN); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_SENT); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX_DN); - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - /* kill t35 if active */ - if (sngss7_info->t35.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id); - } - - /* cancel t39 timer */ - if (sngss7_info->t39.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id); - } - - SS7_DEBUG_CHAN(ftdmchan, "Sending incoming call from %s to %s to FTDM core\n", - ftdmchan->caller_data.ani.digits, - ftdmchan->caller_data.dnis.digits); - - - /* we have enough information to inform FTDM of the call */ - sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_START); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: /*outgoing call request */ - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - SS7_DEBUG_CHAN(ftdmchan, "Sending outgoing call from \"%s\" to \"%s\" to LibSngSS7\n", - ftdmchan->caller_data.ani.digits, - ftdmchan->caller_data.dnis.digits); - - /*call sangoma_ss7_dial to make outgoing call */ - ft_to_sngss7_iam(ftdmchan); - - break; - /**************************************************************************/ - /* We handle RING indication the same way we would indicate PROGRESS */ - case FTDM_CHANNEL_STATE_RINGING: - case FTDM_CHANNEL_STATE_PROGRESS: - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - /*check if the channel is inbound or outbound */ - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - /*OUTBOUND...so we were told by the line of this so noifiy the user */ - sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_PROGRESS); - - /* move to progress media */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else { - /* inbound call so we need to send out ACM */ - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_SENT_ACM)) { - sngss7_set_ckt_flag(sngss7_info, FLAG_SENT_ACM); - ft_to_sngss7_acm(ftdmchan); - } - if (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].cpg_on_progress == FTDM_TRUE) { - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_SENT_CPG)) { - sngss7_set_ckt_flag(sngss7_info, FLAG_SENT_CPG); - ft_to_sngss7_cpg(ftdmchan); - } - } - } - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - /* inform the user there is media avai */ - sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_PROGRESS_MEDIA); - } else { - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_SENT_ACM)) { - sngss7_set_ckt_flag(sngss7_info, FLAG_SENT_ACM); - ft_to_sngss7_acm(ftdmchan); - } - if (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].cpg_on_progress_media == FTDM_TRUE) { - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_SENT_CPG)) { - sngss7_set_ckt_flag(sngss7_info, FLAG_SENT_CPG); - ft_to_sngss7_cpg(ftdmchan); - } - } - } - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_UP: /*call is accpeted...both incoming and outgoing */ - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - /*check if the channel is inbound or outbound */ - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - /*OUTBOUND...so we were told by the line that the other side answered */ - sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_UP); - } else { - /*INBOUND...so FS told us it was going to answer...tell the stack */ - ft_to_sngss7_anm(ftdmchan); - } - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_CANCEL: - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - SS7_ERROR_CHAN(ftdmchan,"Hanging up call before informing user%s\n", " "); - - /*now go to the HANGUP complete state */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: /*call is hung up remotely */ - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - /* set the flag to indicate this hangup is started from the remote side */ - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - - /*this state is set when the line is hanging up */ - sngss7_send_signal(sngss7_info, FTDM_SIGEVENT_STOP); - - /* If the RESET flag is set, do not say in TERMINATING state. - Go back to RESTART state and wait for RESET Confirmation */ - if (sngss7_tx_reset_status_pending(sngss7_info)) { - SS7_DEBUG_CHAN(ftdmchan,"Reset pending in Terminating state!%s\n", ""); - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_HANGUP: /*call is hung up locally */ - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - /* check for remote hangup flag */ - if (sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { - /* remote release ...do nothing here */ - SS7_DEBUG_CHAN(ftdmchan,"Hanging up remotely requested call!%s\n", ""); - } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_GLARE)) { - /* release due to glare */ - SS7_DEBUG_CHAN(ftdmchan,"Hanging up requested call do to glare%s\n", ""); - } else { - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - - /*this state is set when FS is hanging up...so tell the stack */ - ft_to_sngss7_rel (ftdmchan); - - SS7_DEBUG_CHAN(ftdmchan,"Hanging up locally requested call!%s\n", ""); - } - - /*now go to the HANGUP complete state */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); - - break; - - /**************************************************************************/ - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); - break; - } - - if (sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { - - sngss7_clear_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - - /* check if this hangup is from a tx RSC */ - if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) { - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_SENT)) { - ft_to_sngss7_rsc (ftdmchan); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_SENT); - - /* Wait for Reset in HANGUP Complete nothing to do until we - get reset response back */ - } else if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) { - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - /* Stay in hangup complete until RSC is received */ - /* Channel is in use if we go to RESTART we will - restart will just come back to HANGUP_COMPLETE */ - } - } else { - /* if the hangup is from a rx RSC, rx GRS, or glare don't sent RLC */ - if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) && - !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) && - !(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) { - - /* send out the release complete */ - ft_to_sngss7_rlc (ftdmchan); - } - - /*now go to the DOWN state */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - - SS7_DEBUG_CHAN(ftdmchan,"Completing remotely requested hangup!%s\n", ""); - } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_LOCAL_REL)) { - - /* if this hang up is do to a rx RESET we need to sit here till the RSP arrives */ - if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX_RSP)) { - /* go to the down state as we have already received RSC-RLC */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - - /* if it's a local release the user sends us to down */ - SS7_DEBUG_CHAN(ftdmchan,"Completing locally requested hangup!%s\n", ""); - } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_GLARE)) { - SS7_DEBUG_CHAN(ftdmchan,"Completing requested hangup due to glare!%s\n", ""); - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - SS7_DEBUG_CHAN(ftdmchan,"Completing requested hangup for unknown reason!%s\n", ""); - if (sngss7_channel_status_clear(sngss7_info)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } - } - - break; - - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: /*the call is finished and removed */ - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { - if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) { - SS7_DEBUG_CHAN(ftdmchan,"Down came from SUSPEND - break %s\n", ""); - break; - } - } - - /* check if there is a reset response that needs to be sent */ - if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) { - /* send a RSC-RLC */ - ft_to_sngss7_rsca (ftdmchan); - - /* clear the reset flag */ - clear_rx_rsc_flags(sngss7_info); - } - - /* check if there was a GRS that needs a GRA */ - if ((sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) && - (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) && - (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT))) { - - /* check if this is the base circuit and send out the GRA - * we insure that this is the last circuit to have the state change queued */ - if (sngss7_info->rx_grs.range) { - /* send out the GRA */ - ft_to_sngss7_gra(ftdmchan); - - /* clean out the spans GRS structure */ - clear_rx_grs_data(sngss7_info); - } - - /* clear the grp reset flag */ - clear_rx_grs_flags(sngss7_info); - } - - /* check if we got the reset response */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) { - /* clear the reset flag */ - clear_tx_rsc_flags(sngss7_info); - } - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { - /* clear the reset flag */ - clear_tx_grs_flags(sngss7_info); - if (sngss7_info->rx_gra.range) { - /* clean out the spans GRA structure */ - clear_rx_gra_data(sngss7_info); - } - } - - /* check if we came from reset (aka we just processed a reset) */ - if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) || - (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) || - (ftdmchan->last_state == FTDM_CHANNEL_STATE_HANGUP_COMPLETE)) { - - - /* check if reset flags are up indicating there is more processing to do yet */ - if (!(sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) && - !(sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) && - !(sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) && - !(sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX))) { - - SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X\n", - sngss7_info->ckt_flags, - sngss7_info->blk_flags); - - if (sngss7_channel_status_clear(sngss7_info)) { - /* check if the sig status is down, and bring it up if it isn't */ - if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { - SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", ""); - /* all flags are down so we can bring up the sig status */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - } - } else { - state_flag = 0; - SS7_DEBUG_CHAN(ftdmchan,"Down detected blocked flags go to SUSPEND %s\n", " "); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - break; - - } - } else { - SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->ckt_flags); - - /* there is still another reset pending so go back to reset*/ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - } - - /* check if t35 is active */ - if (sngss7_info->t35.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id); - } - - /* clear all of the call specific data store in the channel structure */ - sngss7_info->suInstId = 0; - sngss7_info->spInstId = 0; - sngss7_info->globalFlg = 0; - sngss7_info->spId = 0; - - /* clear any call related flags */ - sngss7_clear_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_clear_ckt_flag (sngss7_info, FLAG_LOCAL_REL); - sngss7_clear_ckt_flag (sngss7_info, FLAG_SENT_ACM); - sngss7_clear_ckt_flag (sngss7_info, FLAG_SENT_CPG); - - - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) { - ftdm_channel_t *close_chan = ftdmchan; - /* close the channel */ - SS7_DEBUG_CHAN(ftdmchan,"FTDM Channel Close %s\n", ""); - sngss7_flush_queue(sngss7_info->event_queue); - ftdm_channel_close (&close_chan); - } - - /* check if there is a glared call that needs to be processed */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { - sngss7_clear_ckt_flag (sngss7_info, FLAG_GLARE); - - if (sngss7_info->glare.circuit != 0) { - int bHandle=0; - switch (g_ftdm_sngss7_data.cfg.glareResolution) { - case SNGSS7_GLARE_DOWN: - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Giving control to the other side, handling copied IAM from glare. \n", sngss7_info->circuit->cic); - bHandle = 1; - break; - - case SNGSS7_GLARE_PC: - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Trying to handle IAM copied from glare. \n", sngss7_info->circuit->cic); - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]My PC = %d, incoming PC = %d. \n", sngss7_info->circuit->cic, - g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc, - g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc ); - - if( g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc > g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc ) - { - if ((sngss7_info->circuit->cic % 2) == 1 ) { - bHandle = 1; - } - } else { - if( (sngss7_info->circuit->cic % 2) == 0 ) { - bHandle = 1; - } - } - - break; - default: /* if configured as SNGSS7_GLARE_CONTROL, always abandon incoming glared IAM. */ - bHandle = 0; - break; - } - - if (!bHandle) { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Handling glare IAM. \n", sngss7_info->circuit->cic); - handle_con_ind (0, sngss7_info->glare.spInstId, sngss7_info->glare.circuit, &sngss7_info->glare.iam); - } - - /* clear the glare info */ - memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t)); - state_flag = 0; - } - } - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: /* CICs needs a Reset */ - - SS7_DEBUG_CHAN(ftdmchan,"RESTART: Current flags: ckt=0x%X, blk=0x%X\n", - sngss7_info->ckt_flags, - sngss7_info->blk_flags); - - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK)) { - if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) || - (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX))) { - - SS7_DEBUG_CHAN(ftdmchan,"Incoming Reset request on CIC in UCIC block, removing UCIC block%s\n", ""); - - /* set the unblk flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); - - /* clear the block flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); - - /* process the flag */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* break out of the processing for now */ - break; - } - } - - - /* check if this is an outgoing RSC */ - if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) && - !(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_SENT))) { - - /* don't send out reset before finished hanging up if I'm in-use. */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) { - /* send a reset request */ - ft_to_sngss7_rsc (ftdmchan); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_SENT); - } - - } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) */ - - /* check if this is the first channel of a GRS (this flag is thrown when requesting reset) */ - if ( (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) && - !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT)) && - (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE))) { - - /* send out the grs */ - ft_to_sngss7_grs (ftdmchan); - - } - - /* if the sig_status is up...bring it down */ - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - } - - if (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX)) { - /* set the grp reset done flag so we know we have finished this reset */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); - } /* if (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX)) */ - - - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_INUSE)) { - /* bring the call down first...then process the rest of the reset */ - switch (ftdmchan->last_state){ - /******************************************************************/ - case (FTDM_CHANNEL_STATE_TERMINATING): - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - break; - /******************************************************************/ - case (FTDM_CHANNEL_STATE_HANGUP): - case (FTDM_CHANNEL_STATE_HANGUP_COMPLETE): - /* go back to the last state after taking care of the rest of the restart state */ - state_flag = 0; - ftdm_set_state(ftdmchan, ftdmchan->last_state); - break; - /******************************************************************/ - case (FTDM_CHANNEL_STATE_IN_LOOP): - /* we screwed up in a COT/CCR, remove the loop */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - - /* go to down */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - /******************************************************************/ - default: - /* KONRAD: find out what the cause code should be */ - ftdmchan->caller_data.hangup_cause = 41; - - /* change the state to terminatting, it will throw us back here - * once the call is done - */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /******************************************************************/ - } /* switch (ftdmchan->last_state) */ - } else { - /* check if this an incoming RSC or we have a response already */ - if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX) || - sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX_RSP) || - sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP) || - sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX_CMPLT)) { - - SS7_DEBUG_CHAN(ftdmchan, "Reset processed moving to DOWN (0x%X)\n", sngss7_info->ckt_flags); - - /* go to a down state to clear the channel and send the response */ - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - - SS7_DEBUG_CHAN(ftdmchan, "Waiting on Reset Rsp/Grp Reset to move to DOWN (0x%X)\n", sngss7_info->ckt_flags); - } - } - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_SUSPENDED: /* circuit has been blocked */ - - SS7_DEBUG_CHAN(ftdmchan,"SUSPEND: Current flags: ckt=0x%X, blk=0x%X, circuit->flag=0x%X\n", - sngss7_info->ckt_flags, sngss7_info->blk_flags, - sngss7_info->circuit->flags ); - - if (!(sngss7_info->circuit->flags & SNGSS7_CONFIGURED)) { - /* Configure the circuit if RESUME and PAUSED are not set. - And also in a case when RESUME is set */ - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED) || - sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { - if (ftmod_ss7_isup_ckt_config(sngss7_info->circuit->id)) { - SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", sngss7_info->circuit->id); - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - } else { - SS7_INFO("ISUP CKT %d configuration DONE!\n", sngss7_info->circuit->id); - sngss7_info->circuit->flags |= SNGSS7_CONFIGURED; - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); - } - } - } - - /**********************************************************************/ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", ""); - - /* clear the RESUME flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - - /* clear the PAUSE flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* We tried to hangup the call while in PAUSED state. - We must send a RESET to clear this circuit */ - if (sngss7_test_ckt_flag (sngss7_info, FLAG_LOCAL_REL)) { - SS7_DEBUG_CHAN(ftdmchan, "Channel local release on RESUME, restart Reset procedure%s\n", ""); - /* By setting RESET_TX flag the check below sngss7_tx_reset_status_pending() will - be true, and will restart the RESET TX procedure */ - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_set_ckt_flag (sngss7_info, FLAG_RESET_TX); - } - - /* We have transmitted Reset/GRS but have not gotten a - * Response. In mean time we got a RESUME. We cannot be sure - * that our reset has been trasmitted, thus restart reset procedure. */ - if (sngss7_tx_reset_status_pending(sngss7_info)) { - SS7_DEBUG_CHAN(ftdmchan, "Channel transmitted RSC/GRS before RESUME, restart Reset procedure%s\n", ""); - clear_rx_grs_flags(sngss7_info); - clear_rx_grs_data(sngss7_info); - clear_tx_grs_flags(sngss7_info); - clear_tx_grs_data(sngss7_info); - clear_rx_rsc_flags(sngss7_info); - clear_tx_rsc_flags(sngss7_info); - - clear_tx_rsc_flags(sngss7_info); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); - } - - /* if there are any resets present */ - if (!sngss7_channel_status_clear(sngss7_info)) { - /* don't bring up the sig status but also move to reset */ - if (!sngss7_reset_status_clear(sngss7_info)) { - goto suspend_goto_restart; - } else if (!sngss7_block_status_clear(sngss7_info)) { - /* Do nothing just go through and handle blocks below */ - } else { - /* This should not happen as above function tests - * for reset and blocks */ - SS7_ERROR_CHAN(ftdmchan, "Invalid code path: sngss7_channel_status_clear reset and block are both cleared%s\n", ""); - goto suspend_goto_restart; - } - } else { - /* bring the sig status back up */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - } - } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */ - - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", ""); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - } - - /* Wait for RESUME */ - goto suspend_goto_last; - } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ - - /**********************************************************************/ - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX) && - !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", ""); - - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - /* send a BLA */ - ft_to_sngss7_bla (ftdmchan); - - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - - } - - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){ - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_RX flag %s\n", ""); - - /* clear the block flags */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - - /* clear the unblock flag */ - sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); - - SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X\n", - sngss7_info->ckt_flags, - sngss7_info->blk_flags); - /* not bring the cic up if there is a hardware block */ - if (sngss7_channel_status_clear(sngss7_info)) { - /* bring the sig status up */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - - } - /* send a uba */ - ft_to_sngss7_uba (ftdmchan); - - } - - - /**********************************************************************/ - /* hardware block/unblock tx */ - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_GRP_HW_BLOCK_TX ) && - !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX_DN )) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_BLOCK_TX flag %s\n", ""); - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - /* dont send block again if the channel is already blocked by maintenance */ - if( !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX) && - !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN) - ) { - ft_to_sngss7_blo(ftdmchan); - } - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX_DN); - - } - - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_UNBLK_TX)) { - int skip_unblock=0; - SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_UNBLK_TX flag %s\n", ""); - - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX) || - sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX_DN)) { - /* Real unblock */ - } else { - SS7_ERROR_CHAN(ftdmchan, "FLAG_GRP_HW_UNBLK_TX set while FLAG_GRP_HW_BLOCK_TX is not %s\n", ""); - skip_unblock=1; - } - - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX_DN); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_UNBLK_TX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_UNBLK_TX_DN); - - if (sngss7_channel_status_clear(sngss7_info)) { - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - } - - if (sngss7_tx_block_status_clear(sngss7_info) && !skip_unblock) { - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); - ft_to_sngss7_ubl(ftdmchan); - } - - } - - /**********************************************************************/ -#if 0 - /* This logic is handled in the handle_cgu_req and handle_cgb_req */ - - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_GRP_HW_BLOCK_RX ) && - !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN )) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_BLOCK_RX flag %s\n", ""); - - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - /* FIXME: Transmit CRG Ack */ - - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN); - - goto suspend_goto_last; - } - - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_GRP_HW_UNBLK_RX )){ - SS7_DEBUG_CHAN(ftdmchan, "Processing FLAG_GRP_HW_UNBLK_RX flag %s\n", ""); - - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_UNBLK_RX); - - if (sngss7_channel_status_clear(sngs7_info)) { - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - } - - /* Transmit CRU Ack */ - - goto suspend_goto_last; - } -#endif - - - /**********************************************************************/ - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX) && - !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", ""); - - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - /* send a blo */ - ft_to_sngss7_blo (ftdmchan); - - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN); - - } - - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_TX flag %s\n", ""); - - /* clear the block flags */ - sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX); - sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN); - - /* clear the unblock flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX); - - if (sngss7_channel_status_clear(sngss7_info)) { - /* bring the sig status up */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - } - - if (sngss7_tx_block_status_clear(sngss7_info)) { - /* send a ubl */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); - ft_to_sngss7_ubl(ftdmchan); - } - - } - - /**********************************************************************/ - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX) && - !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_BLOCK_RX flag %s\n", ""); - - /* send a BLA */ - ft_to_sngss7_bla(ftdmchan); - - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); - - if (sngss7_tx_block_status_clear(sngss7_info)) { - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); - ft_to_sngss7_ubl(ftdmchan); - } else { - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - } - - } - - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_UNBLK_RX flag %s\n", ""); - - /* clear the block flags */ - sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX); - sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); - - /* clear the unblock flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); - - /* send a uba */ - ft_to_sngss7_uba(ftdmchan); - - if (sngss7_channel_status_clear(sngss7_info)) { - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); - } - - - } - /**********************************************************************/ - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK) && - !sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK_DN)) { - - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_BLOCK flag %s\n", ""); - - /* bring the channel signaling status to down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - /* remove any reset flags */ - clear_rx_grs_flags(sngss7_info); - clear_rx_grs_data(sngss7_info); - clear_tx_grs_flags(sngss7_info); - clear_tx_grs_data(sngss7_info); - clear_rx_rsc_flags(sngss7_info); - clear_tx_rsc_flags(sngss7_info); - - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK_DN); - - } - - if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) { - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", ""); - - /* remove the UCIC block flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK_DN); - - /* remove the UCIC unblock flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); - - /* throw the channel into reset to sync states */ - - clear_rx_grs_flags(sngss7_info); - clear_rx_grs_data(sngss7_info); - clear_tx_grs_flags(sngss7_info); - clear_tx_grs_data(sngss7_info); - clear_rx_rsc_flags(sngss7_info); - clear_tx_rsc_flags(sngss7_info); - - clear_tx_rsc_flags(sngss7_info); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); - - /* bring the channel into restart again */ - goto suspend_goto_restart; - } - - SS7_DEBUG_CHAN(ftdmchan,"No block flag processed!%s\n", ""); - -suspend_goto_last: - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_UP) { - /* proceed to UP */ - } else if (!sngss7_reset_status_clear(sngss7_info) || - sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { - - /* At this point the circuit is in reset, if the call is - in use make sure that at least REMOTE REL flag is set - in order to drop the call on the sip side */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) { - if (!sngss7_test_ckt_flag (sngss7_info, FLAG_LOCAL_REL) && - !sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - } - } - SS7_DEBUG_CHAN(ftdmchan,"Channel opted to stay in RESTART due to reset!%s\n", ""); - SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X, circuit->flag=0x%X\n", - sngss7_info->ckt_flags, sngss7_info->blk_flags, - sngss7_info->circuit->flags ); - - goto suspend_goto_restart; - - } else if (sngss7_channel_status_clear(sngss7_info)) { - - /* In this case all resets and blocks are clear sig state is up, thus go to DOWN */ - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART || - ftdmchan->last_state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdmchan->last_state = FTDM_CHANNEL_STATE_DOWN; - } - - SS7_DEBUG_CHAN(ftdmchan,"Channel signallig is UP: proceed to State %s!\n", - ftdm_channel_state2str(ftdmchan->last_state)); - SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X, circuit->flag=0x%X\n", - sngss7_info->ckt_flags, sngss7_info->blk_flags, - sngss7_info->circuit->flags ); - - } else { - - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_DOWN) { - ftdmchan->last_state = FTDM_CHANNEL_STATE_RESTART; - } - SS7_DEBUG_CHAN(ftdmchan,"Channel signaling is in block state: proceed to State=%s]\n", - ftdm_channel_state2str(ftdmchan->last_state)); - SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X, circuit->flag=0x%X\n", - sngss7_info->ckt_flags, sngss7_info->blk_flags, - sngss7_info->circuit->flags); - } - - state_flag = 0; - ftdm_set_state(ftdmchan, ftdmchan->last_state); - break; - -suspend_goto_restart: - state_flag = 0; - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - - /**************************************************************************/ - case FTDM_CHANNEL_STATE_IN_LOOP: /* COT test */ - - isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; - - if (sngss7_test_options(isup_intf, SNGSS7_LPA_FOR_COT)) { - /* send the lpa */ - ft_to_sngss7_lpa (ftdmchan); - } - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_IDLE: - state_flag = 0; - ftdm_set_state(ftdmchan, ftdmchan->last_state); - break; - /**************************************************************************/ - default: - /* we don't handle any of the other states */ - SS7_ERROR_CHAN(ftdmchan, "ftmod_sangoma_ss7 does not support %s state\n", ftdm_channel_state2str (ftdmchan->state)); - - break; - /**************************************************************************/ - } - - if (state_flag) { - /* clear the state change flag...since we might be setting a new state */ - ftdm_channel_complete_state(ftdmchan); - } - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) -{ - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - /* the core has this channel already locked so need to lock again */ - - /* check if the channel sig state is UP */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, skipping channell!%s\n", " "); - /* Sig state will be down due to a block. - Right action is to hunt for another call */ - goto outgoing_break; - } - - /* check if there is a remote block */ - if ((sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { - - /* the channel is blocked...can't send any calls here */ - SS7_ERROR_CHAN(ftdmchan, "Requested channel is remotely blocked, re-hunt channel!%s\n", " "); - goto outgoing_break; - } - - /* check if there is a local block */ - if ((sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { - - /* KONRAD FIX ME : we should check if this is a TEST call and allow it */ - - /* the channel is blocked...can't send any calls here */ - SS7_ERROR_CHAN(ftdmchan, "Requested channel is locally blocked, re-hunt channel!%s\n", " "); - goto outgoing_break; - } - - - /* This is a gracefull stack resource check. - Removing this function will cause unpredictable - ungracefule errors. */ - if (sng_cc_resource_check()) { - goto outgoing_fail; - } - - /* check the state of the channel */ - switch (ftdmchan->state){ - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - /* inform the monitor thread that we want to make a call by returning FTDM_SUCCESS */ - - goto outgoing_successful; - break; - /**************************************************************************/ - default: - /* the channel is already used...this can't be, end the request */ - SS7_ERROR("Outgoing call requested channel in already in use...indicating glare on span=%d,chan=%d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); - - goto outgoing_break; - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) (original call) */ - -outgoing_fail: - SS7_DEBUG_CHAN(ftdmchan, "Call Request failed%s\n", " "); - return FTDM_FAIL; - -outgoing_break: - SS7_DEBUG_CHAN(ftdmchan, "Call Request re-hunt%s\n", " "); - return FTDM_BREAK; - -outgoing_successful: - SS7_DEBUG_CHAN(ftdmchan, "Call Request successful%s\n", " "); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -#if 0 - static FIO_CHANNEL_REQUEST_FUNCTION (ftdm_sangoma_ss7_request_chan) - { - SS7_INFO ("KONRAD-> I got called %s\n", __FTDM_FUNC__); - return FTDM_SUCCESS; - } - -#endif - -/******************************************************************************/ - -/* FT-CORE SIG STATUS FUNCTIONS ********************************************** */ -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_ss7_get_sig_status) -{ - if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { - *status = FTDM_SIG_STATE_UP; - } else { - *status = FTDM_SIG_STATE_DOWN; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_ss7_set_sig_status) -{ - SS7_ERROR ("Cannot set channel status in this module\n"); - return FTDM_NOTIMPL; -} - -/* FT-CORE SIG FUNCTIONS ******************************************************/ -static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) -{ - ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_span_data_t *sngss7_span = NULL; - sng_isup_inf_t *sngss7_intf = NULL; - int x; - int first_channel; - - first_channel=0; - - - SS7_INFO ("Starting span %s:%u.\n", span->name, span->span_id); - - /* clear the monitor thread stop flag */ - ftdm_clear_flag (span, FTDM_SPAN_STOP_THREAD); - ftdm_clear_flag (span, FTDM_SPAN_IN_THREAD); - - /* check the status of all isup interfaces */ - check_status_of_all_isup_intf(); - - /* throw the channels in pause */ - for (x = 1; x < (span->chan_count + 1); x++) { - /* extract the channel structure and sngss7 channel data */ - ftdmchan = span->channels[x]; - - /* if there is no sig mod data move along */ - if (ftdmchan->call_data == NULL) continue; - - sngss7_info = ftdmchan->call_data; - sngss7_span = ftdmchan->span->signal_data; - sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; - - /* flag the circuit as active so we can receieve events on it */ - sngss7_set_flag(sngss7_info->circuit, SNGSS7_ACTIVE); - - /* if this is a non-voice channel, move along cause we're done with it */ - if (sngss7_info->circuit->type != SNG_CKT_VOICE) continue; - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the interface is paused or resumed */ - if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is PAUSED\n", sngss7_intf->id); - /* throw the pause flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - } else { - SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is RESUMED\n", sngss7_intf->id); - /* throw the resume flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - } -#if 0 - /* throw the grp reset flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); - if (first_channel == 0) { - sngss7_chan_data_t *cinfo = ftdmchan->call_data; - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE); - cinfo->tx_grs.circuit = sngss7_info->circuit->id; - cinfo->tx_grs.range = span->chan_count -1; - first_channel=1; - } -#else - /* throw the channel into reset */ - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); -#endif - /* throw the channel to suspend */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - } - - /* activate all the configured ss7 links */ - if (ft_to_sngss7_activate_all()) { - SS7_CRITICAL ("Failed to activate LibSngSS7!\n"); - return FTDM_FAIL; - } - - /*start the span monitor thread */ - if (ftdm_thread_create_detached (ftdm_sangoma_ss7_run, span) != FTDM_SUCCESS) { - SS7_CRITICAL ("Failed to start Span Monitor Thread!\n"); - return FTDM_FAIL; - } - - SS7_DEBUG ("Finished starting span %s:%u.\n", span->name, span->span_id); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span) -{ - /*this function is called by the FT-Core to stop this span */ - int timeout=0; - - ftdm_log (FTDM_LOG_INFO, "Stopping span %s:%u.\n", span->name,span->span_id); - - /* throw the STOP_THREAD flag to signal monitor thread stop */ - ftdm_set_flag (span, FTDM_SPAN_STOP_THREAD); - - /* wait for the thread to stop */ - while (ftdm_test_flag (span, FTDM_SPAN_IN_THREAD)) { - ftdm_set_flag (span, FTDM_SPAN_STOP_THREAD); - ftdm_log (FTDM_LOG_DEBUG,"Waiting for monitor thread to end for %s:%u. [flags=0x%08X]\n", - span->name, - span->span_id, - span->flags); - /* Wait 50ms */ - ftdm_sleep (50); - timeout++; - - /* timeout after 5 sec, better to crash than hang */ - ftdm_assert_return(timeout < 100, FTDM_FALSE, "SS7 Span stop timeout!\n"); - } - - /* KONRAD FIX ME - deconfigure any circuits, links, attached to this span */ - - ftdm_log (FTDM_LOG_DEBUG, "Finished stopping span %s:%u.\n", span->name, span->span_id); - - return FTDM_SUCCESS; -} - -/* SIG_FUNCTIONS ***************************************************************/ -static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) -{ - sngss7_span_data_t *ss7_span_info; - - ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n", - span->name, - span->span_id); - - /* initalize the span's data structure */ - ss7_span_info = ftdm_calloc (1, sizeof (sngss7_span_data_t)); - - /* create a timer schedule */ - if (ftdm_sched_create(&ss7_span_info->sched, "SngSS7_Schedule")) { - SS7_CRITICAL("Unable to create timer schedule!\n"); - return FTDM_FAIL; - } - - /* start the free run thread for the schedule */ - if (ftdm_sched_free_run(ss7_span_info->sched)) { - SS7_CRITICAL("Unable to schedule free run!\n"); - return FTDM_FAIL; - } - - /* create an event queue for this span */ - if ((ftdm_queue_create(&(ss7_span_info)->event_queue, SNGSS7_EVENT_QUEUE_SIZE)) != FTDM_SUCCESS) { - SS7_CRITICAL("Unable to create event queue!\n"); - return FTDM_FAIL; - } - - /*setup the span structure with the info so far */ - g_ftdm_sngss7_data.sig_cb = sig_cb; - span->start = ftdm_sangoma_ss7_start; - span->stop = ftdm_sangoma_ss7_stop; - span->signal_type = FTDM_SIGTYPE_SS7; - span->signal_data = NULL; - span->outgoing_call = ftdm_sangoma_ss7_outgoing_call; - span->channel_request = NULL; - span->signal_cb = sig_cb; - span->get_channel_sig_status = ftdm_sangoma_ss7_get_sig_status; - span->set_channel_sig_status = ftdm_sangoma_ss7_set_sig_status; - span->state_map = &sangoma_ss7_state_map; - span->state_processor = ftdm_sangoma_ss7_process_state_change; - span->signal_data = ss7_span_info; - - /* set the flag to indicate that this span uses channel state change queues */ - ftdm_set_flag (span, FTDM_SPAN_USE_CHAN_QUEUE); - /* set the flag to indicate that this span uses sig event queues */ - ftdm_set_flag (span, FTDM_SPAN_USE_SIGNALS_QUEUE); - - - - /* parse the configuration and apply to the global config structure */ - if (ftmod_ss7_parse_xml(ftdm_parameters, span)) { - ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n"); - ftdm_sleep (100); - return FTDM_FAIL; - } - - if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){ - ftdm_log (FTDM_LOG_INFO, "FreeTDM running as M2UA_SG mode, Setting Span type to FTDM_SIGTYPE_M2UA\n"); - span->signal_type = FTDM_SIGTYPE_M2UA; - } - - if (ft_to_sngss7_cfg_all()) { /* configure libsngss7 */ - ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n"); - ftdm_sleep (100); - return FTDM_FAIL; - } - - ftdm_log (FTDM_LOG_INFO, "Finished configuring ftmod_sangoma_ss7 span = %s(%d)...\n", - span->name, - span->span_id); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) -{ - /*this function is called by the FT-core to load the signaling module */ - uint32_t major = 0; - uint32_t minor = 0; - uint32_t build = 0; - - ftdm_log (FTDM_LOG_INFO, "Loading ftmod_sangoma_ss7...\n"); - - /* default the global structure */ - memset (&g_ftdm_sngss7_data, 0x0, sizeof (ftdm_sngss7_data_t)); - - sngss7_id = 0; - - cmbLinkSetId = 0; - - /* initalize the global gen_config flag */ - g_ftdm_sngss7_data.gen_config = 0; - - /* function trace initizalation */ - g_ftdm_sngss7_data.function_trace = 1; - g_ftdm_sngss7_data.function_trace_level = 7; - - /* message (IAM, ACM, ANM, etc) trace initizalation */ - g_ftdm_sngss7_data.message_trace = 1; - g_ftdm_sngss7_data.message_trace_level = 6; - - /* setup the call backs needed by Sangoma_SS7 library */ - sng_event.cc.sng_con_ind = sngss7_con_ind; - sng_event.cc.sng_con_cfm = sngss7_con_cfm; - sng_event.cc.sng_con_sta = sngss7_con_sta; - sng_event.cc.sng_rel_ind = sngss7_rel_ind; - sng_event.cc.sng_rel_cfm = sngss7_rel_cfm; - sng_event.cc.sng_dat_ind = sngss7_dat_ind; - sng_event.cc.sng_fac_ind = sngss7_fac_ind; - sng_event.cc.sng_fac_cfm = sngss7_fac_cfm; - sng_event.cc.sng_sta_ind = sngss7_sta_ind; - sng_event.cc.sng_umsg_ind = sngss7_umsg_ind; - sng_event.cc.sng_susp_ind = sngss7_susp_ind; - sng_event.cc.sng_resm_ind = sngss7_resm_ind; - - sng_event.sm.sng_log = handle_sng_log; - sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm; - sng_event.sm.sng_mtp2_alarm = handle_sng_mtp2_alarm; - sng_event.sm.sng_mtp3_alarm = handle_sng_mtp3_alarm; - sng_event.sm.sng_isup_alarm = handle_sng_isup_alarm; - sng_event.sm.sng_cc_alarm = handle_sng_cc_alarm; - sng_event.sm.sng_relay_alarm = handle_sng_relay_alarm; - sng_event.sm.sng_m2ua_alarm = handle_sng_m2ua_alarm; - sng_event.sm.sng_nif_alarm = handle_sng_nif_alarm; - sng_event.sm.sng_tucl_alarm = handle_sng_tucl_alarm; - sng_event.sm.sng_sctp_alarm = handle_sng_sctp_alarm; - - /* initalize sng_ss7 library */ - sng_isup_init_gen(&sng_event); - - /* print the version of the library being used */ - sng_isup_version(&major, &minor, &build); - SS7_INFO("Loaded LibSng-SS7 %d.%d.%d\n", major, minor, build); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload) -{ - /*this function is called by the FT-core to unload the signaling module */ - - int x; - - ftdm_log (FTDM_LOG_INFO, "Starting ftmod_sangoma_ss7 unload...\n"); - - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_STARTED)) { - sng_isup_free_cc(); - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_STARTED); - } - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) { - ftmod_ss7_shutdown_isup(); - sng_isup_free_isup(); - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED); - } - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_STARTED)) { - ftmod_ss7_shutdown_mtp3(); - sng_isup_free_mtp3(); - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_STARTED); - } - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED)) { - ftmod_ss7_shutdown_mtp2(); - sng_isup_free_mtp2(); - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED); - } - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_STARTED)) { - sng_isup_free_mtp1(); - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_STARTED); - } - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_STARTED)) { - /* go through all the relays channels and disable them */ - x = 1; - while (x < (MAX_RELAY_CHANNELS)) { - /* check if this relay channel has been configured already */ - if ((g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED)) { - - /* send the specific configuration */ - if (ftmod_ss7_disable_relay_channel(x)) { - SS7_CRITICAL("Relay Channel %d disable failed!\n", x); - /* jz: dont leave like this - * return 1; - * */ - } else { - SS7_INFO("Relay Channel %d disable DONE!\n", x); - } - - /* set the SNGSS7_CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.relay[x].flags &= ~(SNGSS7_CONFIGURED); - } /* if !SNGSS7_CONFIGURED */ - x++; - } /* while (x < (MAX_RELAY_CHANNELS)) */ - - ftmod_ss7_shutdown_relay(); - sng_isup_free_relay(); - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_STARTED); - } - - if(SNG_SS7_OPR_MODE_ISUP != g_ftdm_operating_mode){ - ftmod_ss7_m2ua_free(); - } - - - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM_STARTED)) { - sng_isup_free_sm(); - sngss7_clear_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SM_STARTED); - } - - sng_isup_free_gen(); - - ftdm_log (FTDM_LOG_INFO, "Finished ftmod_sangoma_ss7 unload!\n"); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static FIO_API_FUNCTION(ftdm_sangoma_ss7_api) -{ - /* handle this in it's own file....so much to do */ - return (ftdm_sngss7_handle_cli_cmd (stream, data)); -} - -/******************************************************************************/ -static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_ss7_io_init) -{ - assert (fio != NULL); - memset (&g_ftdm_sngss7_interface, 0, sizeof (g_ftdm_sngss7_interface)); - - g_ftdm_sngss7_interface.name = "ss7"; - g_ftdm_sngss7_interface.api = ftdm_sangoma_ss7_api; - - *fio = &g_ftdm_sngss7_interface; - - return FTDM_SUCCESS; -} - -/******************************************************************************/ - - -/* START **********************************************************************/ -ftdm_module_t ftdm_module = { - "sangoma_ss7", /*char name[256]; */ - ftdm_sangoma_ss7_io_init, /*fio_io_load_t */ - NULL, /*fio_io_unload_t */ - ftdm_sangoma_ss7_init, /*fio_sig_load_t */ - NULL, /*fio_sig_configure_t */ - ftdm_sangoma_ss7_unload, /*fio_sig_unload_t */ - ftdm_sangoma_ss7_span_config /*fio_configure_span_signaling_t */ -}; -/******************************************************************************/ - -/******************************************************************************/ -/* For Emacs: -* Local Variables: -* mode:c -* indent-tabs-mode:t -* tab-width:4 -* c-basic-offset:4 -* End: -* For VIM: -* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: -*/ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h deleted file mode 100644 index 6dabf727cd..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ /dev/null @@ -1,1246 +0,0 @@ -/* - * Copyright (c) 2009, Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributors: - * - * James Zhang - * - */ -/******************************************************************************/ -#ifndef __FTMOD_SNG_SS7_H__ -#define __FTMOD_SNG_SS7_H__ -/******************************************************************************/ - -/* INCLUDE ********************************************************************/ -#include -#include -#include -#include -#include -#include - -#include "private/ftdm_core.h" - -#include "sng_ss7/sng_ss7.h" -#include "ftmod_sangoma_ss7_m2ua.h" - -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -#define MAX_NAME_LEN 25 - -#define MAX_CIC_LENGTH 5 -#define MAX_CIC_MAP_LENGTH 1000 -#define MAX_SCTP_LINK 100 - -#define SNGSS7_EVENT_QUEUE_SIZE 100 -#define SNGSS7_PEER_CHANS_QUEUE_SIZE 100 -#define SNGSS7_CHAN_EVENT_QUEUE_SIZE 100 - -#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */ - -#define SNGSS7_SWITCHTYPE_ANSI(switchtype) (switchtype == LSI_SW_ANS88) || \ - (switchtype == LSI_SW_ANS92) || \ - (switchtype == LSI_SW_ANS95) - -#define sngss7_flush_queue(queue) \ - do { \ - void *__queue_data = NULL; \ - while ((__queue_data = ftdm_queue_dequeue(queue))) { \ - ftdm_safe_free(__queue_data); \ - } \ - } while (0) - -typedef struct ftdm2trillium { - uint8_t ftdm_val; - uint8_t trillium_val; -} ftdm2trillium_t; - -typedef enum { - SNGSS7_CON_IND_EVENT = 0, - SNGSS7_CON_CFM_EVENT, - SNGSS7_CON_STA_EVENT, - SNGSS7_REL_IND_EVENT, - SNGSS7_REL_CFM_EVENT, - SNGSS7_DAT_IND_EVENT, - SNGSS7_FAC_IND_EVENT, - SNGSS7_FAC_CFM_EVENT, - SNGSS7_UMSG_IND_EVENT, - SNGSS7_STA_IND_EVENT, - SNGSS7_SUSP_IND_EVENT, - SNGSS7_RESM_IND_EVENT, - SNGSS7_SSP_STA_CFM_EVENT, - SNGSS7_INVALID_EVENT, -} sng_event_type_t; -#define SNG_EVENT_TYPE_STRINGS "CON_IND", "CON_CFM", "CON_STA", "REL_IND", "REL_CFM", "DAT_IND", "FAC_IND", \ - "FAC_CFM", "UMSG_IND", "STA_IND", "SUSP_IND", "RESM_IND", "SSP_STA_CFM", "INVALID" -FTDM_STR2ENUM_P(ftdm_str2sngss7_event, ftdm_sngss7_event2str, sng_event_type_t) - -typedef enum { - SNG_BIT_A = (1 << 0), - SNG_BIT_B = (1 << 1), - SNG_BIT_C = (1 << 2), - SNG_BIT_D = (1 << 3), - SNG_BIT_E = (1 << 4), - SNG_BIT_F = (1 << 5), - SNG_BIT_G = (1 << 6), - SNG_BIT_H = (1 << 7) -} sng_bit_enums_t; - -typedef enum { - SNG_CKT_VOICE = 0, - SNG_CKT_SIG, - SNG_CKT_HOLE -} sng_ckt_type_t; - -typedef enum { - SNG_RTE_UP = 0, - SNG_RTE_DN -} sng_route_direction_t; - -typedef enum { - SNGSS7_LPA_FOR_COT = (1 << 0), /* send LPA when COT arrives */ - SNGSS7_ACM_OBCI_BITA = (1 << 10) /* in-band indication */ -} sng_intf_options_t; - -typedef enum { - SNG_CALLED = 1, - SNG_CALLING = 2 -} sng_addr_type_t; - -typedef enum { - SNG_GEN_CFG_STATUS_INIT = 0, - SNG_GEN_CFG_STATUS_PENDING = 1, - SNG_GEN_CFG_STATUS_DONE = 2 -} nsg_gen_cfg_type_t; - -typedef struct sng_mtp2_error_type { - int init; - char sng_type[MAX_NAME_LEN]; - uint32_t tril_type; -} sng_mtp2_error_type_t; - -typedef struct sng_link_type { - int init; - char sng_type[MAX_NAME_LEN]; - uint32_t tril_mtp2_type; - uint32_t tril_mtp3_type; -} sng_link_type_t; - -typedef struct sng_switch_type { - int init; - char sng_type[MAX_NAME_LEN]; - uint32_t tril_mtp3_type; - uint32_t tril_isup_type; -} sng_switch_type_t; - -typedef struct sng_ssf_type { - int init; - char sng_type[MAX_NAME_LEN]; - uint32_t tril_type; -} sng_ssf_type_t; - -typedef struct sng_cic_cntrl_type { - int init; - char sng_type[MAX_NAME_LEN]; - uint32_t tril_type; -} sng_cic_cntrl_type_t; - -typedef struct sng_mtp1_link { - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; - uint32_t span; - uint32_t chan; -} sng_mtp1_link_t; - -typedef struct sng_mtp2_link { - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; - uint32_t lssuLength; - uint32_t errorType; - uint32_t linkType; - uint32_t mtp1Id; - uint32_t mtp1ProcId; - uint32_t t1; - uint32_t t2; - uint32_t t3; - uint32_t t4n; - uint32_t t4e; - uint32_t t5; - uint32_t t6; - uint32_t t7; -} sng_mtp2_link_t; - -/* defining glare handling methods: - SNGSS7_GLARE_PC: - higher PointCode controls even number CIC - lower PointCode controls odd number CIC - SNGSS7_GLARE_DOWN: - always give control to the other side - SNGSS7_GLARE_CONTROL: - always trying to control -*/ -typedef enum { - SNGSS7_GLARE_PC = 0, - SNGSS7_GLARE_DOWN, - SNGSS7_GLARE_CONTROL -} sng_glare_resolution; - -typedef struct sng_mtp3_link { - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; - uint32_t priority; - uint32_t linkType; - uint32_t switchType; - uint32_t apc; - uint32_t spc; - uint32_t ssf; - uint32_t slc; - uint32_t linkSetId; - uint32_t mtp2Id; - uint32_t mtp2ProcId; - uint32_t t1; - uint32_t t2; - uint32_t t3; - uint32_t t4; - uint32_t t5; - uint32_t t6; - uint32_t t7; - uint32_t t8; - uint32_t t9; - uint32_t t10; - uint32_t t11; - uint32_t t12; - uint32_t t13; - uint32_t t14; - uint32_t t15; - uint32_t t16; - uint32_t t17; - uint32_t t18; - uint32_t t19; - uint32_t t20; - uint32_t t21; - uint32_t t22; - uint32_t t23; - uint32_t t24; - uint32_t t25; - uint32_t t27; - uint32_t t28; - uint32_t t29; - uint32_t t30; - uint32_t t31; - uint32_t t32; - uint32_t t33; - uint32_t t34; - uint32_t t35; - uint32_t t36; - uint32_t t37; - uint32_t tcraft; - uint32_t tflc; - uint32_t tbnd; -} sng_mtp3_link_t; - -typedef struct sng_link_set { - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; - uint32_t apc; - uint32_t linkType; - uint32_t switchType; - uint32_t ssf; - uint32_t minActive; - uint32_t numLinks; - uint32_t links[16]; -} sng_link_set_t; - -typedef struct sng_link_set_list { - uint32_t lsId; - struct sng_link_set_list *next; -} sng_link_set_list_t; - -typedef struct sng_route { - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; - uint32_t dpc; - uint32_t cmbLinkSetId; - struct sng_link_set_list lnkSets; - uint32_t linkType; - uint32_t switchType; - uint32_t ssf; - uint32_t nwId; - uint32_t isSTP; - uint32_t dir; - uint32_t t6; - uint32_t t8; - uint32_t t10; - uint32_t t11; - uint32_t t15; - uint32_t t16; - uint32_t t18; - uint32_t t19; - uint32_t t21; - uint32_t t25; - uint32_t t26; -} sng_route_t; - -typedef struct sng_isup_intf { - char name[MAX_NAME_LEN]; - uint32_t options; - uint32_t flags; - uint32_t id; - uint32_t spc; - uint32_t dpc; - uint32_t switchType; - uint32_t nwId; - uint32_t mtpRouteId; - uint32_t ssf; - uint32_t isap; - uint16_t t4; - uint32_t t11; - uint32_t t18; - uint32_t t19; - uint32_t t20; - uint32_t t21; - uint32_t t22; - uint32_t t23; - uint32_t t24; - uint32_t t25; - uint32_t t26; - uint32_t t28; - uint32_t t29; - uint32_t t30; - uint32_t t32; - uint32_t t37; - uint32_t t38; - uint32_t t39; - uint32_t tfgr; - uint32_t tpause; - uint32_t tstaenq; -} sng_isup_inf_t; - -typedef struct sng_isup_ckt { - uint32_t options; - uint32_t flags; - uint32_t procId; - uint32_t id; - uint32_t ccSpanId; - uint32_t span; - uint32_t chan; - uint32_t type; /* VOICE/SIG/HOLE */ - uint32_t cic; - uint32_t infId; - uint32_t typeCntrl; - uint32_t ssf; - uint32_t switchType; - - uint32_t clg_nadi; - uint32_t cld_nadi; - uint8_t rdnis_nadi; - uint32_t loc_nadi; - - /* Generic Number defaults */ - uint8_t gn_nmbqual; /* Number Qualifier */ - uint8_t gn_nadi; /* Nature of Address indicator */ - uint8_t gn_screen_ind; /* Screening Indicator */ - uint8_t gn_pres_ind; /* Presentation Indicator */ - uint8_t gn_npi; /* Numbering Plan Indicator */ - uint8_t gn_num_inc_ind; /* Number Incomplete Indicator */ - /* END - Generic Number defaults */ - - uint32_t min_digits; - uint32_t transparent_iam_max_size; - uint8_t transparent_iam; - uint8_t cpg_on_progress_media; - uint8_t cpg_on_progress; - uint8_t itx_auto_reply; - void *obj; - uint16_t t3; - uint32_t t10; - uint16_t t12; - uint16_t t13; - uint16_t t14; - uint16_t t15; - uint16_t t16; - uint16_t t17; - uint32_t t35; - uint32_t t39; - uint16_t tval; -} sng_isup_ckt_t; - -typedef struct sng_nsap { - uint32_t flags; - uint32_t id; - uint32_t suId; - uint32_t spId; - uint32_t nwId; - uint32_t linkType; - uint32_t switchType; - uint32_t ssf; -} sng_nsap_t; - -typedef struct sng_isap { - uint32_t id; - uint32_t suId; - uint32_t spId; - uint32_t switchType; - uint32_t ssf; - uint32_t flags; - uint32_t t1; - uint32_t t2; - uint32_t t5; - uint32_t t6; - uint32_t t7; - uint32_t t8; - uint32_t t9; - uint32_t t27; - uint32_t t31; - uint32_t t33; - uint32_t t34; - uint32_t t36; - uint32_t tccr; - uint32_t tccrt; - uint32_t tex; - uint32_t tcrm; - uint32_t tcra; - uint32_t tect; - uint32_t trelrsp; - uint32_t tfnlrelrsp; -} sng_isap_t; - -typedef struct sng_relay { - uint32_t id; - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t type; - uint32_t port; - char hostname[RY_REMHOSTNAME_SIZE]; - uint32_t procId; -} sng_relay_t; - -/********************************************** -sctp structures and data definitions -**********************************************/ - -typedef struct sng_sctp_gen_cfg { -} sng_sctp_gen_cfg_t; - -typedef struct sng_sctp_link { - char name[MAX_NAME_LEN]; - uint32_t flags; - uint32_t id; - uint32_t port; - uint32_t numSrcAddr; - uint32_t srcAddrList[SCT_MAX_NET_ADDRS+1]; -} sng_sctp_link_t; - -typedef struct sng_sctp_cfg { - sng_sctp_gen_cfg_t genCfg; - sng_sctp_link_t linkCfg[MAX_SCTP_LINK+1]; -} sng_sctp_cfg_t; - - - -typedef struct sng_ss7_cfg { - uint32_t spc; - uint32_t procId; - char license[MAX_SNGSS7_PATH]; - char signature[MAX_SNGSS7_PATH]; - uint32_t transparent_iam_max_size; - uint32_t flags; - sng_relay_t relay[MAX_RELAY_CHANNELS+1]; - sng_mtp1_link_t mtp1Link[MAX_MTP_LINKS+1]; - sng_mtp2_link_t mtp2Link[MAX_MTP_LINKS+1]; - sng_mtp3_link_t mtp3Link[MAX_MTP_LINKS+1]; - sng_link_set_t mtpLinkSet[MAX_MTP_LINKSETS+1]; - sng_route_t mtpRoute[MAX_MTP_ROUTES+1]; - sng_isup_inf_t isupIntf[MAX_ISUP_INFS+1]; - sng_isup_ckt_t isupCkt[10000]; /* KONRAD - only need 2000 ( and 0-1000 aren't used) since other servers are registerd else where */ - sng_nsap_t nsap[MAX_NSAPS+1]; - sng_isap_t isap[MAX_ISAPS+1]; - sng_glare_resolution glareResolution; - uint32_t force_inr; - sng_m2ua_gbl_cfg_t g_m2ua_cfg; - sng_sctp_cfg_t sctpCfg; -} sng_ss7_cfg_t; - -typedef struct ftdm_sngss7_data { - sng_ss7_cfg_t cfg; - int gen_config; - int function_trace; - int function_trace_level; - int message_trace; - int message_trace_level; - fio_signal_cb_t sig_cb; -} ftdm_sngss7_data_t; - -typedef enum{ - SNG_SS7_OPR_MODE_NONE, - SNG_SS7_OPR_MODE_M2UA_SG, - SNG_SS7_OPR_MODE_ISUP, -}ftdm_sngss7_operating_modes_e; - -typedef ftdm_sngss7_operating_modes_e ftdm_sngss7_opr_mode; - -typedef struct sngss7_timer_data { - ftdm_timer_id_t hb_timer_id; - int beat; - int counter; - ftdm_sched_callback_t callback; - ftdm_sched_t *sched; - void *sngss7_info; -} sngss7_timer_data_t; - -typedef struct sngss7_glare_data { - uint32_t spInstId; - uint32_t circuit; - SiConEvnt iam; -} sngss7_glare_data_t; - -typedef struct sngss7_group_data { - uint32_t circuit; - uint32_t range; - uint8_t status[255]; - uint8_t type; - uint8_t cause; -} sngss7_group_data_t; - -typedef struct sngss7_chan_data { - ftdm_channel_t *ftdmchan; - sng_isup_ckt_t *circuit; - uint32_t base_chan; - uint32_t suInstId; - uint32_t spInstId; - uint32_t spId; - uint8_t globalFlg; - uint32_t ckt_flags; - uint32_t blk_flags; - ftdm_hash_t* variables; /* send on next sigevent */ - ftdm_size_t raw_data_len; - void *raw_data; /* send on next sigevent */ - sngss7_glare_data_t glare; - sngss7_timer_data_t t35; - sngss7_timer_data_t t10; - sngss7_timer_data_t t39; - sngss7_group_data_t rx_grs; - sngss7_group_data_t rx_gra; - sngss7_group_data_t tx_grs; - sngss7_group_data_t ucic; - ftdm_queue_t *event_queue; - struct sngss7_chan_data *peer_data; - uint8_t peer_event_transfer_cnt; -} sngss7_chan_data_t; - -#define SNGSS7_RX_GRS_PENDING (1 << 0) -#define SNGSS7_UCIC_PENDING (1 << 1) -#define SNGSS7_RX_GRA_PENDING (1 << 2) -typedef struct sngss7_span_data { - ftdm_sched_t *sched; - uint32_t flags; - sngss7_group_data_t rx_cgb; - sngss7_group_data_t tx_cgb; - sngss7_group_data_t rx_cgu; - sngss7_group_data_t tx_cgu; - ftdm_queue_t *event_queue; -} sngss7_span_data_t; - -typedef struct sngss7_event_data -{ - uint32_t event_id; - uint32_t spId; - uint32_t suId; - uint32_t spInstId; - uint32_t suInstId; - uint32_t circuit; - uint8_t globalFlg; - uint8_t evntType; - union - { - SiConEvnt siConEvnt; - SiCnStEvnt siCnStEvnt; - SiRelEvnt siRelEvnt; - SiInfoEvnt siInfoEvnt; - SiFacEvnt siFacEvnt; - SiStaEvnt siStaEvnt; - SiSuspEvnt siSuspEvnt; - SiResmEvnt siResmEvnt; - } event; -} sngss7_event_data_t; - - -typedef enum { - FLAG_RESET_RX = (1 << 0), - FLAG_RESET_TX = (1 << 1), - FLAG_RESET_SENT = (1 << 2), - FLAG_RESET_TX_RSP = (1 << 3), - FLAG_GRP_RESET_RX = (1 << 4), - FLAG_GRP_RESET_RX_DN = (1 << 5), - FLAG_GRP_RESET_RX_CMPLT = (1 << 6), - FLAG_GRP_RESET_BASE = (1 << 7), - FLAG_GRP_RESET_TX = (1 << 8), - FLAG_GRP_RESET_SENT = (1 << 9), - FLAG_GRP_RESET_TX_RSP = (1 << 10), - FLAG_REMOTE_REL = (1 << 11), - FLAG_LOCAL_REL = (1 << 12), - FLAG_GLARE = (1 << 13), - FLAG_INFID_RESUME = (1 << 14), - FLAG_INFID_PAUSED = (1 << 15), - FLAG_SENT_ACM = (1 << 16), - FLAG_SENT_CPG = (1 << 17), - FLAG_SUS_RECVD = (1 << 18), - FLAG_T6_CANCELED = (1 << 19), - FLAG_INR_TX = (1 << 20), - FLAG_INR_SENT = (1 << 21), - FLAG_INR_RX = (1 << 22), - FLAG_INR_RX_DN = (1 << 23), - FLAG_INF_TX = (1 << 24), - FLAG_INF_SENT = (1 << 25), - FLAG_INF_RX = (1 << 26), - FLAG_INF_RX_DN = (1 << 27), - FLAG_FULL_NUMBER = (1 << 28), - FLAG_RELAY_DOWN = (1 << 30), - FLAG_CKT_RECONFIG = (1 << 31) -} sng_ckt_flag_t; - -#define CKT_FLAGS_STRING \ - "RX_RSC", \ - "TX_RSC", \ - "TX_RSC_REQ_SENT", \ - "TX_RSC_RSP_RECEIVED", \ - "RX_GRS", \ - "RX_GRS_DONE", \ - "RX_GRS_CMPLT", \ - "GRS_BASE", \ - "TX_GRS", \ - "TX_GRS_REQ_SENT", \ - "TX_GRS_RSP_RECEIVED", \ - "REMOTE_REL", \ - "LOCAL_REL", \ - "GLARE", \ - "INF_RESUME", \ - "INF_PAUSED", \ - "TX_ACM_SENT" \ - "TX_INR" \ - "INR_SENT" \ - "RX_INR" \ - "RX_INR_DN" \ - "TX_INF" \ - "INF SENT" \ - "RX_INF" \ - "RX_INF_DN" \ - "RELAY_DOWN", \ - "CKT_RECONFIG" -FTDM_STR2ENUM_P(ftmod_ss7_ckt_state2flag, ftmod_ss7_ckt_flag2str, sng_ckt_flag_t) - -/* ckt blocking flags */ -typedef enum { - FLAG_CKT_UCIC_BLOCK = (1 << 0), - FLAG_CKT_UCIC_BLOCK_DN = (1 << 1), - FLAG_CKT_UCIC_UNBLK = (1 << 2), - FLAG_CKT_UCIC_UNBLK_DN = (1 << 3), - FLAG_CKT_LC_BLOCK_RX = (1 << 4), - FLAG_CKT_LC_BLOCK_RX_DN = (1 << 5), - FLAG_CKT_LC_UNBLK_RX = (1 << 6), - FLAG_CKT_LC_UNBLK_RX_DN = (1 << 7), - FLAG_CKT_MN_BLOCK_RX = (1 << 8), - FLAG_CKT_MN_BLOCK_RX_DN = (1 << 9), - FLAG_CKT_MN_UNBLK_RX = (1 << 10), - FLAG_CKT_MN_UNBLK_RX_DN = (1 << 11), - FLAG_CKT_MN_BLOCK_TX = (1 << 12), - FLAG_CKT_MN_BLOCK_TX_DN = (1 << 13), - FLAG_CKT_MN_UNBLK_TX = (1 << 14), - FLAG_CKT_MN_UNBLK_TX_DN = (1 << 15), - FLAG_GRP_HW_BLOCK_RX = (1 << 16), - FLAG_GRP_HW_BLOCK_RX_DN = (1 << 17), - FLAG_GRP_HW_BLOCK_TX = (1 << 18), - FLAG_GRP_HW_BLOCK_TX_DN = (1 << 19), - FLAG_GRP_MN_BLOCK_RX = (1 << 20), - FLAG_GRP_MN_BLOCK_RX_DN = (1 << 21), - FLAG_GRP_MN_BLOCK_TX = (1 << 22), - FLAG_GRP_MN_BLOCK_TX_DN = (1 << 23), - FLAG_GRP_HW_UNBLK_TX = (1 << 24), - FLAG_GRP_HW_UNBLK_TX_DN = (1 << 25), - FLAG_GRP_MN_UNBLK_TX = (1 << 26), - FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27), -} sng_ckt_block_flag_t; - -#define BLK_FLAGS_STRING \ - "UCIC BLK", \ - "UCIC BLK DN", \ - "UCIC UNBLK", \ - "UCIC UNBLK DN", \ - "RX LC BLK", \ - "RX LC BLK DN", \ - "RX LC UNBLK", \ - "RX LC UNBLK DN", \ - "RX CKT BLK", \ - "RX CKT BLK DN", \ - "RX CKT UNBLK", \ - "RX CKT UNBLK DN", \ - "TX CKT BLK", \ - "TX CKT BLK DN", \ - "TX CKT UNBLK", \ - "TX CKT UNBLK DN", \ - "RX GRP HW BLK", \ - "RX GRP HW BLK DN", \ - "TX GRP HW BLK", \ - "TX GRP HW BLK DN", \ - "RX GRP MN BLK", \ - "RX GRP MN BLK DN", \ - "TX GRP MN BLK", \ - "TX GRP MN BLK DN", \ - "TX GRP HW UNBLK", \ - "TX GRP HW UNBLK DN", \ - "TX GRP MN UNBLK", \ - "TX GRP MN UNBLK DN", \ - "RX GRP HW UNBLK", \ - "RX GRP HW UNBLK DN" -FTDM_STR2ENUM_P(ftmod_ss7_blk_state2flag, ftmod_ss7_blk_flag2str, sng_ckt_block_flag_t) - -/* valid for every cfg array except circuits */ -typedef enum { - SNGSS7_CONFIGURED = (1 << 0), - SNGSS7_ACTIVE = (1 << 1), - SNGSS7_RELAY_INIT = (1 << 3), - SNGSS7_PAUSED = (1 << 7) /* for isup interfaces */ -} sng_cfg_flag_t; - -typedef enum { - SNGSS7_SM_STARTED = (1 << 0), - - SNGSS7_RY_PRESENT = (1 << 2), - SNGSS7_RY_STARTED = (1 << 3), - - SNGSS7_MTP1_PRESENT = (1 << 4), - SNGSS7_MTP1_STARTED = (1 << 5), - - SNGSS7_MTP2_PRESENT = (1 << 6), - SNGSS7_MTP2_STARTED = (1 << 7), - - SNGSS7_MTP3_PRESENT = (1 << 8), - SNGSS7_MTP3_STARTED = (1 << 9), - - SNGSS7_ISUP_PRESENT = (1 << 10), - SNGSS7_ISUP_STARTED = (1 << 11), - - SNGSS7_CC_PRESENT = (1 << 12), - SNGSS7_CC_STARTED = (1 << 13), - - SNGSS7_TUCL_PRESENT = (1 << 14), - SNGSS7_TUCL_STARTED = (1 << 15), - - SNGSS7_SCTP_PRESENT = (1 << 16), - SNGSS7_SCTP_STARTED = (1 << 17), - - SNGSS7_M2UA_PRESENT = (1 << 18), - SNGSS7_M2UA_STARTED = (1 << 19), - SNGSS7_M2UA_EP_OPENED = (1 << 20), - SNGSS7_M2UA_INIT_ASSOC_DONE = (1 << 21), - - SNGSS7_NIF_PRESENT = (1 << 22), - SNGSS7_NIF_STARTED = (1 << 23), - -} sng_task_flag_t; -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -extern ftdm_sngss7_data_t g_ftdm_sngss7_data; -extern ftdm_sngss7_opr_mode g_ftdm_operating_mode; -extern sng_ssf_type_t sng_ssf_type_map[]; -extern sng_switch_type_t sng_switch_type_map[]; -extern sng_link_type_t sng_link_type_map[]; -extern sng_mtp2_error_type_t sng_mtp2_error_type_map[]; -extern sng_cic_cntrl_type_t sng_cic_cntrl_type_map[]; -extern uint32_t sngss7_id; -extern ftdm_sched_t *sngss7_sched; -extern int cmbLinkSetId; -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -/* in ftmod_sangoma_ss7_main.c */ -ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); - -/* in ftmod_sangoma_ss7_logger.c */ -void handle_sng_log(uint8_t level, char *fmt,...); -void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta); -void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); -void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta); -void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta); -void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta); -void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta); -void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta); -void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta); -void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta); -void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta); - -/* in ftmod_sangoma_ss7_relay.c */ -ftdm_status_t handle_relay_connect(RyMngmt *sta); -ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta); -ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta); - -/* in ftmod_sangoma_ss7_cfg.c */ -int ft_to_sngss7_cfg_all(void); -int ftmod_ss7_mtp1_gen_config(void); -int ftmod_ss7_mtp2_gen_config(void); -int ftmod_ss7_mtp3_gen_config(void); -int ftmod_ss7_isup_gen_config(void); -int ftmod_ss7_cc_gen_config(void); -int ftmod_ss7_mtp1_psap_config(int id); -int ftmod_ss7_mtp2_dlsap_config(int id); -int ftmod_ss7_mtp3_dlsap_config(int id); -int ftmod_ss7_mtp3_nsap_config(int id); -int ftmod_ss7_mtp3_linkset_config(int id); -int ftmod_ss7_mtp3_route_config(int id); -int ftmod_ss7_isup_nsap_config(int id); -int ftmod_ss7_isup_intf_config(int id); -int ftmod_ss7_isup_ckt_config(int id); -int ftmod_ss7_isup_isap_config(int id); -int ftmod_ss7_cc_isap_config(int id); - -/* in ftmod_sangoma_ss7_cntrl.c */ -int ft_to_sngss7_activate_all(void); - -int ftmod_ss7_inhibit_mtp3link(uint32_t id); -int ftmod_ss7_uninhibit_mtp3link(uint32_t id); -int ftmod_ss7_bind_mtp3link(uint32_t id); -int ftmod_ss7_unbind_mtp3link(uint32_t id); -int ftmod_ss7_activate_mtp3link(uint32_t id); -int ftmod_ss7_deactivate_mtp3link(uint32_t id); -int ftmod_ss7_deactivate2_mtp3link(uint32_t id); -int ftmod_ss7_activate_mtplinkSet(uint32_t id); -int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); -int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); -int ftmod_ss7_lpo_mtp3link(uint32_t id); -int ftmod_ss7_lpr_mtp3link(uint32_t id); - -int ftmod_ss7_shutdown_isup(void); -int ftmod_ss7_shutdown_mtp3(void); -int ftmod_ss7_shutdown_mtp2(void); -int ftmod_ss7_shutdown_relay(void); -int ftmod_ss7_disable_relay_channel(uint32_t chanId); - -int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId); -int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId); - -int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId); - -#define ftmod_ss7_block_isup_ckt(x) __ftmod_ss7_block_isup_ckt(x,FTDM_TRUE) -#define ftmod_ss7_block_isup_ckt_nowait(x) __ftmod_ss7_block_isup_ckt(x,FTDM_FALSE) -int __ftmod_ss7_block_isup_ckt(uint32_t cktId, ftdm_bool_t wait); -int ftmod_ss7_unblock_isup_ckt(uint32_t cktId); - - -/* in ftmod_sangoma_ss7_sta.c */ -int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm); -int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm); -int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm); -int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); -int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status); -int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm); -int ftmod_ss7_isup_ckt_sta(uint32_t id, unsigned char *state); - - -/* in ftmod_sangoma_ss7_out.c */ -void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_cpg (ftdm_channel_t *ftdmchan); -void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_rsc(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_rsca(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_blo(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_bla(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_grs(ftdm_channel_t *ftdmchan); -void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_inr(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan, SiCnStEvnt *inr); - - - -/* in ftmod_sangoma_ss7_in.c */ -void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); -void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); -void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); -void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); -void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); -void sngss7_ssp_sta_cfm(uint32_t infId); - -ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt); -ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt); -ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt); - -/* in ftmod_sangoma_ss7_handle.c */ -ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); -ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); -ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); -ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); -ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt); -ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -/* in ftmod_sangoma_ss7_xml.c */ -int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span); - -/* in ftmod_sangoma_ss7_cli.c */ -ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data); - -/* in ftmod_sangoma_ss7_support.c */ -ftdm_status_t copy_cgPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum); -ftdm_status_t copy_cgPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum); -ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum); -ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum); -ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum); -ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum); -ftdm_status_t copy_redirgInfo_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo); -ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo); -ftdm_status_t copy_ocn_to_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum); -ftdm_status_t copy_ocn_from_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum); - -ftdm_status_t copy_access_transport_from_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt); -ftdm_status_t copy_access_transport_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt); -ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum); -ftdm_status_t copy_locPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum); -ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb); -ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb); -ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat); -ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat); -ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt); -ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd); -ftdm_status_t copy_fwdCallInd_hex_from_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd); -ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd); -ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq); -ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA); -ftdm_status_t copy_NatureOfConnection_from_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd ); -ftdm_status_t copy_NatureOfConnection_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd); - -ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven); -ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven); -ftdm_status_t copy_tknStr_to_sngss7(char* str, TknStr *tknStr, TknU8 *oddEven); - -int check_for_state_change(ftdm_channel_t *ftdmchan); -int check_for_reset(sngss7_chan_data_t *sngss7_info); -ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan); -unsigned long get_unique_id(void); - -ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan); -ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan); -ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); -ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); - -ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan); - -ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info); -ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info); -ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info); -ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info); -ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info); -ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info); -ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info); - -ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); -ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); - -int find_mtp2_error_type_in_map(const char *err_type); -int find_link_type_in_map(const char *linkType); -int find_switch_type_in_map(const char *switchType); -int find_ssf_type_in_map(const char *ssfType); -int find_cic_cntrl_in_map(const char *cntrlType); - -ftdm_status_t check_status_of_all_isup_intf(void); -ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan); - -void sngss7_send_signal(sngss7_chan_data_t *sngss7_info, ftdm_signal_event_t event_id); -void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_status_t status); -ftdm_status_t sngss7_add_var(sngss7_chan_data_t *ss7_info, const char* var, const char* val); -ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data, ftdm_size_t data_len); - -/* in ftmod_sangoma_ss7_timers.c */ -void handle_isup_t35(void *userdata); -void handle_isup_t10(void *userdata); -void handle_isup_t39(void *userdata); - - -/******************************************************************************/ - -/* MACROS *********************************************************************/ -#define SS7_STATE_CHANGE(ftdmchan, new_state) \ -if (ftdmchan->state == new_state) { \ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); \ -} else { \ - ftdm_set_state(ftdmchan, new_state); \ -} - -#define SS7_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a , ##__VA_ARGS__ ); -#define SS7_INFO(a,...) ftdm_log(FTDM_LOG_INFO,a , ##__VA_ARGS__ ); -#define SS7_WARN(a,...) ftdm_log(FTDM_LOG_WARNING,a , ##__VA_ARGS__ ); -#define SS7_ERROR(a,...) ftdm_log(FTDM_LOG_ERROR,a , ##__VA_ARGS__ ); -#define SS7_CRITICAL(a,...) ftdm_log(FTDM_LOG_CRIT,a , ##__VA_ARGS__ ); - -#define SS7_DEBUG_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_DEBUG, msg , ##args) -#define SS7_INFO_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_INFO, msg , ##args) -#define SS7_WARN_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_WARNING, msg , ##args) -#define SS7_ERROR_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_ERROR, msg , ##args) -#define SS7_CRIT_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_CRIT, msg , ##args) - -#ifdef SS7_CODE_DEVEL -#define SS7_DEVEL_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a,##__VA_ARGS__ ); -#else -#define SS7_DEVEL_DEBUG(a,...) -#endif - -#define SS7_FUNC_TRACE_ENTER(a) if (g_ftdm_sngss7_data.function_trace) { \ - switch (g_ftdm_sngss7_data.function_trace_level) { \ - case 0: \ - ftdm_log(FTDM_LOG_EMERG,"Entering %s\n", a); \ - break; \ - case 1: \ - ftdm_log(FTDM_LOG_ALERT,"Entering %s\n", a); \ - break; \ - case 2: \ - ftdm_log(FTDM_LOG_CRIT,"Entering %s\n", a); \ - break; \ - case 3: \ - ftdm_log(FTDM_LOG_ERROR,"Entering %s\n", a); \ - break; \ - case 4: \ - ftdm_log(FTDM_LOG_WARNING,"Entering %s\n", a); \ - break; \ - case 5: \ - ftdm_log(FTDM_LOG_NOTICE,"Entering %s\n", a); \ - break; \ - case 6: \ - ftdm_log(FTDM_LOG_INFO,"Entering %s\n", a); \ - break; \ - case 7: \ - ftdm_log(FTDM_LOG_DEBUG,"Entering %s\n", a); \ - break; \ - default: \ - ftdm_log(FTDM_LOG_INFO,"Entering %s\n", a); \ - break; \ - } /* switch (g_ftdm_sngss7_data.function_trace_level) */ \ - } /* if(g_ftdm_sngss7_data.function_trace) */ - -#define SS7_FUNC_TRACE_EXIT(a) if (g_ftdm_sngss7_data.function_trace) { \ - switch (g_ftdm_sngss7_data.function_trace_level) { \ - case 0: \ - ftdm_log(FTDM_LOG_EMERG,"Exiting %s\n", a); \ - break; \ - case 1: \ - ftdm_log(FTDM_LOG_ALERT,"Exiting %s\n", a); \ - break; \ - case 2: \ - ftdm_log(FTDM_LOG_CRIT,"Exiting %s\n", a); \ - break; \ - case 3: \ - ftdm_log(FTDM_LOG_ERROR,"Exiting %s\n", a); \ - break; \ - case 4: \ - ftdm_log(FTDM_LOG_WARNING,"Exiting %s\n", a); \ - break; \ - case 5: \ - ftdm_log(FTDM_LOG_NOTICE,"Exiting %s\n", a); \ - break; \ - case 6: \ - ftdm_log(FTDM_LOG_INFO,"Exiting %s\n", a); \ - break; \ - case 7: \ - ftdm_log(FTDM_LOG_DEBUG,"Exiting %s\n", a); \ - break; \ - default: \ - ftdm_log(FTDM_LOG_INFO,"Exiting %s\n", a); \ - break; \ - } /* switch (g_ftdm_sngss7_data.function_trace_level) */ \ - } /* if(g_ftdm_sngss7_data.function_trace) */ - -#define SS7_MSG_TRACE(fchan, sngss7info ,msg) if (g_ftdm_sngss7_data.message_trace) { \ - switch (g_ftdm_sngss7_data.message_trace_level) { \ - case 0: \ - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - case 1: \ - ftdm_log_chan(fchan, FTDM_LOG_ALERT, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - case 2: \ - ftdm_log_chan(fchan, FTDM_LOG_CRIT, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - case 3: \ - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - case 4: \ - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - case 5: \ - ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - case 6: \ - ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - case 7: \ - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - default: \ - ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \ - sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \ - break; \ - } /* switch (g_ftdm_sngss7_data.message_trace_level) */ \ - } /* if(g_ftdm_sngss7_data.message_trace) */ - -#define sngss7_test_flag(obj, flag) ((obj)->flags & flag) -#define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag)) -#define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag)) - -#define sngss7_test_ckt_flag(obj, flag) ((obj)->ckt_flags & flag) -#define sngss7_clear_ckt_flag(obj, flag) ((obj)->ckt_flags &= ~(flag)) -#define sngss7_set_ckt_flag(obj, flag) ((obj)->ckt_flags |= (flag)) - -#define sngss7_test_ckt_blk_flag(obj, flag) ((obj)->blk_flags & flag) -#define sngss7_clear_ckt_blk_flag(obj, flag) ((obj)->blk_flags &= ~(flag)) -#define sngss7_set_ckt_blk_flag(obj, flag) ((obj)->blk_flags |= (flag)) - -#define sngss7_test_options(obj, option) ((obj)->options & option) -#define sngss7_clear_options(obj, option) ((obj)->options &= ~(option)) -#define sngss7_set_options(obj, option) ((obj)->options |= (option)) - -#define sngss7_tx_block_status_clear(obj) (!sngss7_test_ckt_blk_flag(obj, (FLAG_CKT_MN_BLOCK_TX | \ - FLAG_CKT_MN_BLOCK_TX_DN | \ - FLAG_GRP_MN_BLOCK_TX | \ - FLAG_GRP_MN_BLOCK_TX_DN | \ - FLAG_GRP_HW_BLOCK_TX | \ - FLAG_GRP_HW_BLOCK_TX_DN | \ - FLAG_GRP_HW_UNBLK_TX | \ - FLAG_CKT_MN_UNBLK_TX ))) - -#define sngss7_block_status_clear(obj) (obj->blk_flags == 0) - -#define sngss7_reset_status_clear(obj) (!sngss7_test_ckt_flag(obj, (FLAG_RESET_TX | \ - FLAG_RESET_RX | \ - FLAG_GRP_RESET_TX | \ - FLAG_GRP_RESET_RX ))) - -#define sngss7_tx_reset_sent(obj) ((sngss7_test_ckt_flag(obj, (FLAG_RESET_TX)) && \ - sngss7_test_ckt_flag(obj, (FLAG_RESET_SENT))) || \ - (sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_TX)) && \ - sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_SENT)))) - -#define sngss7_tx_reset_status_pending(obj) (sngss7_test_ckt_flag(obj, (FLAG_RESET_TX)) || sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_TX))) - -#define sngss7_channel_status_clear(obj) ((sngss7_block_status_clear(obj)) && \ - (sngss7_reset_status_clear(obj)) && \ - (!sngss7_test_ckt_flag((obj),FLAG_INFID_PAUSED))) - -#define sngss7_tx_reset_restart(obj) do { clear_tx_grs_flags((obj)); \ - clear_tx_grs_data((obj)); \ - clear_tx_rsc_flags((obj)); \ - sngss7_set_ckt_flag((obj), (FLAG_RESET_TX)); \ - } while (0); - - - -#ifdef SMG_RELAY_DBG -#define SS7_RELAY_DBG(a,...) printf(a"\n", ##__VA_ARGS__) -#define SS7_RELAY_DBG_FUN(a) printf(#a"\n") -#else -#define SS7_RELAY_DBG(a, ...) -#define SS7_RELAY_DBG_FUN(a) -#endif -/******************************************************************************/ - -/******************************************************************************/ -#endif /* __FTMOD_SNG_SS7_H__ */ -/******************************************************************************/ - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c deleted file mode 100644 index 7c567ab6ea..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ /dev/null @@ -1,1052 +0,0 @@ -/* - * Copyright (c) 2009, Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -#define SNGSS7_EVNTINFO_IND_INBAND_AVAIL 0x03 -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ - -/* FUNCTIONS ******************************************************************/ -void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) -{ - const char *var = NULL; - SiConEvnt iam; - ftdm_bool_t native_going_up = FTDM_FALSE; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; - sngss7_event_data_t *event_clone = NULL; - - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_info->suInstId = get_unique_id (); - sngss7_info->spInstId = 0; - sngss7_info->spId = 1; - - memset (&iam, 0x0, sizeof (iam)); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { - ftdm_span_t *peer_span = NULL; - ftdm_channel_t *peer_chan = NULL; - sngss7_chan_data_t *peer_info = NULL; - - var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer"); - ftdm_get_channel_from_string(var, &peer_span, &peer_chan); - if (!peer_chan) { - SS7_ERROR_CHAN(ftdmchan, "Failed to find sigbridge peer from string '%s'\n", var); - } else { - if (peer_span->signal_type != FTDM_SIGTYPE_SS7) { - SS7_ERROR_CHAN(ftdmchan, "Peer channel '%s' has different signaling type %d'\n", - var, peer_span->signal_type); - } else { - peer_info = peer_chan->call_data; - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n", - sngss7_info->circuit->cic, peer_info->circuit->cic); - - /* retrieve only first message from the others guys queue (must be IAM) */ - event_clone = ftdm_queue_dequeue(peer_info->event_queue); - - /* make each one of us aware of the native bridge */ - peer_info->peer_data = sngss7_info; - sngss7_info->peer_data = peer_info; - - /* Go to up until release comes, note that state processing is done different and much simpler when there is a peer, - We can't go to UP state right away yet though, so do not set the state to UP here, wait until the end of this function - because moving from one state to another causes the ftdmchan->usrmsg structure to be wiped - and we still need those variables for further IAM processing */ - native_going_up = FTDM_TRUE; - } - } - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) { - if (!event_clone) { - SS7_ERROR_CHAN(ftdmchan, "No IAM event clone in peer queue!%s\n", ""); - } else if (event_clone->event_id != SNGSS7_CON_IND_EVENT) { - /* first message in the queue should ALWAYS be an IAM */ - SS7_ERROR_CHAN(ftdmchan, "Invalid initial peer message type '%d'\n", event_clone->event_id); - } else { - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged, dialing %s)\n", sngss7_info->circuit->cic, caller_data->dnis.digits); - - /* copy original incoming IAM */ - memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam)); - - /* Change DNIS to whatever was specified, do not change NADI or anything else! */ - copy_tknStr_to_sngss7(caller_data->dnis.digits, &iam.cdPtyNum.addrSig, &iam.cdPtyNum.oddEven); - - /* SPIROU certification hack - If the IAM already contain RDINF, just increment the count and set the RDNIS digits - otherwise, honor RDNIS and RDINF stuff coming from the user */ - if (iam.redirInfo.eh.pres == PRSNT_NODEF) { - const char *val = NULL; - if (iam.redirInfo.redirCnt.pres) { - iam.redirInfo.redirCnt.val++; - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count incremented = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val); - } - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits"); - if (!ftdm_strlen_zero(val)) { - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), found user supplied RDNIS digits = %s\n", sngss7_info->circuit->cic, val); - copy_tknStr_to_sngss7((char*)val, &iam.redirgNum.addrSig, &iam.redirgNum.oddEven); - } else { - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), not found user supplied RDNIS digits\n", sngss7_info->circuit->cic); - } - } else { - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info not present, attempting to copy user supplied values\n", sngss7_info->circuit->cic); - /* Redirecting Number */ - copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); - - /* Redirecting Information */ - copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo); - } - - if (iam.origCdNum.eh.pres != PRSNT_NODEF) { - /* Original Called Number */ - copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum); - } - copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt); - } - } else if (sngss7_info->circuit->transparent_iam && - sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) { - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic); - - /* Called Number information */ - copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum); - - /* Redirecting Number */ - copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); - - /* Redirecting Information */ - copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo); - - /* Location Number information */ - copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1); - - /* Forward Call Indicators */ - copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd); - - /* Original Called Number */ - copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum); - - copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt); - - copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd); - } else { - /* Nature of Connection Indicators */ - copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd); - - /* Forward Call Indicators */ - copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd); - - /* Transmission medium requirements */ - copy_txMedReq_to_sngss7(ftdmchan, &iam.txMedReq); - - if (SNGSS7_SWITCHTYPE_ANSI(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType)) { - /* User Service Info A */ - copy_usrServInfoA_to_sngss7(ftdmchan, &iam.usrServInfoA); - } - - /* Called Number information */ - copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum); - - /* Calling Number information */ - copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum); - - /* Location Number information */ - copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1); - - /* Generic Number information */ - copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb); - - /* Calling Party's Category */ - copy_cgPtyCat_to_sngss7(ftdmchan, &iam.cgPtyCat); - - /* Redirecting Number */ - copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); - - /* Redirecting Information */ - copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo); - - /* Original Called Number */ - copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum); - - /* Access Transport - old implementation, taking from channel variable of ss7_clg_subaddr */ - copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt); - - /* Access Transport - taking from channel variable of ss7_access_transport_urlenc. - This will overwirte the IE value set be above old implementation. - */ - copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt); - - copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d), loc = %s (NADI=%d)\n", - sngss7_info->circuit->cic, - ftdmchan->caller_data.cid_num.digits, - iam.cgPtyNum.natAddrInd.val, - ftdmchan->caller_data.dnis.digits, - iam.cdPtyNum.natAddrInd.val, - ftdmchan->caller_data.loc.digits, - iam.cgPtyNum1.natAddrInd.val); - } - - sng_cc_con_request (sngss7_info->spId, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &iam, - 0); - - if (native_going_up) { - /* - Note that this function (ft_to_sngss7_iam) is run within the main SS7 processing loop in - response to the DIALING state handler, we can set the state to UP here and that will - implicitly complete the DIALING state, but we *MUST* also advance the state handler - right away for a native bridge, otherwise, the processing state function (ftdm_sangoma_ss7_process_state_change) - will complete the state without having executed the handler for FTDM_CHANNEL_STATE_UP, and we won't notify - the user sending FTDM_SIGEVENT_UP which can cause the application to misbehave (ie, no audio) */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - ftdm_channel_advance_states(ftdmchan); - } - - ftdm_safe_free(event_clone); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan, SiCnStEvnt *inr) -{ - SiCnStEvnt evnt; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - memset (&evnt, 0x0, sizeof (evnt)); - - evnt.infoInd.eh.pres = PRSNT_NODEF; - evnt.infoInd.cgPtyAddrRespInd.pres = PRSNT_NODEF; - evnt.infoInd.cgPtyCatRespInd.pres = PRSNT_NODEF; - - evnt.infoInd.chrgInfoRespInd.pres = PRSNT_NODEF; - evnt.infoInd.chrgInfoRespInd.val = 0; - evnt.infoInd.solInfoInd.pres = PRSNT_NODEF; - evnt.infoInd.solInfoInd.val = 0; - evnt.infoInd.holdProvInd.pres = PRSNT_NODEF; - evnt.infoInd.holdProvInd.val = 0; - evnt.infoInd.spare.pres = PRSNT_NODEF; - evnt.infoInd.spare.val = 0; - - if (inr->infoReqInd.eh.pres == PRSNT_NODEF) { - if ((inr->infoReqInd.holdingInd.pres == PRSNT_NODEF) && (inr->infoReqInd.holdingInd.val == HOLD_REQ)) { - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting holding information. Holding is not supported in INF.\n", sngss7_info->circuit->cic); - } - if ((inr->infoReqInd.chrgInfoReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.chrgInfoReqInd.val == CHRGINFO_REQ)) { - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting charging information. Charging is not supported in INF.\n", sngss7_info->circuit->cic); - } - if ((inr->infoReqInd.malCaIdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.malCaIdReqInd.val == CHRGINFO_REQ)) { - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting malicious call id. Malicious call id is not supported in INF.\n", sngss7_info->circuit->cic); - } - - if ((inr->infoReqInd.cgPtyAdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyAdReqInd.val == CGPRTYADDREQ_REQ)) { - evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_INCL; - copy_cgPtyNum_to_sngss7 (ftdmchan, &evnt.cgPtyNum); - } else { - evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_NOTINCL; - } - - if ((inr->infoReqInd.cgPtyCatReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyCatReqInd.val == CGPRTYCATREQ_REQ)) { - evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_INCL; - copy_cgPtyCat_to_sngss7 (ftdmchan, &evnt.cgPtyCat); - } else { - evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_NOTINCL; - } - } - else { - SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR with no information request. Sending back default INF.\n", sngss7_info->circuit->cic); - } - - sng_cc_inf(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &evnt, - INFORMATION); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INF\n", sngss7_info->circuit->cic); - -} - -void ft_to_sngss7_inr(ftdm_channel_t *ftdmchan) -{ - SiCnStEvnt evnt; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - memset (&evnt, 0x0, sizeof (evnt)); - - evnt.infoReqInd.eh.pres = PRSNT_NODEF; - evnt.infoReqInd.cgPtyAdReqInd.pres = PRSNT_NODEF; - evnt.infoReqInd.cgPtyAdReqInd.val=CGPRTYADDREQ_REQ; - - evnt.infoReqInd.holdingInd.pres = PRSNT_NODEF; - evnt.infoReqInd.holdingInd.val = HOLD_REQ; - - evnt.infoReqInd.cgPtyCatReqInd.pres = PRSNT_NODEF; - evnt.infoReqInd.cgPtyCatReqInd.val = CGPRTYCATREQ_REQ; - - evnt.infoReqInd.chrgInfoReqInd.pres = PRSNT_NODEF; - evnt.infoReqInd.chrgInfoReqInd.val = CHRGINFO_REQ; - - evnt.infoReqInd.malCaIdReqInd.pres = PRSNT_NODEF; - evnt.infoReqInd.malCaIdReqInd.val = MLBG_INFOREQ; - - sng_cc_inr(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &evnt, - INFORMATREQ); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INR\n", sngss7_info->circuit->cic); -} - -void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiCnStEvnt acm; - const char *backwardInd = NULL; - - memset (&acm, 0x0, sizeof (acm)); - - /* fill in the needed information for the ACM */ - acm.bckCallInd.eh.pres = PRSNT_NODEF; - acm.bckCallInd.chrgInd.pres = PRSNT_NODEF; - acm.bckCallInd.chrgInd.val = CHRG_CHRG; - acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF; - acm.bckCallInd.cadPtyStatInd.val = 0x01; - acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF; - acm.bckCallInd.cadPtyCatInd.val = CADCAT_ORDSUBS; - acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndMethInd.val = E2EMTH_NOMETH; - acm.bckCallInd.intInd.pres = PRSNT_NODEF; - acm.bckCallInd.intInd.val = INTIND_NOINTW; - acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO; - - acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED; - backwardInd = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "acm_bi_iup"); - if (!ftdm_strlen_zero(backwardInd)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied backward indicator ISDN user part indicator ACM, value \"%s\"\n", backwardInd); - if (atoi(backwardInd) != 0 ) { - acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED; - } - } - acm.bckCallInd.holdInd.pres = PRSNT_NODEF; - acm.bckCallInd.holdInd.val = HOLD_NOTREQD; - acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnAccInd.val = ISDNACC_NONISDN; - acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF; - switch (ftdmchan->caller_data.bearer_capability) { - /**********************************************************************/ - case (FTDM_BEARER_CAP_SPEECH): - acm.bckCallInd.echoCtrlDevInd.val = 0x1; - break; - /**********************************************************************/ - case (FTDM_BEARER_CAP_UNRESTRICTED): - acm.bckCallInd.echoCtrlDevInd.val = 0x0; - break; - /**********************************************************************/ - case (FTDM_BEARER_CAP_3_1KHZ_AUDIO): - acm.bckCallInd.echoCtrlDevInd.val = 0x1; - break; - /**********************************************************************/ - default: - SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " "); - acm.bckCallInd.echoCtrlDevInd.val = 0x1; - break; - /**********************************************************************/ - } /* switch (ftdmchan->caller_data.bearer_capability) */ - acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND; - - /* fill in any optional parameters */ - if (sngss7_test_options(&g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id], SNGSS7_ACM_OBCI_BITA)) { - SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].options); - acm.optBckCalInd.eh.pres = PRSNT_NODEF; - acm.optBckCalInd.inbndInfoInd.pres = PRSNT_NODEF; - acm.optBckCalInd.inbndInfoInd.val = 0x1; - acm.optBckCalInd.caFwdMayOcc.pres = PRSNT_DEF; - acm.optBckCalInd.simpleSegmInd.pres = PRSNT_DEF; - acm.optBckCalInd.mlppUserInd.pres = PRSNT_DEF; - acm.optBckCalInd.usrNetIneractInd.pres = PRSNT_DEF; - acm.optBckCalInd.netExcDelInd.pres = PRSNT_DEF; - } /* if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) */ - - /* send the ACM request to LibSngSS7 */ - sng_cc_con_status (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &acm, - ADDRCMPLT); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -void ft_to_sngss7_cpg (ftdm_channel_t *ftdmchan) -{ - SiCnStEvnt cpg; - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - - memset (&cpg, 0, sizeof (cpg)); - - cpg.evntInfo.eh.pres = PRSNT_NODEF; - - cpg.evntInfo.evntInd.pres = PRSNT_NODEF; - cpg.evntInfo.evntInd.val = SNGSS7_EVNTINFO_IND_INBAND_AVAIL; /* Event Indicator = In-band info is now available */ - - cpg.evntInfo.evntPresResInd.pres = PRSNT_NODEF; - cpg.evntInfo.evntPresResInd.val = 0; /* Event presentation restricted indicator = no indication */ - - /* send the CPG request to LibSngSS7 */ - sng_cc_con_status (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &cpg, PROGRESS); - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "[CIC:%d]Tx CPG\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} -void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiConEvnt anm; - - memset (&anm, 0x0, sizeof (anm)); - - /* send the ANM request to LibSngSS7 */ - sng_cc_con_response(1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &anm, - 5); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) -{ - const char *loc_ind = NULL; - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiRelEvnt rel; - - memset (&rel, 0x0, sizeof (rel)); - - rel.causeDgn.eh.pres = PRSNT_NODEF; - rel.causeDgn.location.pres = PRSNT_NODEF; - - loc_ind = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rel_loc"); - if (!ftdm_strlen_zero(loc_ind)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied location indicator in REL, value \"%s\"\n", loc_ind); - rel.causeDgn.location.val = atoi(loc_ind); - } else { - rel.causeDgn.location.val = 0x01; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied location indicator in REL, using 0x01\"%s\"\n", ""); - } - rel.causeDgn.cdeStand.pres = PRSNT_NODEF; - rel.causeDgn.cdeStand.val = 0x00; - rel.causeDgn.recommend.pres = NOTPRSNT; - rel.causeDgn.causeVal.pres = PRSNT_NODEF; - rel.causeDgn.causeVal.val = (uint8_t) ftdmchan->caller_data.hangup_cause; - rel.causeDgn.dgnVal.pres = NOTPRSNT; - - /* send the REL request to LibSngSS7 */ - sng_cc_rel_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &rel); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n", - sngss7_info->circuit->cic, - ftdmchan->caller_data.hangup_cause ); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiRelEvnt rlc; - - memset (&rlc, 0x0, sizeof (rlc)); - - /* send the RLC request to LibSngSS7 */ - sng_cc_rel_response (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - &rlc); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - sng_cc_sta_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - sngss7_info->globalFlg, - SIT_STA_CIRRESREQ, - NULL); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - sng_cc_sta_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - sngss7_info->globalFlg, - SIT_STA_CIRRESRSP, - NULL); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - sng_cc_sta_request (1, - 0, - 0, - sngss7_info->circuit->id, - sngss7_info->globalFlg, - SIT_STA_CIRBLOREQ, - NULL); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - sng_cc_sta_request (1, - 0, - 0, - sngss7_info->circuit->id, - sngss7_info->globalFlg, - SIT_STA_CIRBLORSP, - NULL); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void -ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - sng_cc_sta_request (1, - 0, - 0, - sngss7_info->circuit->id, - sngss7_info->globalFlg, - SIT_STA_CIRUBLREQ, - NULL); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - sng_cc_sta_request (1, - 0, - 0, - sngss7_info->circuit->id, - sngss7_info->globalFlg, - SIT_STA_CIRUBLRSP, - NULL); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - sng_cc_sta_request (1, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, - sngss7_info->globalFlg, - SIT_STA_LOOPBACKACK, - NULL); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); -return; -} - -/******************************************************************************/ -void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiStaEvnt gra; - - /* clean out the gra struct */ - memset (&gra, 0x0, sizeof (gra)); - - gra.rangStat.eh.pres = PRSNT_NODEF; - - /* fill in the range */ - gra.rangStat.range.pres = PRSNT_NODEF; - gra.rangStat.range.val = sngss7_info->rx_grs.range; - - /* fill in the status */ - gra.rangStat.status.pres = PRSNT_NODEF; - gra.rangStat.status.len = ((sngss7_info->rx_grs.range + 1) >> 3) + (((sngss7_info->rx_grs.range + 1) & 0x07) ? 1 : 0); - - /* the status field should be 1 if blocked for maintenace reasons - * and 0 is not blocked....since we memset the struct nothing to do - */ - - /* send the GRA to LibSng-SS7 */ - sng_cc_sta_request (1, - 0, - 0, - sngss7_info->rx_grs.circuit, - 0, - SIT_STA_GRSRSP, - &gra); - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Tx GRA (%d:%d)\n", - sngss7_info->circuit->cic, - sngss7_info->circuit->cic, - (sngss7_info->circuit->cic + sngss7_info->rx_grs.range)); - - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_grs (ftdm_channel_t *fchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_chan_data_t *cinfo = fchan->call_data; - - SiStaEvnt grs; - - ftdm_assert(sngss7_test_ckt_flag(cinfo, FLAG_GRP_RESET_TX) && - !sngss7_test_ckt_flag(cinfo, FLAG_GRP_RESET_SENT), "Incorrect flags\n"); - - memset (&grs, 0x0, sizeof(grs)); - grs.rangStat.eh.pres = PRSNT_NODEF; - grs.rangStat.range.pres = PRSNT_NODEF; - grs.rangStat.range.val = cinfo->tx_grs.range; - - sng_cc_sta_request (1, - 0, - 0, - cinfo->tx_grs.circuit, - 0, - SIT_STA_GRSREQ, - &grs); - - SS7_INFO_CHAN(fchan, "[CIC:%d]Tx GRS (%d:%d)\n", - cinfo->circuit->cic, - cinfo->circuit->cic, - (cinfo->circuit->cic + cinfo->tx_grs.range)); - - sngss7_set_ckt_flag(cinfo, FLAG_GRP_RESET_SENT); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); -} - -/******************************************************************************/ -void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - int x = 0; - - SiStaEvnt cgba; - - memset (&cgba, 0x0, sizeof(cgba)); - - /* fill in the circuit group supervisory message */ - cgba.cgsmti.eh.pres = PRSNT_NODEF; - cgba.cgsmti.typeInd.pres = PRSNT_NODEF; - cgba.cgsmti.typeInd.val = sngss7_span->rx_cgb.type; - - cgba.rangStat.eh.pres = PRSNT_NODEF; - /* fill in the range */ - cgba.rangStat.range.pres = PRSNT_NODEF; - cgba.rangStat.range.val = sngss7_span->rx_cgb.range; - /* fill in the status */ - cgba.rangStat.status.pres = PRSNT_NODEF; - cgba.rangStat.status.len = ((sngss7_span->rx_cgb.range + 1) >> 3) + (((sngss7_span->rx_cgb.range + 1) & 0x07) ? 1 : 0); - for(x = 0; x < cgba.rangStat.status.len; x++){ - cgba.rangStat.status.val[x] = sngss7_span->rx_cgb.status[x]; - } - - sng_cc_sta_request (1, - 0, - 0, - sngss7_span->rx_cgb.circuit, - 0, - SIT_STA_CGBRSP, - &cgba); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGBA (%d:%d)\n", - sngss7_info->circuit->cic, - sngss7_info->circuit->cic, - (sngss7_info->circuit->cic + sngss7_span->rx_cgb.range)); - - /* clean out the saved data */ - memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t)); - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - int x = 0; - - SiStaEvnt cgua; - - memset (&cgua, 0x0, sizeof(cgua)); - - /* fill in the circuit group supervisory message */ - cgua.cgsmti.eh.pres = PRSNT_NODEF; - cgua.cgsmti.typeInd.pres = PRSNT_NODEF; - cgua.cgsmti.typeInd.val = sngss7_span->rx_cgu.type; - - cgua.rangStat.eh.pres = PRSNT_NODEF; - /* fill in the range */ - cgua.rangStat.range.pres = PRSNT_NODEF; - cgua.rangStat.range.val = sngss7_span->rx_cgu.range; - /* fill in the status */ - cgua.rangStat.status.pres = PRSNT_NODEF; - cgua.rangStat.status.len = ((sngss7_span->rx_cgu.range + 1) >> 3) + (((sngss7_span->rx_cgu.range + 1) & 0x07) ? 1 : 0); - for(x = 0; x < cgua.rangStat.status.len; x++){ - cgua.rangStat.status.val[x] = sngss7_span->rx_cgu.status[x]; - } - - sng_cc_sta_request (1, - 0, - 0, - sngss7_span->rx_cgu.circuit, - 0, - SIT_STA_CGURSP, - &cgua); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGUA (%d:%d)\n", - sngss7_info->circuit->cic, - sngss7_info->circuit->cic, - (sngss7_info->circuit->cic + sngss7_span->rx_cgu.range)); - - /* clean out the saved data */ - memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t)); - - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiStaEvnt cgb; - int x = 0; - - - memset (&cgb, 0x0, sizeof(cgb)); - - /* fill in the circuit group supervisory message */ - cgb.cgsmti.eh.pres = PRSNT_NODEF; - cgb.cgsmti.typeInd.pres = PRSNT_NODEF; - cgb.cgsmti.typeInd.val = sngss7_span->tx_cgb.type; - - /* fill in the range */ - cgb.rangStat.eh.pres = PRSNT_NODEF; - cgb.rangStat.range.pres = PRSNT_NODEF; - cgb.rangStat.range.val = sngss7_span->tx_cgb.range; - - /* fill in the status */ - cgb.rangStat.status.pres = PRSNT_NODEF; - cgb.rangStat.status.len = ((sngss7_span->tx_cgb.range + 1) >> 3) + (((sngss7_span->tx_cgb.range + 1) & 0x07) ? 1 : 0); - for(x = 0; x < cgb.rangStat.status.len; x++){ - cgb.rangStat.status.val[x] = sngss7_span->tx_cgb.status[x]; - } - - sng_cc_sta_request (1, - 0, - 0, - sngss7_span->tx_cgb.circuit, - 0, - SIT_STA_CGBREQ, - &cgb); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGB (%d:%d)\n", - sngss7_info->circuit->cic, - sngss7_info->circuit->cic, - (sngss7_info->circuit->cic + sngss7_span->tx_cgb.range)); - - /* clean out the saved data */ - memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t)); - - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan) -{ - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiStaEvnt cgu; - int x = 0; - - - memset (&cgu, 0x0, sizeof(cgu)); - - /* fill in the circuit group supervisory message */ - cgu.cgsmti.eh.pres = PRSNT_NODEF; - cgu.cgsmti.typeInd.pres = PRSNT_NODEF; - cgu.cgsmti.typeInd.val = sngss7_span->tx_cgu.type; - - /* fill in the range */ - cgu.rangStat.eh.pres = PRSNT_NODEF; - cgu.rangStat.range.pres = PRSNT_NODEF; - cgu.rangStat.range.val = sngss7_span->tx_cgu.range; - - /* fill in the status */ - cgu.rangStat.status.pres = PRSNT_NODEF; - cgu.rangStat.status.len = ((sngss7_span->tx_cgu.range + 1) >> 3) + (((sngss7_span->tx_cgu.range + 1) & 0x07) ? 1 : 0); - for(x = 0; x < cgu.rangStat.status.len; x++){ - cgu.rangStat.status.val[x] = sngss7_span->tx_cgu.status[x]; - } - - sng_cc_sta_request (1, - 0, - 0, - sngss7_span->tx_cgu.circuit, - 0, - SIT_STA_CGUREQ, - &cgu); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGU (%d:%d)\n", - sngss7_info->circuit->cic, - sngss7_info->circuit->cic, - (sngss7_info->circuit->cic + sngss7_span->tx_cgu.range)); - - /* clean out the saved data */ - memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t)); - - - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/* French SPIROU send Charge Unit */ -/* No one calls this function yet, but it has been implemented to complement TXA messages */ -void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan) -{ -#ifndef SANGOMA_SPIROU - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "ITX message not supported!, please update your libsng_ss7\n"); -#else - const char* var = NULL; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SiCnStEvnt itx; - - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - memset (&itx, 0x0, sizeof (itx)); - - itx.msgNum.eh.pres = PRSNT_NODEF; - itx.msgNum.msgNum.pres = PRSNT_NODEF; - var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_msg_num"); - if (!ftdm_strlen_zero(var)) { - itx.msgNum.msgNum.val = atoi(var); - } else { - itx.msgNum.msgNum.val = 0x1; - } - - itx.chargUnitNum.eh.pres = PRSNT_NODEF; - itx.chargUnitNum.chargUnitNum.pres = PRSNT_NODEF; - var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_charge_unit"); - if (!ftdm_strlen_zero(var)) { - itx.chargUnitNum.chargUnitNum.val = atoi(var); - } else { - itx.chargUnitNum.chargUnitNum.val = 0x1; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "ITX Charging Unit:%d Msg Num:%d\n", itx.chargUnitNum.chargUnitNum.val, itx.msgNum.msgNum.val); - sng_cc_con_status (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &itx, CHARGE_UNIT); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ITX\n", sngss7_info->circuit->cic); -#endif - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/* French SPIROU send Charging Acknowledgement */ -void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan) -{ -#ifndef SANGOMA_SPIROU - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "TXA message not supported!, please update your libsng_ss7\n"); -#else - SiCnStEvnt txa; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__); - - memset (&txa, 0x0, sizeof(txa)); - - sng_cc_con_status(1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &txa, CHARGE_ACK); - - SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx TXA\n", sngss7_info->circuit->cic); -#endif - SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__); - return; -} - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c deleted file mode 100644 index 8389e56950..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2009|Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms|with or without - * modification|are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice|this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice|this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT - * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, - * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ - -/*static ftdm_status_t enable_all_ckts_for_relay(void);*/ -static ftdm_status_t reconfig_all_ckts_for_relay(void); -static ftdm_status_t disable_all_ckts_for_relay(void); -static ftdm_status_t block_all_ckts_for_relay(uint32_t procId); -/* static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId); */ -static ftdm_status_t disable_all_sigs_for_relay(uint32_t procId); -static ftdm_status_t disble_all_mtp2_sigs_for_relay(void); -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -ftdm_status_t handle_relay_connect(RyMngmt *sta) -{ - sng_relay_t *sng_relay = &g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id]; - - if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) { - /* SS7_INFO("Relay Channel %d initial connection UP\n", sng_relay->id); */ - sngss7_set_flag(sng_relay, SNGSS7_RELAY_INIT); - } - - SS7_INFO("Relay Channel %d connection UP\n", sng_relay->id); - if (sng_relay->type == LRY_CT_TCP_CLIENT) { - if (reconfig_all_ckts_for_relay()) { - SS7_ERROR("Failed to reconfigure ISUP Ckts!\n"); - /* we're done....this is very bad! */ - } - return FTDM_SUCCESS; - } else if (sng_relay->type == LRY_CT_TCP_SERVER) { - ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id); - /* unbloock the ckts on the client system */ - return FTDM_SUCCESS; - } - return FTDM_FAIL; -} - -/******************************************************************************/ -ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta) -{ - SS7_DEBUG("SS7 relay disconnect on error\n"); - - /* check which procId is in error, if it is 1, disable the ckts */ - if (sta->t.usta.s.ryErrUsta.errPid == 1 ) { - /* we've lost the server, bring the sig status down on all ckts */ - disable_all_ckts_for_relay(); - - /* we've lost the server, bring down the mtp2 links */ - disble_all_mtp2_sigs_for_relay(); - } - - /* check if the channel is a server, means we just lost a MGW */ - if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryErrUsta.errPid].type == LRY_CT_TCP_SERVER) { - /* we've lost the client, bring down all the ckts for this procId */ - block_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid); - - /* we've lost the client, bring down all mtp3 links for this procId */ - disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid); - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta) -{ - - SS7_DEBUG("SS7 relay disconnect on down\n"); - - /* check if the channel is a server, means we just lost a MGW */ - if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type == LRY_CT_TCP_SERVER) { - block_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id); - - disable_all_sigs_for_relay(sta->t.usta.s.ryUpUsta.id); - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t disable_all_ckts_for_relay(void) -{ - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - int x; - - SS7_INFO("Disabling all ckts becuase of Relay loss\n"); - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /**********************************************************************/ - /* make sure this is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCkt[x].id, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCkt[x].id); - x++; - continue; - } - - /* throw the relay_down flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); - - /* throw the channel infId status flags to PAUSED ... they will be executed next process cycle */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) */ - - /* move along */ - x++; - /**********************************************************************/ - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - - return FTDM_SUCCESS; -} -#if 0 -/******************************************************************************/ -ftdm_status_t enable_all_ckts_for_relay(void) -{ - sngss7_chan_data_t *sngss7_info = NULL; - sng_isup_inf_t *sngIntf = NULL; - ftdm_channel_t *ftdmchan = NULL; - int x; - - SS7_INFO("Enabling all ckts becuase of Relay connection\n"); - - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /**********************************************************************/ - /* make sure this is voice channel */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCkt[x].id, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCkt[x].id); - x++; - continue; - } - - /* bring the relay_down flag down */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); - - sngIntf = &g_ftdm_sngss7_data.cfg.isupIntf[g_ftdm_sngss7_data.cfg.isupCkt[x].infId]; - - /* check if the interface is paused or resumed */ - if (sngss7_test_flag(sngIntf, SNGSS7_PAUSED)) { - /* don't bring the channel resume flag up...the interface is down */ - SS7_DEBUG_CHAN(ftdmchan, "ISUP interface (%d) set to paused, not resuming channel\n", sngIntf->id); - } else { - SS7_DEBUG_CHAN(ftdmchan, "ISUP interface (%d) set to resume, resuming channel\n", sngIntf->id); - /* throw the channel infId status flags to PAUSED ... they will be executed next process cycle */ - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - } - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) */ - - /* move along */ - x++; - /**********************************************************************/ - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - - return FTDM_SUCCESS; -} -#endif -/******************************************************************************/ -ftdm_status_t reconfig_all_ckts_for_relay(void) -{ - int x; - sngss7_chan_data_t *sngss7_info = NULL; - - /* go through all the circuits on our ProcId */ - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /**************************************************************************/ - if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - /* grab the private data structure */ - sngss7_info = g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - - /* mark the circuit for re-configuration */ - sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_RECONFIG); - - /* clear the relay flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); - } - - /* move to the next circuit */ - x++; - /**************************************************************************/ - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t block_all_ckts_for_relay(uint32_t procId) -{ - int x; - int ret; - - /* we just lost connection to this procId, send out a block for all these circuits */ - x = (procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /**************************************************************************/ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - /* send a block request via stack manager */ - ret = ftmod_ss7_block_isup_ckt_nowait(g_ftdm_sngss7_data.cfg.isupCkt[x].id); - if (ret) { - SS7_INFO("Successfully BLOcked CIC:%d(ckt:%d) due to Relay failure\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } else { - SS7_ERROR("Failed to BLOck CIC:%d(ckt:%d) due to Relay failure\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) */ - - /* move along */ - x++; - /**************************************************************************/ - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t disable_all_sigs_for_relay(uint32_t procId) -{ - SS7_INFO("Disalbing all sig links on ProcID = %d\n", procId); - - ftmod_ss7_disable_grp_mtp3Link(procId); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t disble_all_mtp2_sigs_for_relay(void) -{ - /* check if there is a local mtp2 link*/ - if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_STARTED)) { - SS7_INFO("Disalbing all mtp2 sig links on local system\n"); - - ftmod_ss7_disable_grp_mtp2Link(1); - } - - return FTDM_SUCCESS; - -} - -#if 0 -/******************************************************************************/ -static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId) -{ - int x; - int ret; - - /* we just got connection to this procId, send out a unblock for all these circuits - * since we blocked them when we lost the connection - */ - x = (procId * 1000) + 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /**************************************************************************/ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { - - /* send a block request via stack manager */ - ret = ftmod_ss7_unblock_isup_ckt(g_ftdm_sngss7_data.cfg.isupCkt[x].id); - if (ret) { - SS7_INFO("Successfully unblocked CIC:%d(ckt:%d) due to Relay connection\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } else { - SS7_ERROR("Failed to unblock CIC:%d(ckt:%d) due to Relay connection\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) */ - - /* move along */ - x++; - /**************************************************************************/ - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - - return FTDM_SUCCESS; -} -#endif - - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c deleted file mode 100644 index d9e1790da0..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2009 Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms|with or without - * modification|are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice|this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice|this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT - * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, - * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm); -int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm); -int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm); -int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); -int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status); -int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm); -int ftmod_ss7_isup_ckt_sta(uint32_t id, unsigned char *state); -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm) -{ - - return 1; -} - -/******************************************************************************/ -int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm) -{ - SdMngmt sta; - Pst pst; - - memset(&sta, 0x0, sizeof(sta)); - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSD; - - sta.hdr.elmId.elmnt = STDLSAP; - sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp2Link[id].id; - - return(sng_sta_mtp2(&pst, &sta, cfm)); -} - -/******************************************************************************/ -int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm) -{ - SnMngmt sta; - Pst pst; - - memset(&sta, 0x0, sizeof(sta)); - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* check the for the correct ProcId and make sure it goes to the right system */ - if (g_ftdm_sngss7_data.cfg.procId != 1) { - pst.dstProcId = 1; - } - - sta.hdr.elmId.elmnt = STDLSAP; - sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; - - return(sng_sta_mtp3(&pst, &sta, cfm)); -} - -/******************************************************************************/ -int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm) -{ - SnMngmt sta; - Pst pst; - - memset(&sta, 0x0, sizeof(sta)); - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSN; - - /* check the for the correct ProcId and make sure it goes to the right system */ - if (g_ftdm_sngss7_data.cfg.procId != 1) { - pst.dstProcId = 1; - } - - sta.hdr.elmId.elmnt = STLNKSET; - sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; - sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0]; - - return(sng_sta_mtp3(&pst, &sta, cfm)); -} - -/******************************************************************************/ -int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status) -{ - SiMngmt sta; - SiMngmt cfm; - Pst pst; - int ret; - - memset(&sta, 0x0, sizeof(sta)); - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* check the for the correct ProcId and make sure it goes to the right system */ - if (g_ftdm_sngss7_data.cfg.procId != 1) { - pst.dstProcId = 1; - } - - /* request the status of an inftId */ - sta.hdr.entId.ent = ENTSI; - sta.hdr.entId.inst = S_INST; - sta.hdr.msgType = TSSTA; - sta.hdr.elmId.elmnt = SI_STINTF; - - sta.t.ssta.elmntId.intfId = id; - - ret = sng_sta_isup(&pst, &sta, &cfm); - - *status = cfm.t.ssta.cfm.s.intf.state; - - return(ret); -} - -/******************************************************************************/ -int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm) -{ - RyMngmt sta; - Pst pst; - - memset(&sta, 0x0, sizeof(sta)); - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTRY; - - sta.hdr.entId.ent = ENTRY; - sta.hdr.entId.inst = S_INST; - sta.hdr.msgType = TSSTA; - sta.hdr.elmId.elmnt = STCHSTA; - sta.hdr.elmId.elmntInst1 = id; - - - return(sng_sta_relay(&pst, &sta, cfm)); -} - -/******************************************************************************/ -int ftmod_ss7_isup_ckt_sta(uint32_t id, unsigned char *state) -{ - SiMngmt sta; - SiMngmt cfm; - Pst pst; - int ret; - - memset(&sta, 0x0, sizeof(sta)); - - /* initalize the post structure */ - smPstInit(&pst); - - /* insert the destination Entity */ - pst.dstEnt = ENTSI; - - /* check the for the correct ProcId and make sure it goes to the right system */ - if (g_ftdm_sngss7_data.cfg.procId != 1) { - pst.dstProcId = 1; - } - - /* request the status of an inftId */ - sta.hdr.entId.ent = ENTSI; - sta.hdr.entId.inst = S_INST; - sta.hdr.msgType = TSSTA; - sta.hdr.elmId.elmnt = SI_STCIRGRP; - - sta.t.ssta.elmntId.circuit = id; - sta.t.ssta.param.cirgr.range = 1; - - ret = sng_sta_isup(&pst, &sta, &cfm); - - *state = cfm.t.ssta.cfm.s.cir.state[0]; - - return(ret); -} - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c deleted file mode 100644 index 257ccd943a..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2009 Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms|with or without - * modification|are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice|this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice|this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT - * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, - * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -/******************************************************************************/ - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c deleted file mode 100644 index 42f1ca82da..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ /dev/null @@ -1,3415 +0,0 @@ -/* - * Copyright (c) 2009, Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -#ifdef HAVE_ZLIB -#include -#endif -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -uint32_t sngss7_id; -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -int check_for_state_change(ftdm_channel_t *ftdmchan); -int check_for_reset(sngss7_chan_data_t *sngss7_info); - -unsigned long get_unique_id(void); - -ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan); - -ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan); -ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan); -ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); -ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); - -ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan); - -ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); -ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); - -int find_mtp2_error_type_in_map(const char *err_type); -int find_link_type_in_map(const char *linkType); -int find_switch_type_in_map(const char *switchType); -int find_ssf_type_in_map(const char *ssfType); -int find_cic_cntrl_in_map(const char *cntrlType); - -ftdm_status_t check_status_of_all_isup_intf(void); -ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan); - -void sngss7_send_signal(sngss7_chan_data_t *sngss7_info, ftdm_signal_event_t event_id); -void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_status_t status); -ftdm_status_t sngss7_add_var(sngss7_chan_data_t *ss7_info, const char* var, const char* val); -ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data, ftdm_size_t data_len); -/******************************************************************************/ - -FTDM_ENUM_NAMES(CKT_FLAGS_NAMES, CKT_FLAGS_STRING) -FTDM_STR2ENUM(ftmod_ss7_ckt_state2flag, ftmod_ss7_ckt_flag2str, sng_ckt_flag_t, CKT_FLAGS_NAMES, 31) - -FTDM_ENUM_NAMES(BLK_FLAGS_NAMES, BLK_FLAGS_STRING) -FTDM_STR2ENUM(ftmod_ss7_blk_state2flag, ftmod_ss7_blk_flag2str, sng_ckt_block_flag_t, BLK_FLAGS_NAMES, 31) - -/* FUNCTIONS ******************************************************************/ -static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val); -static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val); -ftdm_status_t four_char_to_hex(const char* in, uint16_t* out) ; -ftdm_status_t hex_to_four_char(uint16_t in, char* out); - - -ftdm_status_t hex_to_char(uint16_t in, char* out, int len); -ftdm_status_t char_to_hex(const char* in, uint16_t* out, int len); - -/* Maps generic FreeTDM CPC codes to SS7 CPC codes */ -ftdm2trillium_t cpc_codes[] = { - {FTDM_CPC_UNKNOWN, CAT_UNKNOWN}, - {FTDM_CPC_OPERATOR_FRENCH, CAT_OPLANGFR}, - {FTDM_CPC_OPERATOR_ENGLISH, CAT_OPLANGENG}, - {FTDM_CPC_OPERATOR_GERMAN, CAT_OPLANGGER}, - {FTDM_CPC_OPERATOR_RUSSIAN, CAT_OPLANGRUS}, - {FTDM_CPC_OPERATOR_SPANISH, CAT_OPLANGSP}, - {FTDM_CPC_ORDINARY, CAT_ORD}, - {FTDM_CPC_PRIORITY, CAT_PRIOR}, - {FTDM_CPC_DATA, CAT_DATA}, - {FTDM_CPC_TEST, CAT_TEST}, - {FTDM_CPC_PAYPHONE, CAT_PAYPHONE}, -}; - -ftdm2trillium_t bc_cap_codes[] = { - {FTDM_BEARER_CAP_SPEECH, ITC_SPEECH}, /* speech as per ATIS-1000113.3.2005 */ - {FTDM_BEARER_CAP_UNRESTRICTED, ITC_UNRDIG}, /* unrestricted digital as per ATIS-1000113.3.2005 */ - {FTDM_BEARER_CAP_RESTRICTED, ITC_UNRDIG}, /* Restricted Digital */ - {FTDM_BEARER_CAP_3_1KHZ_AUDIO, ITC_A31KHZ}, /* 3.1kHz audio as per ATIS-1000113.3.2005 */ - {FTDM_BEARER_CAP_7KHZ_AUDIO, ITC_A7KHZ}, /* 7Khz audio */ - {FTDM_BEARER_CAP_15KHZ_AUDIO, ITC_A15KHZ}, /* 15Khz audio */ - {FTDM_BEARER_CAP_VIDEO, ITC_VIDEO}, /* Video */ -}; - -static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val) -{ - ftdm2trillium_t *val = vals; - while(val++) { - if (val->ftdm_val == ftdm_val) { - return val->trillium_val; - } - } - return default_val; -} - -static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val) -{ - ftdm2trillium_t *val = vals; - while(val++) { - if (val->trillium_val == trillium_val) { - return val->ftdm_val; - } - } - return default_val; -} - -ftdm_status_t copy_cgPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum) -{ - return FTDM_SUCCESS; -} - -ftdm_status_t copy_cgPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum) -{ - const char *val = NULL; - const char *clg_nadi = NULL; - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - cgPtyNum->eh.pres = PRSNT_NODEF; - - cgPtyNum->natAddrInd.pres = PRSNT_NODEF; - cgPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].clg_nadi; - - - cgPtyNum->scrnInd.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_screen_ind"); - if (!ftdm_strlen_zero(val)) { - cgPtyNum->scrnInd.val = atoi(val); - } else { - cgPtyNum->scrnInd.val = caller_data->screen; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Screening Ind %d\n", cgPtyNum->scrnInd.val); - - cgPtyNum->presRest.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_pres_ind"); - if (!ftdm_strlen_zero(val)) { - cgPtyNum->presRest.val = atoi(val); - } else { - cgPtyNum->presRest.val = caller_data->pres; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Presentation Ind %d\n", cgPtyNum->presRest.val); - - cgPtyNum->numPlan.pres = PRSNT_NODEF; - cgPtyNum->numPlan.val = 0x01; - - cgPtyNum->niInd.pres = PRSNT_NODEF; - cgPtyNum->niInd.val = 0x00; - - /* check if the user would like a custom NADI value for the calling Pty Num */ - clg_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_nadi"); - if (!ftdm_strlen_zero(clg_nadi)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Calling NADI value \"%s\"\n", clg_nadi); - cgPtyNum->natAddrInd.val = atoi(clg_nadi); - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number NADI value %d\n", cgPtyNum->natAddrInd.val); - - return copy_tknStr_to_sngss7(caller_data->cid_num.digits, &cgPtyNum->addrSig, &cgPtyNum->oddEven); -} - -ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum) -{ - char var[FTDM_DIGITS_LIMIT]; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - if (cdPtyNum->eh.pres == PRSNT_NODEF && - cdPtyNum->natAddrInd.pres == PRSNT_NODEF) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Called Party Number NADI %d\n", cdPtyNum->natAddrInd.val); - sprintf(var, "%d", cdPtyNum->natAddrInd.val); - sngss7_add_var(sngss7_info, "ss7_cld_nadi", var); - } - - return FTDM_SUCCESS; -} - - -ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum) -{ - const char *val = NULL; - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - cdPtyNum->eh.pres = PRSNT_NODEF; - - cdPtyNum->natAddrInd.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_nadi"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Called NADI value \"%s\"\n", val); - cdPtyNum->natAddrInd.val = atoi(val); - } else { - cdPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].cld_nadi; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied NADI value found for CLD, using \"%d\"\n", cdPtyNum->natAddrInd.val); - } - - cdPtyNum->numPlan.pres = PRSNT_NODEF; - cdPtyNum->numPlan.val = 0x01; - - cdPtyNum->innInd.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_inn"); - if (!ftdm_strlen_zero(val)) { - cdPtyNum->innInd.val = atoi(val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Called INN value \"%s\"\n", val); - } else { - cdPtyNum->innInd.val = 0x01; - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Called INN value, set to default value 0x01\n"); - } - - return copy_tknStr_to_sngss7(caller_data->dnis.digits, &cdPtyNum->addrSig, &cdPtyNum->oddEven); -} - -ftdm_status_t copy_locPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum) -{ - return FTDM_SUCCESS; -} - -ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum) -{ - const char *val = NULL; - const char *loc_nadi = NULL; - int pres_val = PRSNT_NODEF; - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - if (!strcasecmp(caller_data->loc.digits, "NULL")) { - pres_val = NOTPRSNT; - return FTDM_SUCCESS; - } - - locPtyNum->eh.pres = pres_val; - locPtyNum->natAddrInd.pres = pres_val; - locPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].loc_nadi; - - locPtyNum->scrnInd.pres = pres_val; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_loc_screen_ind"); - if (!ftdm_strlen_zero(val)) { - locPtyNum->scrnInd.val = atoi(val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Location Screening Ind %d\n", locPtyNum->scrnInd.val); - } else { - locPtyNum->scrnInd.val = caller_data->screen; - } - - locPtyNum->presRest.pres = pres_val; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_loc_pres_ind"); - if (!ftdm_strlen_zero(val)) { - locPtyNum->presRest.val = atoi(val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Location Presentation Ind %d\n", locPtyNum->presRest.val); - } else { - locPtyNum->presRest.val = caller_data->pres; - } - - locPtyNum->numPlan.pres = pres_val; - locPtyNum->numPlan.val = 0x01; - - locPtyNum->niInd.pres = pres_val; - locPtyNum->niInd.val = 0x00; - - /* check if the user would like a custom NADI value for the Location Reference */ - loc_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_loc_nadi"); - if (!ftdm_strlen_zero(loc_nadi)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Location Reference NADI value \"%s\"\n", loc_nadi); - locPtyNum->natAddrInd.val = atoi(loc_nadi); - } else { - locPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].loc_nadi; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied NADI value found for LOC, using \"%d\"\n", locPtyNum->natAddrInd.val); - } - - return copy_tknStr_to_sngss7(caller_data->loc.digits, &locPtyNum->addrSig, &locPtyNum->oddEven); -} - -ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb) -{ - const char *val = NULL; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_digits"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number qualifier \"%s\"\n", val); - if (copy_tknStr_to_sngss7((char*)val, &genNmb->addrSig, &genNmb->oddEven) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else { - return FTDM_SUCCESS; - } - - genNmb->eh.pres = PRSNT_NODEF; - genNmb->addrSig.pres = PRSNT_NODEF; - - genNmb->nmbQual.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_numqual"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"%s\"\n", val); - genNmb->nmbQual.val = atoi(val); - } else { - genNmb->nmbQual.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_nmbqual; - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \n"); - } - genNmb->natAddrInd.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_nadi"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"nature of address\" \"%s\"\n", val); - genNmb->natAddrInd.val = atoi(val); - } else { - genNmb->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_nadi; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"nature of address\" \"%d\"\n", genNmb->natAddrInd.val); - } - genNmb->scrnInd.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_screen_ind"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"screening indicator\" \"%s\"\n", val); - genNmb->scrnInd.val = atoi(val); - } else { - genNmb->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_screen_ind; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"screening indicator\" \"%d\"\n", genNmb->natAddrInd.val); - } - genNmb->presRest.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_pres_ind"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"presentation indicator\" \"%s\"\n", val); - genNmb->presRest.val = atoi(val); - } else { - genNmb->presRest.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_pres_ind; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"presentation indicator\" \"%d\"\n", genNmb->presRest.val); - } - genNmb->numPlan.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_npi"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"numbering plan\" \"%s\"\n", val); - genNmb->numPlan.val = atoi(val); - } else { - genNmb->numPlan.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_npi; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"numbering plan\" \"%d\"\n", genNmb->numPlan.val); - } - genNmb->niInd.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_num_inc_ind"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"number incomplete indicator\" \"%s\"\n", val); - genNmb->niInd.val = atoi(val); - } else { - genNmb->niInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_num_inc_ind; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"number incomplete indicator\" \"%d\"\n", genNmb->niInd.val); - } - return FTDM_SUCCESS; -} - -ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb) -{ - char val[64]; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - memset(val, 0, sizeof(val)); - - if (genNmb->eh.pres != PRSNT_NODEF || genNmb->addrSig.pres != PRSNT_NODEF) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Generic Number available\n"); - return FTDM_SUCCESS; - } - - copy_tknStr_from_sngss7(genNmb->addrSig, val, genNmb->oddEven); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_gn_digits", val); - - if (genNmb->nmbQual.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", genNmb->nmbQual.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number qualifier\" \"%s\"\n", val); - sngss7_add_var(sngss7_info, "ss7_gn_numqual", val); - } - - if (genNmb->natAddrInd.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", genNmb->natAddrInd.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"nature of address\" \"%s\"\n", val); - sngss7_add_var(sngss7_info, "ss7_gn_nadi", val); - } - - if (genNmb->scrnInd.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", genNmb->scrnInd.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"screening indicator\" \"%s\"\n", val); - sngss7_add_var(sngss7_info, "ss7_gn_screen_ind", val); - } - - if (genNmb->presRest.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", genNmb->presRest.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"presentation indicator\" \"%s\"\n", val); - sngss7_add_var(sngss7_info, "ss7_gn_pres_ind", val); - } - - if (genNmb->numPlan.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", genNmb->numPlan.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"numbering plan\" \"%s\"\n", val); - sngss7_add_var(sngss7_info, "ss7_gn_npi", val); - } - - if (genNmb->niInd.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", genNmb->niInd.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number incomplete indicator\" \"%s\"\n", val); - sngss7_add_var(sngss7_info, "ss7_gn_num_inc_ind", val); - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum) -{ - const char* val = NULL; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Redirection Number\"%s\"\n", val); - if (copy_tknStr_to_sngss7((char*)val, &redirgNum->addrSig, &redirgNum->oddEven) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else if (!ftdm_strlen_zero(caller_data->rdnis.digits)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Redirection Number\"%s\"\n", caller_data->rdnis.digits); - if (copy_tknStr_to_sngss7(caller_data->rdnis.digits, &redirgNum->addrSig, &redirgNum->oddEven) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - } else { - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_pres_ind"); - if (!ftdm_strlen_zero(val)) { - redirgNum->presRest.val = atoi(val); - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Address Presentation Restricted Ind:%d\n", redirgNum->presRest.val); - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Number\n"); - return FTDM_SUCCESS; - } - - redirgNum->eh.pres = PRSNT_NODEF; - - /* Nature of address indicator */ - redirgNum->natAddr.pres = PRSNT_NODEF; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_nadi"); - if (!ftdm_strlen_zero(val)) { - redirgNum->natAddr.val = atoi(val); - } else { - redirgNum->natAddr.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].rdnis_nadi; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number NADI:%d\n", redirgNum->natAddr.val); - - /* Screening indicator */ - redirgNum->scrInd.pres = PRSNT_NODEF; - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_screen_ind"); - if (!ftdm_strlen_zero(val)) { - redirgNum->scrInd.val = atoi(val); - } else { - redirgNum->scrInd.val = FTDM_SCREENING_VERIFIED_PASSED; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Screening Ind:%d\n", redirgNum->scrInd.val); - - /* Address presentation restricted ind */ - redirgNum->presRest.pres = PRSNT_NODEF; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_pres_ind"); - if (!ftdm_strlen_zero(val)) { - redirgNum->presRest.val = atoi(val); - } else { - redirgNum->presRest.val = FTDM_PRES_ALLOWED; - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Address Presentation Restricted Ind:%d\n", redirgNum->presRest.val); - - /* Numbering plan */ - redirgNum->numPlan.pres = PRSNT_NODEF; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_plan"); - if (!ftdm_strlen_zero(val)) { - redirgNum->numPlan.val = atoi(val); - } else { - redirgNum->numPlan.val = caller_data->rdnis.plan; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Numbering plan:%d\n", redirgNum->numPlan.val); - - return copy_tknStr_to_sngss7(caller_data->rdnis.digits, &redirgNum->addrSig, &redirgNum->oddEven); -} - -ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum) -{ - char val[20]; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - if (redirgNum->eh.pres != PRSNT_NODEF || redirgNum->addrSig.pres != PRSNT_NODEF) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Redirecting Number available\n"); - return FTDM_SUCCESS; - } - - copy_tknStr_from_sngss7(redirgNum->addrSig, ftdmchan->caller_data.rdnis.digits, redirgNum->oddEven); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number:%s\n", ftdmchan->caller_data.rdnis.digits); - snprintf(val, sizeof(val), "%s", ftdmchan->caller_data.rdnis.digits); - sngss7_add_var(sngss7_info, "ss7_rdnis_digits", val); - - - if (redirgNum->natAddr.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirgNum->natAddr.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number NADI:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdnis_nadi", val); - caller_data->rdnis.type = redirgNum->natAddr.val; - } - - if (redirgNum->scrInd.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirgNum->scrInd.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Screening Ind:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdnis_screen_ind", val); - } - - if (redirgNum->presRest.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirgNum->presRest.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Presentation Ind:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdnis_pres_ind", val); - } - - if (redirgNum->numPlan.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirgNum->numPlan.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Numbering plan:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdnis_plan", val); - caller_data->rdnis.plan = redirgNum->numPlan.val; - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_redirgInfo_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo) -{ - char val[20]; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - if (redirInfo->eh.pres != PRSNT_NODEF ) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Redirecting Information available\n"); - return FTDM_SUCCESS; - } - - - if (redirInfo->redirInd.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirInfo->redirInd.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - redirection indicator:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdinfo_indicator", val); - } - - if (redirInfo->origRedirReas.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirInfo->origRedirReas.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - original redirection reason:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdinfo_orig", val); - } - - if (redirInfo->redirCnt.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirInfo->redirCnt.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - redirection count:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdinfo_count", val); - } - - if (redirInfo->redirReas.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", redirInfo->redirReas.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirection Information - redirection reason:%s\n", val); - sngss7_add_var(sngss7_info, "ss7_rdinfo_reason", val); - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo) -{ - const char* val = NULL; - int bProceed = 0; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_indicator"); - if (!ftdm_strlen_zero(val)) { - redirInfo->redirInd.val = atoi(val); - redirInfo->redirInd.pres = 1; - bProceed = 1; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Indicator\n"); - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_orig"); - if (!ftdm_strlen_zero(val)) { - redirInfo->origRedirReas.val = atoi(val); - redirInfo->origRedirReas.pres = 1; - bProceed = 1; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Original Reasons\n"); - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_count"); - if (!ftdm_strlen_zero(val)) { - redirInfo->redirCnt.val = atoi(val); - redirInfo->redirCnt.pres= 1; - bProceed = 1; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Count\n"); - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdinfo_reason"); - if (!ftdm_strlen_zero(val)) { - redirInfo->redirReas.val = atoi(val); - redirInfo->redirReas.pres = 1; - bProceed = 1; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Information on Redirection Reasons\n"); - } - - if( bProceed == 1 ) { - redirInfo->eh.pres = PRSNT_NODEF; - } else { - redirInfo->eh.pres = NOTPRSNT; - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_access_transport_from_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt) -{ - char val[3*((MF_SIZE_TKNSTRE + 7) & 0xff8)]; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - if (accTrnspt->eh.pres != PRSNT_NODEF || accTrnspt->infoElmts.pres !=PRSNT_NODEF) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Access Transport IE available\n"); - return FTDM_SUCCESS; - } - - ftdm_url_encode((const char*)accTrnspt->infoElmts.val, val, accTrnspt->infoElmts.len); - sngss7_add_var (sngss7_info, "ss7_access_transport_urlenc", val); - - return FTDM_SUCCESS; -} -ftdm_status_t copy_access_transport_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt) -{ - const char *val = NULL; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_access_transport_urlenc"); - if (ftdm_strlen_zero(val)) { - accTrnspt->eh.pres = NOTPRSNT; - accTrnspt->infoElmts.pres = NOTPRSNT; - } - else { - char *val_dec = NULL; - int val_len = strlen (val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found Access Transport IE encoded : %s\n", val); - - accTrnspt->eh.pres = PRSNT_NODEF; - accTrnspt->infoElmts.pres = PRSNT_NODEF; - - val_dec = ftdm_strdup(val); - ftdm_url_decode(val_dec, (ftdm_size_t*)&val_len); - memcpy (accTrnspt->infoElmts.val, val_dec, val_len); - accTrnspt->infoElmts.len = val_len; - ftdm_safe_free(val_dec); - } - return FTDM_SUCCESS; -} - -ftdm_status_t copy_ocn_from_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum) -{ - char val[20]; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - if (origCdNum->eh.pres != PRSNT_NODEF ) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Original Called Number available\n"); - return FTDM_SUCCESS; - } - - if (origCdNum->addrSig.pres == PRSNT_NODEF) { - copy_tknStr_from_sngss7(origCdNum->addrSig, val, origCdNum->oddEven); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Original Called Number - Digits: %s\n", val); - sngss7_add_var(sngss7_info, "ss7_ocn", val); - } - - if (origCdNum->natAddr.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", origCdNum->natAddr.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Original Called Number - NADI: %s\n", val); - sngss7_add_var(sngss7_info, "ss7_ocn_nadi", val); - } - - if (origCdNum->numPlan.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", origCdNum->numPlan.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Original Called Number - Plan: %s\n", val); - sngss7_add_var(sngss7_info, "ss7_ocn_plan", val); - } - - if (origCdNum->presRest.pres == PRSNT_NODEF) { - snprintf(val, sizeof(val), "%d", origCdNum->presRest.val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Original Called Number - Presentation: %s\n", val); - sngss7_add_var(sngss7_info, "ss7_ocn_pres", val); - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_ocn_to_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum) -{ - const char *val = NULL; - int bProceed = 0; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_ocn"); - if (!ftdm_strlen_zero(val)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Original Called Number - Digits: %s\n", val); - if (copy_tknStr_to_sngss7((char*)val, &origCdNum->addrSig, &origCdNum->oddEven) != FTDM_SUCCESS) { - return FTDM_FAIL; - } - origCdNum->addrSig.pres = 1; - } else { - return FTDM_SUCCESS; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_ocn_nadi"); - if (!ftdm_strlen_zero(val)) { - origCdNum->natAddr.val = atoi(val); - origCdNum->natAddr.pres = 1; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Original Called Number - NADI: %s\n", val); - bProceed = 1; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Original Called Number NADI value\n"); - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_ocn_plan"); - if (!ftdm_strlen_zero(val)) { - origCdNum->numPlan.val = atoi(val); - origCdNum->numPlan.pres = 1; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Original Called Number - Plan: %s\n", val); - bProceed = 1; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Original Called Number Plan value\n"); - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_ocn_pres"); - if (!ftdm_strlen_zero(val)) { - origCdNum->presRest.val = atoi(val); - origCdNum->presRest.pres = 1; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Original Called Number - Presentation: %s\n", val); - bProceed = 1; - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Original Called Number Presentation value\n"); - } - - if( bProceed == 1 ) { - origCdNum->eh.pres = PRSNT_NODEF; - } else { - origCdNum->eh.pres = NOTPRSNT; - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - cgPtyCat->eh.pres = PRSNT_NODEF; - cgPtyCat->cgPtyCat.pres = PRSNT_NODEF; - - cgPtyCat->cgPtyCat.val = get_trillium_val(cpc_codes, caller_data->cpc, CAT_ORD); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Category:0x%x\n",cgPtyCat->cgPtyCat.val); - return FTDM_SUCCESS; -} - -ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat) -{ - ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - - if (cgPtyCat->eh.pres == PRSNT_NODEF && - cgPtyCat->cgPtyCat.pres == PRSNT_NODEF) { - - caller_data->cpc = get_ftdm_val(cpc_codes, cgPtyCat->cgPtyCat.val, FTDM_CPC_UNKNOWN); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Category:0x%x\n", cgPtyCat->cgPtyCat.val); - } - return FTDM_SUCCESS; -} - - -ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt) -{ - const char *clg_subAddr = NULL; - const char *cld_subAddr = NULL; - char subAddrIE[MAX_SIZEOF_SUBADDR_IE]; - - /* check if the user would like us to send a clg_sub-address */ - clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr"); - if (!ftdm_strlen_zero(clg_subAddr)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr); - - /* clean out the subAddrIE */ - memset(subAddrIE, 0x0, sizeof(subAddrIE)); - - /* check the first character in the sub-address to see what type of encoding to use */ - switch (clg_subAddr[0]) { - case '0': /* NSAP */ - encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING); - break; - case '1': /* national variant */ - encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]); - break; - } /* switch (cld_subAddr[0]) */ - - - /* if subaddIE is still empty don't copy it in */ - if (subAddrIE[0] != '0') { - /* check if the clg_subAddr has already been added */ - if (accTrnspt->eh.pres == PRSNT_NODEF) { - /* append the subAddrIE */ - memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2)); - accTrnspt->infoElmts.len = accTrnspt->infoElmts.len +subAddrIE[1] + 2; - } else { - /* fill in from the beginning */ - accTrnspt->eh.pres = PRSNT_NODEF; - accTrnspt->infoElmts.pres = PRSNT_NODEF; - memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2)); - accTrnspt->infoElmts.len = subAddrIE[1] + 2; - } - } - } - - /* check if the user would like us to send a cld_sub-address */ - cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr"); - if ((cld_subAddr != NULL) && (*cld_subAddr)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr); - - /* clean out the subAddrIE */ - memset(subAddrIE, 0x0, sizeof(subAddrIE)); - - /* check the first character in the sub-address to see what type of encoding to use */ - switch (cld_subAddr[0]) { - case '0': /* NSAP */ - encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED); - break; - case '1': /* national variant */ - encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED); - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]); - break; - } /* switch (cld_subAddr[0]) */ - - /* if subaddIE is still empty don't copy it in */ - if (subAddrIE[0] != '0') { - /* check if the cld_subAddr has already been added */ - if (accTrnspt->eh.pres == PRSNT_NODEF) { - /* append the subAddrIE */ - memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2)); - accTrnspt->infoElmts.len = accTrnspt->infoElmts.len +subAddrIE[1] + 2; - } else { - /* fill in from the beginning */ - accTrnspt->eh.pres = PRSNT_NODEF; - accTrnspt->infoElmts.pres = PRSNT_NODEF; - memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2)); - accTrnspt->infoElmts.len = subAddrIE[1] + 2; - } - } - } /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */ - return FTDM_SUCCESS; -} - -ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd) -{ - /* copy down the nature of connection indicators */ - natConInd->eh.pres = PRSNT_NODEF; - natConInd->satInd.pres = PRSNT_NODEF; - natConInd->satInd.val = 0; /* no satellite circuit */ - natConInd->contChkInd.pres = PRSNT_NODEF; - natConInd->contChkInd.val = CONTCHK_NOTREQ; - natConInd->echoCntrlDevInd.pres = PRSNT_NODEF; - natConInd->echoCntrlDevInd.val = ECHOCDEV_INCL; - return FTDM_SUCCESS; -} - -ftdm_status_t four_char_to_hex(const char* in, uint16_t* out) -{ - int i= 4; - char a, b, c, d; - if (!in || 4>strlen(in)) { - return FTDM_FAIL; - } - while(i) - { - switch((char)*(in+(4-i))) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (i==4) { - d = *(in+(4-i)) - 48; - } else if (i==3) { - c = *(in+(4-i)) - 48; - } else if (i==2) { - b = *(in+(4-i)) - 48; - } else { - a = *(in+(4-i)) - 48; - } - break; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - if (i==4) { - d = *(in+(4-i)) - 55; - } else if (i==3) { - c = *(in+(4-i)) - 55; - } else if (i==2) { - b = *(in+(4-i)) - 55; - } else { - a = *(in+(4-i)) - 55; - } - break; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - if (i==4) { - d = *(in+(4-i)) - 87; - } else if (i==3) { - c = *(in+(4-i)) - 87; - } else if (i==2) { - b = *(in+(4-i)) - 87; - } else { - a = *(in+(4-i)) - 87; - } - break; - default: - SS7_ERROR("Invalid character found when decoding hex string, %c!\n", *(in+(4-i)) ); - break; - } - i--; - }; - - *out |= d; - *out = *out<<4; - *out |= c; - *out = *out<<4; - *out |= b; - *out = *out<<4; - *out |= a; - - return FTDM_SUCCESS; -} - -ftdm_status_t char_to_hex(const char* in, uint16_t* out, int len) -{ - int i= len; - char *val = ftdm_malloc(len*sizeof(char)); - - if (!val ||!in || len>strlen(in)) { - return FTDM_FAIL; - } - - while(i) - { - switch((char)*(in+(len-i))) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - *(val+(len-i)) = *(in+(len-i)) - 48; - break; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - *(val+(len-i)) = *(in+(len-i)) - 55; - break; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - *(val+(len-i)) = *(in+(len-i)) - 87; - break; - default: - SS7_ERROR("Invalid character found when decoding hex string, %c!\n", *(in+(len-i)) ); - break; - } - i--; - }; - - for (i=0; i<=len-1; i++) { - *out = *out << 4; - *out |= *(val+i); - } - - return FTDM_SUCCESS; -} - - - -ftdm_status_t hex_to_char(uint16_t in, char* out, int len) -{ - char val=0; - int mask = 0xf; - int i=0; - if (!out) { - return FTDM_SUCCESS; - } - - for (i=len-1; i>=0; i--) { - val = (in & (mask<<(4*i))) >> (4*i); - sprintf (out+(len-1-i), "%x", val); - } - - return FTDM_SUCCESS; -} -ftdm_status_t hex_to_four_char(uint16_t in, char* out) -{ - char val=0; - int mask = 0xf; - int i=0; - if (!out) { - return FTDM_SUCCESS; - } - - for (i=3; i>=0; i--) { - val = (in & (mask<<(4*i))) >> (4*i); - sprintf (out+(3-i), "%x", val); - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_NatureOfConnection_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd) -{ - const char *val = NULL; - - natConInd->eh.pres = PRSNT_NODEF; - natConInd->satInd.pres = PRSNT_NODEF; - natConInd->contChkInd.pres = PRSNT_NODEF;; - natConInd->echoCntrlDevInd.pres = PRSNT_NODEF; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_nature_connection_hex"); - if (!ftdm_strlen_zero(val)) { - uint16_t val_hex = 0; - if (char_to_hex (val, &val_hex, 2) == FTDM_FAIL) { - SS7_ERROR ("Wrong value set in ss7_iam_nature_connection_hex variable. Please correct the error. Setting to default values.\n" ); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "hex = 0x%x\n", val_hex); - natConInd->satInd.val = (val_hex & 0x3); - natConInd->contChkInd.val = (val_hex & 0xc)>>2; - natConInd->echoCntrlDevInd.val = (val_hex & 0x10) >> 4; - - return FTDM_SUCCESS; - } - } - - natConInd->satInd.val = 0; - natConInd->contChkInd.val = 0; - natConInd->echoCntrlDevInd.val = 0; - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_NatureOfConnection_from_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd ) -{ - char val[3]; - uint16_t val_hex = 0; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - memset (val, 0, 3*sizeof(char)); - if (natConInd->eh.pres != PRSNT_NODEF ) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No nature of connection indicator IE available\n"); - return FTDM_SUCCESS; - } - - val_hex |= natConInd->satInd.val; - val_hex |= natConInd->contChkInd.val << 2; - val_hex |= natConInd->echoCntrlDevInd.val <<4; - hex_to_char(val_hex, val, 2) ; - - sngss7_add_var(sngss7_info, "ss7_iam_nature_connection_hex", val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Nature of connection indicator Hex: 0x%s\n", val); - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_fwdCallInd_hex_from_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd) -{ - char val[5]; - uint16_t val_hex = 0; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - memset (val, 0, 5*sizeof(char)); - if (fwdCallInd->eh.pres != PRSNT_NODEF ) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No forward call indicator IE available\n"); - return FTDM_SUCCESS; - } - - val_hex |= fwdCallInd->natIntCallInd.val << 8; - val_hex |= (fwdCallInd->end2EndMethInd.val & 0x1) << 9; - val_hex |= ((fwdCallInd->end2EndMethInd.val & 0x2)>>1) << 10; - val_hex |= fwdCallInd->intInd.val << 11; - val_hex |= fwdCallInd->end2EndInfoInd.val << 12; - val_hex |= fwdCallInd->isdnUsrPrtInd.val << 13; - val_hex |= (fwdCallInd->isdnUsrPrtPrfInd.val & 0x1) << 14; - val_hex |= ((fwdCallInd->isdnUsrPrtPrfInd.val & 0x2)>>1) << 15; - - val_hex |= fwdCallInd->isdnAccInd.val; - hex_to_four_char(val_hex, val) ; - - sngss7_add_var(sngss7_info, "ss7_iam_fwd_ind_hex", val); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Forwad Call Indicator Hex: 0x%s\n", val); - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd) -{ - const char *val = NULL; - int acc_val = ISDNACC_ISDN; - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - fwdCallInd->eh.pres = PRSNT_NODEF; - fwdCallInd->natIntCallInd.pres = PRSNT_NODEF; - fwdCallInd->end2EndMethInd.pres = PRSNT_NODEF; - fwdCallInd->intInd.pres = PRSNT_NODEF; - fwdCallInd->end2EndInfoInd.pres = PRSNT_NODEF; - fwdCallInd->isdnUsrPrtInd.pres = PRSNT_NODEF; - fwdCallInd->isdnUsrPrtPrfInd.pres = PRSNT_NODEF; - fwdCallInd->isdnAccInd.pres = PRSNT_NODEF; - fwdCallInd->sccpMethInd.pres = PRSNT_NODEF; - fwdCallInd->sccpMethInd.val = SCCPMTH_NOIND; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_fwd_ind_hex"); - if (!ftdm_strlen_zero(val)) { - uint16_t val_hex = 0; - if (four_char_to_hex (val, &val_hex) == FTDM_FAIL) { - SS7_ERROR ("Wrong value set in iam_fwd_ind_HEX variable. Please correct the error. Setting to default values.\n" ); - } else { - fwdCallInd->natIntCallInd.val = (val_hex & 0x100)>>8; - fwdCallInd->end2EndMethInd.val = (val_hex & 0x600)>>9; - fwdCallInd->intInd.val = (val_hex & 0x800)>>11; - fwdCallInd->end2EndInfoInd.val = (val_hex & 0x1000)>>12; - fwdCallInd->isdnUsrPrtInd.val = (val_hex & 0x2000)>>13; - fwdCallInd->isdnUsrPrtPrfInd.val = (val_hex & 0xC000)>>14; - fwdCallInd->isdnUsrPrtPrfInd.val = (fwdCallInd->isdnUsrPrtPrfInd.val==0x03)?0x0:fwdCallInd->isdnUsrPrtPrfInd.val; - fwdCallInd->isdnAccInd.val = val_hex & 0x1; - - if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) || - (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) || - (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) { - - /* include only if we're running ANSI */ - fwdCallInd->transCallNInd.pres = PRSNT_NODEF; - fwdCallInd->transCallNInd.val = 0x0; - } - - return FTDM_SUCCESS; - } - } - - fwdCallInd->natIntCallInd.val = 0x00; - fwdCallInd->end2EndMethInd.val = E2EMTH_NOMETH; - fwdCallInd->intInd.val = INTIND_NOINTW; - fwdCallInd->end2EndInfoInd.val = E2EINF_NOINFO; - fwdCallInd->isdnUsrPrtInd.val = ISUP_USED; - fwdCallInd->isdnUsrPrtPrfInd.val = PREF_PREFAW; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_fwd_ind_isdn_access_ind"); - if (ftdm_strlen_zero(val)) { - /* Kept for backward compatibility */ - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "iam_fwd_ind_isdn_access_ind"); - } - - if (!ftdm_strlen_zero(val)) { - acc_val = (int)atoi(val); - } - - fwdCallInd->isdnAccInd.val = acc_val; - - if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) || - (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) || - (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) { - - /* include only if we're running ANSI */ - fwdCallInd->transCallNInd.pres = PRSNT_NODEF; - fwdCallInd->transCallNInd.val = 0x0; - } - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq) -{ - txMedReq->eh.pres = PRSNT_NODEF; - txMedReq->trMedReq.pres = PRSNT_NODEF; - txMedReq->trMedReq.val = ftdmchan->caller_data.bearer_capability; - - return FTDM_SUCCESS; -} - -ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA) -{ - int bProceed = 0; - const char *val = NULL; - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_trans_cap"); - if (!ftdm_strlen_zero(val)) { - int itc_type = 0; - if (!strcasecmp(val, "SPEECH")) { - itc_type = ITC_SPEECH; - } else if (!strcasecmp(val, "UNRESTRICTED")) { - itc_type = ITC_UNRDIG; - } else if (!strcasecmp(val, "RESTRICTED")) { - itc_type = ITC_RESDIG; - } else if (!strcasecmp(val, "31KHZ")) { - itc_type = ITC_A31KHZ; - } else if (!strcasecmp(val, "7KHZ")) { - itc_type = ITC_A7KHZ; - } else if (!strcasecmp(val, "15KHZ")) { - itc_type = ITC_A15KHZ; - } else if (!strcasecmp(val, "VIDEO")) { - itc_type = ITC_VIDEO; - } else { - itc_type = ITC_SPEECH; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI transmission capability parameter is wrong : %s. Setting to default SPEECH. \n", val ); - } - - usrServInfoA->infoTranCap.pres = PRSNT_NODEF; - usrServInfoA->infoTranCap.val = get_trillium_val(bc_cap_codes, ftdmchan->caller_data.bearer_capability, itc_type); - bProceed = 1; - } else { - usrServInfoA->infoTranCap.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_code_standard"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->cdeStand.pres = PRSNT_NODEF; - usrServInfoA->cdeStand.val = (int)atoi(val); /* default is 0x0 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI coding standard = %d\n", usrServInfoA->cdeStand.val ); - bProceed = 1; - } else { - usrServInfoA->cdeStand.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_trans_mode"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->tranMode.pres = PRSNT_NODEF; - usrServInfoA->tranMode.val = (int)atoi(val); /* transfer mode, default is 0x0*/ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI transfer mode = %d\n", usrServInfoA->tranMode.val ); - bProceed = 1; - } else { - usrServInfoA->tranMode.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_trans_rate_0"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->infoTranRate0.pres = PRSNT_NODEF; - usrServInfoA->infoTranRate0.val = (int)atoi(val); /* default is 0x10, 64kbps origination to destination*/ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI trans rate 0 = %d\n", usrServInfoA->infoTranRate0.val ); - bProceed = 1; - } else { - usrServInfoA->infoTranRate0.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_trans_rate_1"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->infoTranRate1.pres = PRSNT_NODEF; - usrServInfoA->infoTranRate1.val = (int)atoi(val); /* 64kbps destination to origination, default is 0x10 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI trans rate 1 = %d\n", usrServInfoA->infoTranRate1.val ); - bProceed = 1; - } else { - usrServInfoA->infoTranRate1.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_layer1_ident"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->lyr1Ident.pres = PRSNT_NODEF; - usrServInfoA->lyr1Ident.val = (int)atoi(val); /*default value is 0x01 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI layer 1 indentification = %d\n", usrServInfoA->lyr1Ident.val ); - bProceed = 1; - } else { - usrServInfoA->lyr1Ident.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_layer1_prot"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->usrInfLyr1Prot.pres = PRSNT_NODEF; - usrServInfoA->usrInfLyr1Prot.val = (int)atoi(val); /*default value is 0x02 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI layer 1 protocol = %d\n", usrServInfoA->usrInfLyr1Prot.val ); - bProceed = 1; - } else { - usrServInfoA->usrInfLyr1Prot.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_layer2_ident"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->lyr2Ident.pres = PRSNT_NODEF; - usrServInfoA->lyr2Ident.val = (int)atoi(val); /*default value is 0x01 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI layer 2 indentification = %d\n", usrServInfoA->lyr2Ident.val ); - bProceed = 1; - } else { - usrServInfoA->lyr2Ident.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_layer2_prot"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->usrInfLyr2Prot.pres = PRSNT_NODEF; - usrServInfoA->usrInfLyr2Prot.val = (int)atoi(val); /*default value is 0x02 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI layer 2 protocol = %d\n", usrServInfoA->usrInfLyr2Prot.val ); - bProceed = 1; - } else { - usrServInfoA->usrInfLyr2Prot.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_layer3_ident"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->lyr3Ident.pres = PRSNT_NODEF; - usrServInfoA->lyr3Ident.val = (int)atoi(val); /*default value is 0x01 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI layer 3 indentification = %d\n", usrServInfoA->lyr3Ident.val ); - bProceed = 1; - } else { - usrServInfoA->lyr3Ident.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_layer3_prot"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->usrInfLyr3Prot.pres = PRSNT_NODEF; - usrServInfoA->usrInfLyr3Prot.val = (int)atoi(val); /*default value is 0x02 */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI layer 3 protocol = %d\n", usrServInfoA->usrInfLyr3Prot.val ); - bProceed = 1; - } else { - usrServInfoA->usrInfLyr3Prot.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_chan_struct"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->chanStruct.pres = PRSNT_NODEF; - usrServInfoA->chanStruct.val = (int)atoi(val); /* default value is 0x1, 8kHz integrity */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI channel structure = %d\n", usrServInfoA->chanStruct.val ); - bProceed = 1; - } else { - usrServInfoA->chanStruct.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_config"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->config.pres = PRSNT_NODEF; - usrServInfoA->config.val = (int)atoi(val); /* default value is 0x0, point to point configuration */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI configuration = %d\n", usrServInfoA->config.val ); - bProceed = 1; - } else { - usrServInfoA->config.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_establish"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->establish.pres = PRSNT_NODEF; - usrServInfoA->establish.val = (int)atoi(val); /* default value is 0x0, on demand */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI establishment = %d\n", usrServInfoA->establish.val ); - bProceed = 1; - } else { - usrServInfoA->establish.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_symmetry"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->symmetry.pres = PRSNT_NODEF; - usrServInfoA->symmetry.val = (int)atoi(val); /* default value is 0x0, bi-directional symmetric */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI symmetry = %d\n", usrServInfoA->symmetry.val ); - bProceed = 1; - } else { - usrServInfoA->symmetry.pres = NOTPRSNT; - } - - val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_usi_rate_multiplier"); - if (!ftdm_strlen_zero(val)) { - usrServInfoA->rateMultiplier.pres = PRSNT_NODEF; - usrServInfoA->rateMultiplier.val = (int)atoi(val); /* default value is 0x1, 1x rate multipler */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "USI rate multipier = %d\n", usrServInfoA->rateMultiplier.val ); - bProceed = 1; - } else { - usrServInfoA->rateMultiplier.pres = NOTPRSNT; - } - - if (bProceed) { - usrServInfoA->eh.pres = PRSNT_NODEF; - } else { - usrServInfoA->eh.pres = NOTPRSNT; - } - - return FTDM_SUCCESS; -} - - - -ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven) -{ - uint8_t i; - uint8_t j; - - /* check if the token string is present */ - if (str.pres == 1) { - j = 0; - - for (i = 0; i < str.len; i++) { - sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F)); - j++; - sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4)); - j++; - } - - /* if the odd flag is up the last digit is a fake "0" */ - if ((oddEven.pres == 1) && (oddEven.val == 1)) { - ftdm[j-1] = '\0'; - } else { - ftdm[j] = '\0'; - } - - - } else { - SS7_ERROR("Asked to copy tknStr that is not present!\n"); - return FTDM_FAIL; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven) -{ - int i = 0; - int j = 0; - - /* check if the token string is present */ - if (str.pres == 1) { - /* find the length of the digits so far */ - j = strlen(ftdm); - - /* confirm that we found an acceptable length */ - if ( j > 25 ) { - SS7_ERROR("string length exceeds maxium value...aborting append!\n"); - return FTDM_FAIL; - } /* if ( j > 25 ) */ - - /* copy in digits */ - for (i = 0; i < str.len; i++) { - /* convert 4 bit integer to char and copy into lower nibblet*/ - sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F)); - /* move along */ - j++; - /* convert 4 bit integer to char and copy into upper nibblet */ - sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4)); - /* move along */ - j++; - } /* for (i = 0; i < str.len; i++) */ - - /* if the odd flag is up the last digit is a fake "0" */ - if ((oddEven.pres == 1) && (oddEven.val == 1)) { - ftdm[j-1] = '\0'; - } else { - ftdm[j] = '\0'; - } /* if ((oddEven.pres == 1) && (oddEven.val == 1)) */ - } else { - SS7_ERROR("Asked to copy tknStr that is not present!\n"); - return FTDM_FAIL; - } /* if (str.pres == 1) */ - - return FTDM_SUCCESS; -} - - -ftdm_status_t copy_tknStr_to_sngss7(char* val, TknStr *tknStr, TknU8 *oddEven) -{ - char tmp[2]; - int k = 0; - int j = 0; - uint8_t flag = 0; - uint8_t odd = 0; - - uint8_t lower = 0x0; - uint8_t upper = 0x0; - - tknStr->pres = PRSNT_NODEF; - - /* atoi will search through memory starting from the pointer it is given until - * it finds the \0...since tmp is on the stack it will start going through the - * possibly causing corruption. Hard code a \0 to prevent this - */ - tmp[1] = '\0'; - - while (1) { - /* grab a digit from the ftdm digits */ - tmp[0] = val[k]; - - /* check if the digit is a number and that is not null */ - while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - if (tmp[0] == '*') { - /* Could not find a spec that specifies this , but on customer system, * was transmitted as 0x0b */ - SS7_DEBUG("Replacing * with 0x0b"); - k++; - tmp[0] = 0x0b; - } else { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - /* move on to the next value */ - k++; - tmp[0] = val[k]; - } - } /* while(!(isdigit(tmp))) */ - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push it into the lower nibble */ - lower = strtol(&tmp[0], (char **)NULL, 16); - /* move to the next digit */ - k++; - /* grab a digit from the ftdm digits */ - tmp[0] = val[k]; - - /* check if the digit is a number and that is not null */ - while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - k++; - tmp[0] = val[k]; - } /* while(!(isdigit(tmp))) */ - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push the digit into the upper nibble */ - upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4; - } else { - /* there is no upper ... fill in 0 */ - upper = 0x0; - /* throw the odd flag */ - odd = 1; - /* throw the end flag */ - flag = 1; - } /* if (tmp != '\0') */ - } else { - /* keep the odd flag down */ - odd = 0; - /* break right away since we don't need to write the digits */ - break; - } - - /* push the digits into the trillium structure */ - tknStr->val[j] = upper | lower; - - /* increment the trillium pointer */ - j++; - - /* if the flag is up we're through all the digits */ - if (flag) break; - - /* move to the next digit */ - k++; - } /* while(1) */ - - tknStr->len = j; - oddEven->pres = PRSNT_NODEF; - oddEven->val = odd; - return FTDM_SUCCESS; -} - - - -/******************************************************************************/ -int check_for_state_change(ftdm_channel_t *ftdmchan) -{ - - /* check to see if there are any pending state changes on the channel and give them a sec to happen*/ - ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 500); - - /* check the flag to confirm it is clear now */ - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - /* the flag is still up...so we have a problem */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "FTDM_CHANNEL_STATE_CHANGE flag set for over 500ms, channel state = %s\n", - ftdm_channel_state2str (ftdmchan->state)); - - return 1; - } - - return 0; -} - -/******************************************************************************/ -ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan) -{ - if (!g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj) { - SS7_ERROR("No ss7 info for circuit #%d\n", circuit); - return FTDM_FAIL; - } - - *sngss7_info = g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj; - - if (!(*sngss7_info)->ftdmchan) { - SS7_ERROR("No ftdmchan for circuit #%d\n", circuit); - return FTDM_FAIL; - } - - if (!(*sngss7_info)->ftdmchan->span) { - SS7_CRITICAL("ftdmchan->span = NULL for circuit #%d\n",circuit); - return FTDM_FAIL; - - } - if (!(*sngss7_info)->ftdmchan->span->signal_data) { - SS7_CRITICAL("ftdmchan->span->signal_data = NULL for circuit #%d\n",circuit); - return FTDM_FAIL; - - } - - *ftdmchan = (*sngss7_info)->ftdmchan; - return FTDM_SUCCESS; -} - -/******************************************************************************/ -int check_for_reset(sngss7_chan_data_t *sngss7_info) -{ - - if (sngss7_test_ckt_flag(sngss7_info,FLAG_RESET_RX)) { - return 1; - } - - if (sngss7_test_ckt_flag(sngss7_info,FLAG_RESET_TX)) { - return 1; - } - - if (sngss7_test_ckt_flag(sngss7_info,FLAG_GRP_RESET_RX)) { - return 1; - } - - if (sngss7_test_ckt_flag(sngss7_info,FLAG_GRP_RESET_TX)) { - return 1; - } - - return 0; - -} - -/******************************************************************************/ -unsigned long get_unique_id(void) -{ - int procId = sng_get_procId(); - - /* id values are between (procId * 1,000,000) and ((procId + 1) * 1,000,000) */ - if (sngss7_id < ((procId + 1) * 1000000) ) { - sngss7_id++; - } else { - sngss7_id = procId * 1000000; - } - - return(sngss7_id); -} - -/******************************************************************************/ -ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan) -{ - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_chan_data_t *cinfo = NULL; - int i = 0; - - iter = ftdm_span_get_chan_iterator(ftdmspan, NULL); - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *fchan = ftdm_iterator_current(curr); - - ftdm_channel_lock(fchan); - - cinfo = fchan->call_data; - - if (!cinfo->rx_grs.range) { - ftdm_channel_unlock(fchan); - continue; - } - - SS7_INFO("Rx GRS (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_grs.circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_grs.circuit].cic + cinfo->rx_grs.range)); - - for (i = cinfo->rx_grs.circuit; i < (cinfo->rx_grs.circuit + cinfo->rx_grs.range + 1); i++) { - - /* confirm this is a voice channel, otherwise we do nothing */ - if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) { - continue; - } - - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); - continue; - } - - /* check if the GRP_RESET_RX flag is already up */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) { - /* we have already processed this channel...move along */ - continue; - } - - /* lock the channel */ - ftdm_channel_lock(ftdmchan); - - /* clear up any pending state changes */ - while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change (ftdmchan); - } - - /* flag the channel as having received a reset */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_channel_unlock(ftdmchan); - - } - - ftdm_channel_unlock(fchan); - } - - ftdm_iterator_free(iter); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) -{ - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_chan_data_t *cinfo = NULL; - int i = 0, bn = 0; - int byte = 0, bit = 0; - int cic_start = 0, cic_end = 0, num_cics = 0; - ftdm_bitmap_t *lockmap = 0; - ftdm_size_t mapsize = 0; - - iter = ftdm_span_get_chan_iterator(ftdmspan, NULL); - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *fchan = ftdm_iterator_current(curr); - - ftdm_channel_lock(fchan); - - cinfo = fchan->call_data; - - if (!cinfo->rx_grs.range) { - - ftdm_channel_unlock(fchan); - - continue; - } - - cic_start = cinfo->rx_grs.circuit; - cic_end = cinfo->rx_grs.circuit + cinfo->rx_grs.range; - num_cics = cinfo->rx_grs.range + 1; - mapsize = (num_cics / FTDM_BITMAP_NBITS) + 1; - - lockmap = ftdm_calloc(mapsize, sizeof(*lockmap)); - if (!lockmap) { - ftdm_channel_unlock(fchan); - return FTDM_ENOMEM; - } - - /* check all the circuits in the range to see if they are done resetting */ - for (i = cic_start, bn = 0; i <= cic_end; i++, bn++) { - - /* confirm this is a voice channel, otherwise we do nothing */ - if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) { - continue; - } - - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); - ftdm_assert(FTDM_FALSE, "Failed to extract channel data during GRS\n"); - continue; - } - - /* lock the channel */ - ftdm_channel_lock(ftdmchan); - ftdm_map_set_bit(lockmap, bn); - - /* check if there is a state change pending on the channel */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - /* check the state to the GRP_RESET_RX_DN flag */ - if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { - /* this channel is still resetting...do nothing */ - goto GRS_UNLOCK_ALL; - } /* if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ - } else { - /* state change pending */ - goto GRS_UNLOCK_ALL; - } - - } - - SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n", cinfo->rx_grs.circuit, cinfo->rx_grs.range); - for (i = cic_start; i <= cic_end; i++) { - - /* confirm this is a voice channel, otherwise we do nothing */ - if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) { - continue; - } - - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i); - ftdm_assert(FTDM_FALSE, "Failed to extract channel data during GRS\n"); - continue; - } - - /* throw the GRP reset flag complete flag */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); - - /* move the channel to the down state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - /* update the status map if the ckt is in blocked state */ - if ((sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { - - cinfo->rx_grs.status[byte] = (cinfo->rx_grs.status[byte] | (1 << bit)); - } - - /* update the bit and byte counter*/ - bit ++; - if (bit == 8) { - byte++; - bit = 0; - } - - } -GRS_UNLOCK_ALL: - for (i = cic_start, bn = 0; i <= cic_end; i++, bn++) { - /* confirm this is a voice channel, otherwise we do nothing */ - if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) { - continue; - } - - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); - ftdm_assert(FTDM_FALSE, "Failed to extract channel data during GRS\n"); - continue; - } - if (ftdm_map_test_bit(lockmap, bn)) { - /* unlock the channel */ - ftdm_channel_unlock(ftdmchan); - ftdm_map_clear_bit(lockmap, bn); - } - } - - ftdm_safe_free(lockmap); - - ftdm_channel_unlock(fchan); - } - - ftdm_iterator_free(iter); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) -{ - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_chan_data_t *cinfo = NULL; - int i = 0; - - iter = ftdm_span_get_chan_iterator(ftdmspan, NULL); - - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *fchan = ftdm_iterator_current(curr); - ftdm_channel_lock(fchan); - - cinfo = fchan->call_data; - - if (!cinfo->rx_gra.range) { - - ftdm_channel_unlock(fchan); - - continue; - } - - SS7_INFO("Rx GRA (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_gra.circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_gra.circuit].cic + cinfo->rx_gra.range)); - - for (i = cinfo->rx_gra.circuit; i < (cinfo->rx_gra.circuit + cinfo->rx_gra.range + 1); i++) { - - /* confirm this is a voice channel, otherwise we do nothing */ - if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) { - continue; - } - - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); - continue; - } - - /* check if the channel is already processing the GRA */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { - /* move along */ - continue; - } - - /* lock the channel */ - ftdm_channel_lock(ftdmchan); - - /* clear up any pending state changes */ - while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change (ftdmchan); - } - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived GRA in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if (cinfo->rx_gra.cause != 0) { - ftdmchan->caller_data.hangup_cause = cinfo->rx_gra.cause; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - /* go to terminating to hang up the call */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - ftdm_channel_unlock(ftdmchan); - } - - ftdm_channel_unlock(fchan); - } - - ftdm_iterator_free(iter); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) -{ - ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_sigmsg_t sigev; - int x; - - for (x = 1; x < (ftdmspan->chan_count + 1); x++) { - - /* extract the channel structure and sngss7 channel data */ - ftdmchan = ftdmspan->channels[x]; - - /* if the call data is NULL move on */ - if (ftdmchan->call_data == NULL) continue; - - sngss7_info = ftdmchan->call_data; - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - memset (&sigev, 0, sizeof (sigev)); - - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - - /* if we have the PAUSED flag and the sig status is still UP */ - if ((sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) && - (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { - - /* clear up any pending state changes */ - while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change (ftdmchan); - } - - /* throw the channel into SUSPENDED to process the flag */ - /* after doing this once the sig status will be down */ - ftdm_set_state (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - /* if the RESUME flag is up go to SUSPENDED to process the flag */ - /* after doing this the flag will be cleared */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { - - /* clear up any pending state changes */ - while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change (ftdmchan); - } - - /* got SUSPENDED state to clear the flag */ - ftdm_set_state (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* for (x = 1; x < (span->chan_count + 1); x++) */ - - /* signal the core that sig events are queued for processing */ - ftdm_span_trigger_signals(ftdmspan); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan) -{ - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - sngss7_chan_data_t *cinfo = NULL; - sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data; - int i = 0; - - iter = ftdm_span_get_chan_iterator(ftdmspan, NULL); - curr = iter; - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *fchan = ftdm_iterator_current(curr); - - ftdm_channel_lock(fchan); - - cinfo = fchan->call_data; - - if (!cinfo->ucic.range) { - - ftdm_channel_unlock(fchan); - - continue; - } - - for (i = cinfo->ucic.circuit; i < (cinfo->ucic.circuit + cinfo->ucic.range + 1); i++) { - - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); - continue; - } - - /* lock the channel */ - ftdm_channel_lock(ftdmchan); - - SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx Span UCIC\n", sngss7_info->circuit->cic); - - /* clear up any pending state changes */ - while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change (ftdmchan); - } - - /* throw the ckt block flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); - - /* set the channel to suspended state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_channel_unlock(ftdmchan); - } - /* clear out the ucic data since we're done with it */ - memset(&cinfo->ucic, 0, sizeof(cinfo->ucic)); - - ftdm_channel_unlock(fchan); - } - - ftdm_clear_flag(sngss7_span, SNGSS7_UCIC_PENDING); - - ftdm_iterator_free(iter); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info) -{ - /* clear all the flags related to an incoming GRS */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); - sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info) -{ - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - sngss7_chan_data_t *cinfo = NULL; - ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmchan->span->signal_data; - - memset(&sngss7_info->rx_grs, 0, sizeof(sngss7_info->rx_grs)); - - iter = ftdm_span_get_chan_iterator(ftdmchan->span, NULL); - curr = iter; - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *fchan = ftdm_iterator_current(curr); - - ftdm_channel_lock(fchan); - - cinfo = fchan->call_data; - if (cinfo->rx_grs.range) { - /* there is still another grs pending, do not clear the SNGSS7_RX_GRS_PENDING flag yet */ - ftdm_channel_unlock(fchan); - goto done; - } - - ftdm_channel_unlock(fchan); - } - - /* if we're here is because there is no other grs going on now in this span */ - ftdm_clear_flag(sngss7_span, SNGSS7_RX_GRS_PENDING); - -done: - ftdm_iterator_free(iter); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info) -{ - ftdm_iterator_t *iter = NULL; - ftdm_iterator_t *curr = NULL; - sngss7_chan_data_t *cinfo = NULL; - ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data; - - /* clear the rx_grs data fields */ - memset(&sngss7_info->rx_gra, 0, sizeof(sngss7_info->rx_gra)); - - iter = ftdm_span_get_chan_iterator(ftdmchan->span, NULL); - curr = iter; - for (curr = iter; curr; curr = ftdm_iterator_next(curr)) { - ftdm_channel_t *fchan = ftdm_iterator_current(curr); - - ftdm_channel_lock(fchan); - - cinfo = fchan->call_data; - if (cinfo->rx_gra.range) { - /* there is still another gra pending, do not clear the SNGSS7_RX_GRA_PENDING flag yet */ - ftdm_channel_unlock(fchan); - goto done; - } - - ftdm_channel_unlock(fchan); - } - - /* if we're here is because there is no other gra pending in this span */ - ftdm_clear_flag(sngss7_span, SNGSS7_RX_GRA_PENDING); - -done: - - ftdm_iterator_free(iter); - - return FTDM_SUCCESS; -} -/******************************************************************************/ -ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info) -{ - /* clear all the flags related to an outgoing GRS */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE); - sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT); - sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info) -{ - /* clear everything up */ - memset(&sngss7_info->tx_grs, 0, sizeof(sngss7_info->tx_grs)); - return FTDM_SUCCESS; -} - -/******************************************************************************/ - -/******************************************************************************/ -ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info) -{ - /* clear all the flags related to an incoming RSC */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_RX); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info) -{ - /* clear all the flags related to an outgoing RSC */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_TX); - sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_SENT); - sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type) -{ - /* Q931 4.5.9 - * 8 7 6 5 4 3 2 1 (octet) - * - * 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7) - * X X X X X X X X (length of IE contents) - * 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3) - * X X X X X X X X (sub address encoded in ia5) - */ - - int x = 0; - int p = 0; - int len = 0; - char tmp[2]; - - /* initalize the second element of tmp to \0 so that atoi doesn't go to far */ - tmp[1]='\0'; - - /* set octet 1 aka IE id */ - p = 0; - switch(type) { - /**************************************************************************/ - case SNG_CALLED: /* called party sub address */ - subAddrIE[p] = 0x71; - break; - /**************************************************************************/ - case SNG_CALLING: /* calling party sub address */ - subAddrIE[p] = 0x6d; - break; - /**************************************************************************/ - default: /* not good */ - SS7_ERROR("Sub-Address type is invalid: %d\n", type); - return FTDM_FAIL; - break; - /**************************************************************************/ - } /* switch(type) */ - - /* set octet 3 aka type and o/e */ - p = 2; - subAddrIE[p] = 0x80; - - /* set the subAddrIE pointer octet 4 */ - p = 3; - - /* loop through all digits in subAddr and insert them into subAddrIE */ - while (subAddr[x] != '\0') { - - /* grab a character */ - tmp[0] = subAddr[x]; - - /* confirm it is a digit */ - if (!isdigit(tmp[0])) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - /* move to the next character in subAddr */ - x++; - - /* restart the loop */ - continue; - } - - /* convert the character to IA5 encoding and write into subAddrIE */ - subAddrIE[p] = atoi(&tmp[0]); /* lower nibble is the digit */ - subAddrIE[p] |= 0x3 << 4; /* upper nibble is 0x3 */ - - /* increment address length counter */ - len++; - - /* increment the subAddrIE pointer */ - p++; - - /* move to the next character in subAddr */ - x++; - - } /* while (subAddr[x] != '\0') */ - - /* set octet 2 aka length of subaddr */ - p = 1; - subAddrIE[p] = len + 1; - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type) -{ - /* Q931 4.5.9 - * 8 7 6 5 4 3 2 1 (octet) - * - * 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7) - * X X X X X X X X (length of IE contents) - * 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3) - * X X X X X X X X (sub address encoded in ia5) - */ - - int x = 0; - int p = 0; - int len = 0; - char tmp[2]; - int flag = 0; - int odd = 0; - uint8_t lower = 0x0; - uint8_t upper = 0x0; - - /* initalize the second element of tmp to \0 so that atoi doesn't go to far */ - tmp[1]='\0'; - - /* set octet 1 aka IE id */ - p = 0; - switch(type) { - /**************************************************************************/ - case SNG_CALLED: /* called party sub address */ - subAddrIE[p] = 0x71; - break; - /**************************************************************************/ - case SNG_CALLING: /* calling party sub address */ - subAddrIE[p] = 0x6d; - break; - /**************************************************************************/ - default: /* not good */ - SS7_ERROR("Sub-Address type is invalid: %d\n", type); - return FTDM_FAIL; - break; - /**************************************************************************/ - } /* switch(type) */ - - /* set the subAddrIE pointer octet 4 */ - p = 3; - - /* loop through all digits in subAddr and insert them into subAddrIE */ - while (1) { - - /* grab a character */ - tmp[0] = subAddr[x]; - - /* confirm it is a hex digit */ - while ((!isxdigit(tmp[0])) && (tmp[0] != '\0')) { - if (tmp[0] == '*') { - /* Could not find a spec that specifies this, but on customer system, * was transmitted as 0x0b */ - SS7_DEBUG("Replacing * with 0x0b"); - x++; - tmp[0] = 0x0b; - } else { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - /* move to the next character in subAddr */ - x++; - tmp[0] = subAddr[x]; - } - } - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push it into the lower nibble using strtol to allow a-f chars */ - lower = strtol(&tmp[0], (char **)NULL, 16); - /* move to the next digit */ - x++; - /* grab a digit from the ftdm digits */ - tmp[0] = subAddr[x]; - - /* check if the digit is a hex digit and that is not null */ - while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - x++; - tmp[0] = subAddr[x]; - } /* while(!(isdigit(tmp))) */ - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push the digit into the upper nibble using strtol to allow a-f chars */ - upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4; - } else { - /* there is no upper ... fill in spare */ - upper = 0x00; - /* throw the odd flag since we need to buffer */ - odd = 1; - /* throw the end flag */ - flag = 1; - } /* if (tmp != '\0') */ - } else { - /* keep the odd flag down */ - odd = 0; - - /* throw the flag */ - flag = 1; - - /* bounce out right away */ - break; - } - - /* fill in the octet */ - subAddrIE[p] = upper | lower; - - /* increment address length counter */ - len++; - - /* if the flag is we're through all the digits */ - if (flag) break; - - /* increment the subAddrIE pointer */ - p++; - - /* move to the next character in subAddr */ - x++; - - } /* while (subAddr[x] != '\0') */ - - /* set octet 2 aka length of subaddr */ - p = 1; - subAddrIE[p] = len + 1; - - /* set octet 3 aka type and o/e */ - p = 2; - subAddrIE[p] = 0xa0 | (odd << 3); - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -int find_mtp2_error_type_in_map(const char *err_type) -{ - int i = 0; - - while (sng_mtp2_error_type_map[i].init == 1) { - /* check if string matches the sng_type name */ - if (!strcasecmp(err_type, sng_mtp2_error_type_map[i].sng_type)) { - /* we've found a match break from the loop */ - break; - } else { - /* move on to the next on */ - i++; - } - } /* while (sng_mtp2_error_type_map[i].init == 1) */ - - /* check how we exited the loop */ - if (sng_mtp2_error_type_map[i].init == 0) { - return -1; - } else { - return i; - } /* if (sng_mtp2_error_type_map[i].init == 0) */ -} - -/******************************************************************************/ -int find_link_type_in_map(const char *linkType) -{ - int i = 0; - - while (sng_link_type_map[i].init == 1) { - /* check if string matches the sng_type name */ - if (!strcasecmp(linkType, sng_link_type_map[i].sng_type)) { - /* we've found a match break from the loop */ - break; - } else { - /* move on to the next on */ - i++; - } - } /* while (sng_link_type_map[i].init == 1) */ - - /* check how we exited the loop */ - if (sng_link_type_map[i].init == 0) { - return -1; - } else { - return i; - } /* if (sng_link_type_map[i].init == 0) */ -} - -/******************************************************************************/ -int find_switch_type_in_map(const char *switchType) -{ - int i = 0; - - while (sng_switch_type_map[i].init == 1) { - /* check if string matches the sng_type name */ - if (!strcasecmp(switchType, sng_switch_type_map[i].sng_type)) { - /* we've found a match break from the loop */ - break; - } else { - /* move on to the next on */ - i++; - } - } /* while (sng_switch_type_map[i].init == 1) */ - - /* check how we exited the loop */ - if (sng_switch_type_map[i].init == 0) { - return -1; - } else { - return i; - } /* if (sng_switch_type_map[i].init == 0) */ -} - -/******************************************************************************/ -int find_ssf_type_in_map(const char *ssfType) -{ - int i = 0; - - while (sng_ssf_type_map[i].init == 1) { - /* check if string matches the sng_type name */ - if (!strcasecmp(ssfType, sng_ssf_type_map[i].sng_type)) { - /* we've found a match break from the loop */ - break; - } else { - /* move on to the next on */ - i++; - } - } /* while (sng_ssf_type_map[i].init == 1) */ - - /* check how we exited the loop */ - if (sng_ssf_type_map[i].init == 0) { - return -1; - } else { - return i; - } /* if (sng_ssf_type_map[i].init == 0) */ -} - -/******************************************************************************/ -int find_cic_cntrl_in_map(const char *cntrlType) -{ - int i = 0; - - while (sng_cic_cntrl_type_map[i].init == 1) { - /* check if string matches the sng_type name */ - if (!strcasecmp(cntrlType, sng_cic_cntrl_type_map[i].sng_type)) { - /* we've found a match break from the loop */ - break; - } else { - /* move on to the next on */ - i++; - } - } /* while (sng_cic_cntrl_type_map[i].init == 1) */ - - /* check how we exited the loop */ - if (sng_cic_cntrl_type_map[i].init == 0) { - return -1; - } else { - return i; - } /* if (sng_cic_cntrl_type_map[i].init == 0) */ -} - -/******************************************************************************/ -ftdm_status_t check_status_of_all_isup_intf(void) -{ - sng_isup_inf_t *sngss7_intf = NULL; - uint8_t status = 0xff; - int x; - - /* go through all the isupIntfs and ask the stack to give their current state */ - x = 1; - for (x = 1; x < (MAX_ISUP_INFS); x++) { - /**************************************************************************/ - - if (g_ftdm_sngss7_data.cfg.isupIntf[x].id == 0) continue; - - sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[x]; - - if (ftmod_ss7_isup_intf_sta(sngss7_intf->id, &status)) { - SS7_ERROR("Failed to get status of ISUP intf %d\n", sngss7_intf->id); - sngss7_set_flag(sngss7_intf, SNGSS7_PAUSED); - continue; - } - - switch (status){ - /**********************************************************************/ - case (SI_INTF_AVAIL): - SS7_DEBUG("State of ISUP intf %d = AVAIL\n", sngss7_intf->id); - - /* check the current state for interface that we know */ - if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - /* we thing the intf is paused...put into resume */ - sngss7_clear_flag(sngss7_intf, SNGSS7_PAUSED); - } else { - /* nothing to since we already know that interface is active */ - } - break; - /**********************************************************************/ - case (SI_INTF_UNAVAIL): - SS7_DEBUG("State of ISUP intf %d = UNAVAIL\n", sngss7_intf->id); - /* check the current state for interface that we know */ - if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - /* nothing to since we already know that interface is active */ - } else { - /* put the interface into pause */ - sngss7_set_flag(sngss7_intf, SNGSS7_PAUSED); - } - break; - /**********************************************************************/ - case (SI_INTF_CONG1): - SS7_DEBUG("State of ISUP intf %d = Congestion 1\n", sngss7_intf->id); - break; - /**********************************************************************/ - case (SI_INTF_CONG2): - SS7_DEBUG("State of ISUP intf %d = Congestion 2\n", sngss7_intf->id); - break; - /**********************************************************************/ - case (SI_INTF_CONG3): - SS7_DEBUG("State of ISUP intf %d = Congestion 3\n", sngss7_intf->id); - break; - /**********************************************************************/ - default: - /* should do something here to handle the possiblity of an unknown case */ - SS7_ERROR("Unknown ISUP intf Status code (%d) for Intf = %d\n", status, sngss7_intf->id); - break; - /**********************************************************************/ - } /* switch (status) */ - - /**************************************************************************/ - } /* for (x = 1; x < MAX_ISUP_INFS); i++) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t sngss7_add_var(sngss7_chan_data_t *sngss7_info, const char* var, const char* val) -{ - char *t_name = 0; - char *t_val = 0; - - /* confirm the user has sent us a value */ - if (!var || !val) { - return FTDM_FAIL; - } - - if (!sngss7_info->variables) { - /* initialize on first use */ - sngss7_info->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - ftdm_assert_return(sngss7_info->variables, FTDM_FAIL, "Failed to create hash table\n"); - } - - t_name = ftdm_strdup(var); - t_val = ftdm_strdup(val); - - hashtable_insert(sngss7_info->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data, ftdm_size_t data_len) -{ - ftdm_assert_return(!sngss7_info->raw_data, FTDM_FAIL, "Overwriting existing raw data\n"); - - sngss7_info->raw_data = ftdm_calloc(1, data_len); - ftdm_assert_return(sngss7_info->raw_data, FTDM_FAIL, "Failed to allocate raw data\n"); - - memcpy(sngss7_info->raw_data, data, data_len); - sngss7_info->raw_data_len = data_len; - return FTDM_SUCCESS; -} - -/******************************************************************************/ -void sngss7_send_signal(sngss7_chan_data_t *sngss7_info, ftdm_signal_event_t event_id) -{ - ftdm_sigmsg_t sigev; - ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - - memset(&sigev, 0, sizeof(sigev)); - - sigev.chan_id = ftdmchan->chan_id; - sigev.span_id = ftdmchan->span_id; - sigev.channel = ftdmchan; - sigev.event_id = event_id; - - if (sngss7_info->variables) { - /* - * variables now belongs to the ftdm core, and - * will be cleared after sigev is processed by user. Set - * local pointer to NULL so we do not attempt to - * destroy it */ - sigev.variables = sngss7_info->variables; - sngss7_info->variables = NULL; - } - - if (sngss7_info->raw_data) { - /* - * raw_data now belongs to the ftdm core, and - * will be cleared after sigev is processed by user. Set - * local pointer to NULL so we do not attempt to - * destroy it */ - - sigev.raw.data = sngss7_info->raw_data; - sigev.raw.len = sngss7_info->raw_data_len; - - sngss7_info->raw_data = NULL; - sngss7_info->raw_data_len = 0; - } - ftdm_span_send_signal(ftdmchan->span, &sigev); -} - -/******************************************************************************/ -void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_status_t status) -{ - ftdm_sigmsg_t sig; - ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", - ftdm_signaling_status2str(status)); - - memset(&sig, 0, sizeof(sig)); - - sig.chan_id = ftdmchan->chan_id; - sig.span_id = ftdmchan->span_id; - sig.channel = ftdmchan; - sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.ev_data.sigstatus.status = status; - - if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", - ftdm_signaling_status2str(status)); - } - return; -} - -#if 0 -ftdm_status_t check_for_invalid_states(ftdm_channel_t *ftmchan) -{ - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - if (!sngss7_info) { - SS7_WARN_CHAN(ftdmchan, "Found ftdmchan with no sig module data!%s\n", " "); - return FTDM_FAIL; - } - - if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - return FTDM_SUCCESS; - } - - switch (ftdmchan->state) { - case UP: - case DOWN: - return FTDM_SUCCESS; - - default: - if ((ftdm_current_time_in_ms() - ftdmchan->last_state_change_time) > 30000) { - SS7_WARN_CHAN(ftdmchan, "Circuite in state=%s too long - resetting!%s\n", - ftdm_channel_state2str(ftdmchan->state)); - - ftdm_channel_lock(ftdmchan); - - if (sngss7_channel_status_clear(sngss7_info)) { - sngss7_tx_reset_restart(sngss7_info); - - if (ftdmchan->state == FTDM_CHANNEL_STATE_RESTART) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } else { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - } - } else { - - } - - - - ftdm_channel_unlock(ftdmchan); - } - } - - return FTDM_SUCCESS; -} -#endif - - -/******************************************************************************/ -ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan) -{ - ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; - sng_isup_inf_t *sngss7_intf = NULL; - uint8_t state; - uint8_t bits_ab = 0; - uint8_t bits_cd = 0; - uint8_t bits_ef = 0; - int x; - int ret; - ret=0; - - for (x = 1; x < (ftdmspan->chan_count + 1); x++) { - /**************************************************************************/ - /* extract the channel structure and sngss7 channel data */ - ftdmchan = ftdmspan->channels[x]; - - /* if the call data is NULL move on */ - if (ftdmchan->call_data == NULL) { - SS7_WARN_CHAN(ftdmchan, "Found ftdmchan with no sig module data!%s\n", " "); - continue; - } - - /* grab the private data */ - sngss7_info = ftdmchan->call_data; - - /* check the reconfig flag */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_RECONFIG)) { - /* confirm the state of all isup interfaces*/ - check_status_of_all_isup_intf(); - - sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; - - /* check if the interface is paused or resumed */ - if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Circuit set to PAUSED %s\n"," "); - /* throw the pause flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - } else { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Circuit set to RESUMED %s\n"," "); - /* throw the resume flag */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); - } - - /* query for the status of the ckt */ - if (ftmod_ss7_isup_ckt_sta(sngss7_info->circuit->id, &state)) { - /* NC: Circuit statistic failed: does not exist. Must re-configure circuit - Reset the circuit CONFIGURED flag so that RESUME will reconfigure - this circuit. */ - sngss7_info->circuit->flags &= ~SNGSS7_CONFIGURED; - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR,"Failed to read isup ckt = %d status\n", sngss7_info->circuit->id); - continue; - } - - /* extract the bit sections */ - bits_ab = (state & (SNG_BIT_A + SNG_BIT_B)) >> 0; - bits_cd = (state & (SNG_BIT_C + SNG_BIT_D)) >> 2; - bits_ef = (state & (SNG_BIT_E + SNG_BIT_F)) >> 4; - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Circuit state=0x%X ab=0x%X cd=0x%X ef=0x%X\n",state,bits_ab,bits_cd,bits_ef); - - if (bits_cd == 0x0) { - /* check if circuit is UCIC or transient */ - if (bits_ab == 0x3) { - SS7_INFO("ISUP CKT %d re-configuration pending!\n", x); - sngss7_info->circuit->flags &= ~SNGSS7_CONFIGURED; - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* NC: The code below should be deleted. Its here for hitorical - reason. The RESUME code will reconfigure the channel since - the CONFIGURED flag has been reset */ -#if 0 - /* bit a and bit b are set, unequipped */ - ret = ftmod_ss7_isup_ckt_config(sngss7_info->circuit->id); - if (ret) { - SS7_CRITICAL("ISUP CKT %d re-configuration FAILED!\n",x); - } else { - SS7_INFO("ISUP CKT %d re-configuration DONE!\n", x); - } - - /* reset the circuit to sync states */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* flag the circuit as active */ - sngss7_set_flag(sngss7_info->circuit, SNGSS7_ACTIVE); - - /* throw the channel into reset */ - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); - - /* throw the channel to suspend */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); -#endif - - } else { /* if (bits_ab == 0x3) */ - /* The stack status is not blocked. However this is possible if - the circuit state was UP. So even though Master sent out the BLO - the status command is not showing it. - - As a kudge. We will try to send out an UBL even though the status - indicates that there is no BLO. */ - if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX); - - /* set the channel to suspended state */ - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - } - } else { - /* check the maintenance block status in bits A and B */ - switch (bits_ab) { - /**************************************************************************/ - case (0): - /* no maintenace block...do nothing */ - break; - /**************************************************************************/ - case (1): - /* The stack status is Blocked. Check if the block was sent - by user via console. If the block was not sent by user then, it - was sent out by Master due to relay down. - Therefore send out the unblock to clear it */ - if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX); - - /* set the channel to suspended state */ - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - /* Only locally blocked, thus remove a remote block */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - - break; - /**************************************************************************/ - case (2): - /* remotely blocked */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - - /* set the channel to suspended state */ - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - break; - /**************************************************************************/ - case (3): - /* both locally and remotely blocked */ - if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX); - } - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); - - /* set the channel to suspended state */ - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - break; - /**************************************************************************/ - default: - break; - /**************************************************************************/ - } /* switch (bits_ab) */ - - /* check the hardware block status in bits e and f */ - switch (bits_ef) { - /**************************************************************************/ - case (0): - /* no maintenace block...do nothing */ - break; - /**************************************************************************/ - case (1): - /* locally blocked */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX); - - /* set the channel to suspended state */ - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - break; - /**************************************************************************/ - case (2): - /* remotely blocked */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - - /* set the channel to suspended state */ - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - break; - /**************************************************************************/ - case (3): - /* both locally and remotely blocked */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX); - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - - /* set the channel to suspended state */ - SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - break; - /**************************************************************************/ - default: - break; - /**************************************************************************/ - } /* switch (bits_ef) */ - } - - /* clear the re-config flag ... no matter what */ - sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_RECONFIG); - - } - } /* for (x = 1; x < (span->chan_count + 1); x++) */ - - return FTDM_SUCCESS; -} - -ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt) -{ - if (siConEvnt->natConInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natConInd, 0, sizeof(siConEvnt->natConInd)); - if (siConEvnt->fwdCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdCallInd, 0, sizeof(siConEvnt->fwdCallInd)); - if (siConEvnt->cgPtyCat.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyCat, 0, sizeof(siConEvnt->cgPtyCat)); - if (siConEvnt->txMedReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedReq, 0, sizeof(siConEvnt->txMedReq)); -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - if (siConEvnt->usrServInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfoA, 0, sizeof(siConEvnt->usrServInfoA)); -#endif - if (siConEvnt->cdPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdPtyNum, 0, sizeof(siConEvnt->cdPtyNum)); -#if TNS_ANSI -#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL) - if (siConEvnt->tranNetSel1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel1, 0, sizeof(siConEvnt->tranNetSel1)); -#endif -#endif - if (siConEvnt->tranNetSel.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel, 0, sizeof(siConEvnt->tranNetSel)); -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA) - if (siConEvnt->callRefA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRefA, 0, sizeof(siConEvnt->callRefA)); -#endif - if (siConEvnt->callRef.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRef, 0, sizeof(siConEvnt->callRef)); - if (siConEvnt->cgPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum, 0, sizeof(siConEvnt->cgPtyNum)); -#if SS7_BELL - if (siConEvnt->cgPtyNumB.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumB, 0, sizeof(siConEvnt->cgPtyNumB)); -#endif - if (siConEvnt->opFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalInd, 0, sizeof(siConEvnt->opFwdCalInd)); -#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT) - if (siConEvnt->opFwdCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndQ, 0, sizeof(siConEvnt->opFwdCalIndQ)); -#endif -#if SS7_Q767IT - if (siConEvnt->fwdVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdVad, 0, sizeof(siConEvnt->fwdVad)); -#endif -#if SS7_ANS88 - if (siConEvnt->opFwdCalIndA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndA, 0, sizeof(siConEvnt->opFwdCalIndA)); -#endif - if (siConEvnt->redirgNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirgNum, 0, sizeof(siConEvnt->redirgNum)); - if (siConEvnt->redirInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfo, 0, sizeof(siConEvnt->redirInfo)); - if (siConEvnt->cugIntCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCode, 0, sizeof(siConEvnt->cugIntCode)); -#if SS7_ANS88 - if (siConEvnt->cugIntCodeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCodeA, 0, sizeof(siConEvnt->cugIntCodeA)); -#endif -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA) - if (siConEvnt->connReqA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReqA, 0, sizeof(siConEvnt->connReqA)); -#endif -#if SS7_ANS88 - if (siConEvnt->usr2UsrInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfoA, 0, sizeof(siConEvnt->usr2UsrInfoA)); -#endif - if (siConEvnt->connReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReq, 0, sizeof(siConEvnt->connReq)); - if (siConEvnt->origCdNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCdNum, 0, sizeof(siConEvnt->origCdNum)); - if (siConEvnt->usr2UsrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfo, 0, sizeof(siConEvnt->usr2UsrInfo)); - if (siConEvnt->accTrnspt.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accTrnspt, 0, sizeof(siConEvnt->accTrnspt)); - if (siConEvnt->echoControl.eh.pres != PRSNT_NODEF) memset(&siConEvnt->echoControl, 0, sizeof(siConEvnt->echoControl)); -#if SS7_ANS88 - if (siConEvnt->redirInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfoA, 0, sizeof(siConEvnt->redirInfoA)); -#endif -#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - if (siConEvnt->chargeNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->chargeNum, 0, sizeof(siConEvnt->chargeNum)); - if (siConEvnt->origLineInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origLineInf, 0, sizeof(siConEvnt->origLineInf)); -#endif - if (siConEvnt->usrServInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo, 0, sizeof(siConEvnt->usrServInfo)); - if (siConEvnt->usr2UsrInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInd, 0, sizeof(siConEvnt->usr2UsrInd)); - if (siConEvnt->propDly.eh.pres != PRSNT_NODEF) memset(&siConEvnt->propDly, 0, sizeof(siConEvnt->propDly)); - if (siConEvnt->usrServInfo1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo1, 0, sizeof(siConEvnt->usrServInfo1)); - if (siConEvnt->netFac.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netFac, 0, sizeof(siConEvnt->netFac)); -#ifdef SS7_CHINA - if (siConEvnt->orgPteCdeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCdeA, 0, sizeof(siConEvnt->orgPteCdeA)); -#endif - if (siConEvnt->orgPteCde.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCde, 0, sizeof(siConEvnt->orgPteCde)); - if (siConEvnt->genDigits.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigits, 0, sizeof(siConEvnt->genDigits)); - if (siConEvnt->genDigitsR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigitsR, 0, sizeof(siConEvnt->genDigitsR)); - if (siConEvnt->usrTSrvInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrTSrvInfo, 0, sizeof(siConEvnt->usrTSrvInfo)); - if (siConEvnt->remotOper.eh.pres != PRSNT_NODEF) memset(&siConEvnt->remotOper, 0, sizeof(siConEvnt->remotOper)); - if (siConEvnt->parmCom.eh.pres != PRSNT_NODEF) memset(&siConEvnt->parmCom, 0, sizeof(siConEvnt->parmCom)); -#if (SS7_ANS92 || SS7_ANS95) - if (siConEvnt->servCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->servCode, 0, sizeof(siConEvnt->servCode)); -#endif -#if SS7_ANS92 - if (siConEvnt->serviceAct1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct1, 0, sizeof(siConEvnt->serviceAct1)); -#endif -#if SS7_CHINA - if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2)); -#endif - if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2)); - if (siConEvnt->serviceAct.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct, 0, sizeof(siConEvnt->serviceAct)); - if (siConEvnt->mlppPrec.eh.pres != PRSNT_NODEF) memset(&siConEvnt->mlppPrec, 0, sizeof(siConEvnt->mlppPrec)); -#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT)) - if (siConEvnt->txMedUsPr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedUsPr, 0, sizeof(siConEvnt->txMedUsPr)); -#endif - if (siConEvnt->bckCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->bckCallInd, 0, sizeof(siConEvnt->bckCallInd)); - if (siConEvnt->cgPtyNum1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum1, 0, sizeof(siConEvnt->cgPtyNum1)); - if (siConEvnt->optBckCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalInd, 0, sizeof(siConEvnt->optBckCalInd)); -#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT) - if (siConEvnt->optBckCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalIndQ, 0, sizeof(siConEvnt->optBckCalIndQ)); -#endif - if (siConEvnt->connNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum, 0, sizeof(siConEvnt->connNum)); -#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT)) - if (siConEvnt->connNum2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum2, 0, sizeof(siConEvnt->connNum2)); -#endif - if (siConEvnt->accDelInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accDelInfo, 0, sizeof(siConEvnt->accDelInfo)); - if (siConEvnt->notifInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd, 0, sizeof(siConEvnt->notifInd)); - if (siConEvnt->notifIndR2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR2, 0, sizeof(siConEvnt->notifIndR2)); - if (siConEvnt->cllHstry.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cllHstry, 0, sizeof(siConEvnt->cllHstry)); - if (siConEvnt->genNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmb, 0, sizeof(siConEvnt->genNmb)); - if (siConEvnt->genNmbR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmbR, 0, sizeof(siConEvnt->genNmbR)); - if (siConEvnt->redirNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirNum, 0, sizeof(siConEvnt->redirNum)); - if (siConEvnt->redirRstr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirRstr, 0, sizeof(siConEvnt->redirRstr)); - -#if SS7_Q767IT - if (siConEvnt->backVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backVad, 0, sizeof(siConEvnt->backVad)); -#endif -#if SS7_SINGTEL - if (siConEvnt->cgPtyNumS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumS, 0, sizeof(siConEvnt->cgPtyNumS)); -#endif -#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL) - if (siConEvnt->businessGrp.eh.pres != PRSNT_NODEF) memset(&siConEvnt->businessGrp, 0, sizeof(siConEvnt->businessGrp)); - if (siConEvnt->infoInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoInd, 0, sizeof(siConEvnt->infoInd)); - if (siConEvnt->carrierId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierId, 0, sizeof(siConEvnt->carrierId)); - if (siConEvnt->carSelInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carSelInf, 0, sizeof(siConEvnt->carSelInf)); - if (siConEvnt->egress.eh.pres != PRSNT_NODEF) memset(&siConEvnt->egress, 0, sizeof(siConEvnt->egress)); - if (siConEvnt->genAddr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddr, 0, sizeof(siConEvnt->genAddr)); - if (siConEvnt->genAddrR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddrR, 0, sizeof(siConEvnt->genAddrR)); - if (siConEvnt->infoReqInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoReqInd, 0, sizeof(siConEvnt->infoReqInd)); - if (siConEvnt->jurisInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->jurisInf, 0, sizeof(siConEvnt->jurisInf)); - if (siConEvnt->netTransport.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netTransport, 0, sizeof(siConEvnt->netTransport)); - if (siConEvnt->specProcReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->specProcReq, 0, sizeof(siConEvnt->specProcReq)); - if (siConEvnt->transReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->transReq, 0, sizeof(siConEvnt->transReq)); -#endif -#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT)) -#if (SS7_ANS92 || SS7_ANS95) - if (siConEvnt->notifInd1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd1, 0, sizeof(siConEvnt->notifInd1)); - if (siConEvnt->notifIndR1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR1, 0, sizeof(siConEvnt->notifIndR1)); -#endif /* SS7_ANS92 */ -#endif /* SIT_PARAMETER || TDS_ROLL_UPGRADE_SUPPORT */ -#if (SS7_BELL || SS7_ANS95) - if (siConEvnt->genName.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genName, 0, sizeof(siConEvnt->genName)); -#endif -#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \ - SS7_BELL || SS7_ANS95 || SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ) - if (siConEvnt->hopCounter.eh.pres != PRSNT_NODEF) memset(&siConEvnt->hopCounter, 0, sizeof(siConEvnt->hopCounter)); -#endif -#if (SS7_BELL || SS7_ITU2000 || SS7_KZ) - if (siConEvnt->redirCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCap, 0, sizeof(siConEvnt->redirCap)); - if (siConEvnt->redirCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCntr, 0, sizeof(siConEvnt->redirCntr)); -#endif -#if (SS7_ETSI || SS7_FTZ) - if (siConEvnt->ccbsParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccbsParam, 0, sizeof(siConEvnt->ccbsParam)); - if (siConEvnt->freePhParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->freePhParam, 0, sizeof(siConEvnt->freePhParam)); -#endif -#ifdef SS7_FTZ - if (siConEvnt->naPaFF.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFF, 0, sizeof(siConEvnt->naPaFF)); - if (siConEvnt->naPaFE.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFE, 0, sizeof(siConEvnt->naPaFE)); - if (siConEvnt->naPaSSP.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSSP, 0, sizeof(siConEvnt->naPaSSP)); - if (siConEvnt->naPaCdPNO.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaCdPNO, 0, sizeof(siConEvnt->naPaCdPNO)); - if (siConEvnt->naPaSPV.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSPV, 0, sizeof(siConEvnt->naPaSPV)); - if (siConEvnt->naPaUKK.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaUKK, 0, sizeof(siConEvnt->naPaUKK)); -#endif -#if SS7_NTT - if (siConEvnt->msgAreaInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->msgAreaInfo, 0, sizeof(siConEvnt->msgAreaInfo)); - if (siConEvnt->subsNumber.eh.pres != PRSNT_NODEF) memset(&siConEvnt->subsNumber, 0, sizeof(siConEvnt->subsNumber)); - if (siConEvnt->rpCllngNo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->rpCllngNo, 0, sizeof(siConEvnt->rpCllngNo)); - if (siConEvnt->supplUserType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->supplUserType, 0, sizeof(siConEvnt->supplUserType)); - if (siConEvnt->carrierInfoTrans.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierInfoTrans, 0, sizeof(siConEvnt->carrierInfoTrans)); - if (siConEvnt->nwFuncType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->nwFuncType, 0, sizeof(siConEvnt->nwFuncType)); -#endif -#if SS7_ANS95 - if (siConEvnt->optrServicesInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optrServicesInfo, 0, sizeof(siConEvnt->optrServicesInfo)); -#endif -#if (SS7_ANS95 || SS7_ITU97 || SS7_RUSS2000|| SS7_ITU2000 || SS7_NZL || SS7_KZ) - if (siConEvnt->cirAsgnMap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cirAsgnMap, 0, sizeof(siConEvnt->cirAsgnMap)); -#endif -#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \ - SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ) - if (siConEvnt->displayInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->displayInfo, 0, sizeof(siConEvnt->displayInfo)); - if (siConEvnt->confTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->confTrtInd, 0, sizeof(siConEvnt->confTrtInd)); - if (siConEvnt->netMgmtControls.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netMgmtControls, 0, sizeof(siConEvnt->netMgmtControls)); - if (siConEvnt->correlationId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->correlationId, 0, sizeof(siConEvnt->correlationId)); - if (siConEvnt->callDivTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callDivTrtInd, 0, sizeof(siConEvnt->callDivTrtInd)); - if (siConEvnt->callInNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callInNmb, 0, sizeof(siConEvnt->callInNmb)); - if (siConEvnt->callOfferTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callOfferTrtInd, 0, sizeof(siConEvnt->callOfferTrtInd)); - if (siConEvnt->scfId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->scfId, 0, sizeof(siConEvnt->scfId)); - if (siConEvnt->uidCapInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->uidCapInd, 0, sizeof(siConEvnt->uidCapInd)); - if (siConEvnt->collCallReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->collCallReq, 0, sizeof(siConEvnt->collCallReq)); - if (siConEvnt->ccss.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccss, 0, sizeof(siConEvnt->ccss)); -#endif -#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ) - if (siConEvnt->backGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backGVNS, 0, sizeof(siConEvnt->backGVNS)); - if (siConEvnt->forwardGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->forwardGVNS, 0, sizeof(siConEvnt->forwardGVNS)); -#endif -#if (SS7_ETSIV3 || SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || \ - SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ) - if (siConEvnt->appTransParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->appTransParam, 0, sizeof(siConEvnt->appTransParam)); -#endif -#if (SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ) - if (siConEvnt->htrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->htrInfo, 0, sizeof(siConEvnt->htrInfo)); - if (siConEvnt->pivotCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCap, 0, sizeof(siConEvnt->pivotCap)); - if (siConEvnt->cadDirNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cadDirNmb, 0, sizeof(siConEvnt->cadDirNmb)); - if (siConEvnt->origCallInNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCallInNum, 0, sizeof(siConEvnt->origCallInNum)); - if (siConEvnt->calgGeoLoc.eh.pres != PRSNT_NODEF) memset(&siConEvnt->calgGeoLoc, 0, sizeof(siConEvnt->calgGeoLoc)); - if (siConEvnt->netRoutNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netRoutNum, 0, sizeof(siConEvnt->netRoutNum)); - if (siConEvnt->qonRelCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->qonRelCap, 0, sizeof(siConEvnt->qonRelCap)); - if (siConEvnt->pivotCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCntr, 0, sizeof(siConEvnt->pivotCntr)); - if (siConEvnt->pivotRtgFwInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgFwInfo, 0, sizeof(siConEvnt->pivotRtgFwInfo)); - if (siConEvnt->pivotRtgBkInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgBkInfo, 0, sizeof(siConEvnt->pivotRtgBkInfo)); - if (siConEvnt->numPortFwdInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->numPortFwdInfo, 0, sizeof(siConEvnt->numPortFwdInfo)); -#endif -#ifdef SS7_UK - if (siConEvnt->natFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalInd, 0, sizeof(siConEvnt->natFwdCalInd)); - if (siConEvnt->presntNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->presntNum, 0, sizeof(siConEvnt->presntNum)); - if (siConEvnt->lstDvrtLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->lstDvrtLineId, 0, sizeof(siConEvnt->lstDvrtLineId)); - if (siConEvnt->pcgLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pcgLineId, 0, sizeof(siConEvnt->pcgLineId)); - if (siConEvnt->natFwdCalIndLnk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalIndLnk, 0, sizeof(siConEvnt->natFwdCalIndLnk)); - if (siConEvnt->cdBascSrvcMrk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdBascSrvcMrk, 0, sizeof(siConEvnt->cdBascSrvcMrk)); -#endif /* SS7_UK */ -#if (defined(CGPN_CHK)) - if (siConEvnt->causeDgnCgPnChk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->causeDgnCgPnChk, 0, sizeof(siConEvnt->causeDgnCgPnChk)); -#endif - return FTDM_SUCCESS; -} - -ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt) -{ -#ifndef HAVE_ZLIB - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n"); - return FTDM_FAIL; -#else - unsigned ret_val = FTDM_FAIL; - char *compressed_iam = NULL; - char *url_encoded_iam = NULL; - uLongf len = sizeof(*siConEvnt); - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - - /* By default, Trillium does not memset their whole structure to zero for - * performance. But we want to memset all the IE's that are not present to - * optimize compressed size */ - sngss7_bufferzero_iam(siConEvnt); - - compressed_iam = ftdm_malloc(sizeof(*siConEvnt)); - if (!compressed_iam) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocate buffer for compressed_iam\n"); - goto done; - } - - /* Compress IAM structure to minimize buffer size */ - ret_val = compress((Bytef *)compressed_iam, &len, (const Bytef *)siConEvnt, (uLong)sizeof(*siConEvnt)); - if (ret_val != Z_OK) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to compress IAM (error:%d)\n", ret_val); - ret_val = FTDM_FAIL; - goto done; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%lu\n", len); - - /* Worst case: size will triple after url encode */ - url_encoded_iam = ftdm_malloc(3*sizeof(*siConEvnt)); - if (!url_encoded_iam) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocated buffer for url_encoded_iam\n"); - ret_val = FTDM_FAIL; - goto done; - } - memset(url_encoded_iam, 0, 2*sizeof(*siConEvnt)); - - /* URL encode buffer to that its safe to store it in a string */ - ftdm_url_encode((const char*)compressed_iam, url_encoded_iam, len); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%"FTDM_SIZE_FMT"\n", strlen(url_encoded_iam)); - - if (strlen(url_encoded_iam) > sngss7_info->circuit->transparent_iam_max_size) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%d max:%d) \n", - strlen(url_encoded_iam), sngss7_info->circuit->transparent_iam_max_size); - ret_val = FTDM_FAIL; - goto done; - } - - sngss7_add_var(sngss7_info, "ss7_iam", url_encoded_iam); -done: - ftdm_safe_free(compressed_iam); - ftdm_safe_free(url_encoded_iam); - return ret_val; -#endif -} - -ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt) -{ -#ifndef HAVE_ZLIB - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n"); - return FTDM_FAIL; -#else - uLongf len = 3*sizeof(*siConEvnt); /* worst case: URL encoded buffer is 3x length of buffer */ - char *val = NULL; - unsigned ret_val = FTDM_FAIL; - void *uncompressed_buffer = NULL; - char *url_encoded_iam = NULL; - ftdm_size_t url_encoded_iam_len; - - val = (char*)ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam"); - if (ftdm_strlen_zero(val)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Transparent IAM info available\n"); - return FTDM_FAIL; - } - - url_encoded_iam = ftdm_strdup(val); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%"FTDM_SIZE_FMT"\n", strlen(val)); - ftdm_url_decode(url_encoded_iam, &url_encoded_iam_len); - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%"FTDM_SIZE_FMT"\n", url_encoded_iam_len); - - uncompressed_buffer = ftdm_malloc(sizeof(*siConEvnt)); - ftdm_assert_return(uncompressed_buffer, FTDM_FAIL, "Failed to allocate buffer for uncompressed buffer\n"); - - ret_val = uncompress(uncompressed_buffer, &len, (const Bytef *)url_encoded_iam, (uLong)url_encoded_iam_len); - if (ret_val != Z_OK) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to uncompress IAM (error:%d)\n", ret_val); - goto done; - } - - if (len != sizeof(*siConEvnt)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Incompatible IAM structure size (expected:%"FTDM_SIZE_FMT" size:%"FTDM_SIZE_FMT")\n", sizeof(*siConEvnt), strlen(uncompressed_buffer)); - goto done; - } - - memcpy(siConEvnt, uncompressed_buffer, sizeof(*siConEvnt)); - ret_val = FTDM_SUCCESS; - -done: - ftdm_safe_free(uncompressed_buffer); - ftdm_safe_free(url_encoded_iam); - return ret_val; -#endif -} - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c deleted file mode 100644 index 541f107704..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2009, Sangoma Technologies - * Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ - -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ - -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ -void handle_isup_t35(void *userdata) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_timer_data_t *timer = userdata; - sngss7_chan_data_t *sngss7_info = timer->sngss7_info; - ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_channel_lock(ftdmchan); - - /* Q.764 2.2.5 Address incomplete (T35 expiry action is hangup with cause 28 according to Table A.1/Q.764) */ - SS7_ERROR("[Call-Control] Timer 35 expired on CIC = %d\n", sngss7_info->circuit->cic); - - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL); - - /* hang up on timer expiry */ - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_INVALID_NUMBER_FORMAT; - - /* end the call */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - - /* kill t10 t39 if active */ - if (sngss7_info->t10.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id); - } - if (sngss7_info->t39.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id); - } - - /*unlock*/ - ftdm_channel_unlock(ftdmchan); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); - return; -} - - -void handle_isup_t10(void *userdata) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_timer_data_t *timer = userdata; - sngss7_chan_data_t *sngss7_info = timer->sngss7_info; - ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - - ftdm_channel_lock(ftdmchan); - - SS7_DEBUG("[Call-Control] Timer 10 expired on CIC = %d\n", sngss7_info->circuit->cic); - - /* send the call to the user */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); - - ftdm_channel_unlock(ftdmchan); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} - -void handle_isup_t39(void *userdata) -{ - SS7_FUNC_TRACE_ENTER(__FTDM_FUNC__); - - sngss7_timer_data_t *timer = userdata; - sngss7_chan_data_t *sngss7_info = timer->sngss7_info; - ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_channel_lock(ftdmchan); - - /* Q.764 2.2.5 Address incomplete (T35 expiry action is hangup with cause 28 according to Table A.1/Q.764) */ - SS7_ERROR("[Call-Control] Timer 39 expired on CIC = %d\n", sngss7_info->circuit->cic); - - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL); - - /* hang up on timer expiry */ - ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_INVALID_NUMBER_FORMAT; - - /* end the call */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - - /* kill t10 t35 if active */ - if (sngss7_info->t10.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id); - } - if (sngss7_info->t35.hb_timer_id) { - ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id); - } - - /*unlock*/ - ftdm_channel_unlock(ftdmchan); - - SS7_FUNC_TRACE_EXIT(__FTDM_FUNC__); -} -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ - diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c deleted file mode 100644 index ad504b14b0..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ /dev/null @@ -1,3454 +0,0 @@ -/* - * Copyright (c) 2009, Konrad Hammel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributors: - * - * James Zhang - * - */ - -/* INCLUDE ********************************************************************/ -#include "ftmod_sangoma_ss7_main.h" -/******************************************************************************/ - -/* DEFINES ********************************************************************/ -/******************************************************************************/ - -/* GLOBALS ********************************************************************/ -sng_ssf_type_t sng_ssf_type_map[] = -{ - { 1, "nat" , SSF_NAT }, - { 1, "int" , SSF_INTL }, - { 1, "spare" , SSF_SPARE }, - { 1, "res" , SSF_RES }, - { 0, "", 0 }, -}; - -sng_switch_type_t sng_switch_type_map[] = -{ - { 1, "itu88" , LSI_SW_ITU , LSI_SW_ITU }, - { 1, "itu92" , LSI_SW_ITU , LSI_SW_ITU }, - { 1, "itu97" , LSI_SW_ITU97 , LSI_SW_ITU97 }, - { 1, "itu00" , LSI_SW_ITU2000 , LSI_SW_ITU2000 }, - { 1, "ansi88" , LSI_SW_ANS88 , LSI_SW_ANS88 }, - { 1, "ansi92" , LSI_SW_ANS92 , LSI_SW_ANS92 }, - { 1, "ansi95" , LSI_SW_ANS92 , LSI_SW_ANS92 }, - { 1, "etsiv2" , LSI_SW_ETSI , LSI_SW_ETSI }, - { 1, "etsiv3" , LSI_SW_ETSIV3 , LSI_SW_ETSIV3 }, - { 1, "india" , LSI_SW_INDIA , LSI_SW_INDIA }, - { 1, "uk" , LSI_SW_UK , LSI_SW_UK }, - { 1, "russia" , LSI_SW_RUSSIA , LSI_SW_RUSSIA }, - { 1, "china" , LSI_SW_CHINA , LSI_SW_CHINA }, - { 0, "", 0, 0 }, -}; - -sng_link_type_t sng_link_type_map[] = -{ - { 1, "itu88" , LSD_SW_ITU88 , LSN_SW_ITU }, - { 1, "itu92" , LSD_SW_ITU92 , LSN_SW_ITU }, - { 1, "etsi" , LSD_SW_ITU92 , LSN_SW_ITU }, - { 1, "ansi88" , LSD_SW_ANSI88, LSN_SW_ANS }, - { 1, "ansi92" , LSD_SW_ANSI92, LSN_SW_ANS }, - { 1, "ansi96" , LSD_SW_ANSI92, LSN_SW_ANS96 }, - { 0, "", 0, 0 }, -}; - -sng_mtp2_error_type_t sng_mtp2_error_type_map[] = -{ - { 1, "basic", SD_ERR_NRM }, - { 1, "pcr" , SD_ERR_CYC }, - { 0, "", 0 }, -}; - -sng_cic_cntrl_type_t sng_cic_cntrl_type_map[] = -{ - { 1, "bothway" , BOTHWAY }, - { 1, "incoming" , INCOMING }, - { 1, "outgoing" , OUTGOING }, - { 1, "controlling" , CONTROLLING }, - { 1, "controlled" , CONTROLLED }, - { 0, "", 0 }, -}; - -typedef struct sng_timeslot -{ - int channel; - int siglink; - int gap; - int hole; -}sng_timeslot_t; - -typedef struct sng_span -{ - char name[MAX_NAME_LEN]; - ftdm_span_t *span; - uint32_t ccSpanId; -} sng_span_t; - -typedef struct sng_ccSpan -{ - char name[MAX_NAME_LEN]; - uint32_t options; - uint32_t id; - uint32_t procId; - uint32_t isupInf; - uint32_t cicbase; - char ch_map[MAX_CIC_MAP_LENGTH]; - uint32_t typeCntrl; - uint32_t switchType; - uint32_t ssf; - uint32_t clg_nadi; - uint32_t cld_nadi; - uint32_t rdnis_nadi; - uint32_t loc_nadi; - uint32_t min_digits; - uint32_t transparent_iam_max_size; - uint8_t transparent_iam; - uint8_t cpg_on_progress_media; - uint8_t cpg_on_progress; - uint8_t itx_auto_reply; - uint32_t t3; - uint32_t t10; - uint32_t t12; - uint32_t t13; - uint32_t t14; - uint32_t t15; - uint32_t t16; - uint32_t t17; - uint32_t t35; - uint32_t t39; - uint32_t tval; -} sng_ccSpan_t; - -int cmbLinkSetId; -/******************************************************************************/ - -/* PROTOTYPES *****************************************************************/ -int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span); - -static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup); - -static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen); - -static int ftmod_ss7_parse_sng_relay(ftdm_conf_node_t *sng_relay); -static int ftmod_ss7_parse_relay_channel(ftdm_conf_node_t *relay_chan); - -static int ftmod_ss7_parse_mtp1_links(ftdm_conf_node_t *mtp1_links); -static int ftmod_ss7_parse_mtp1_link(ftdm_conf_node_t *mtp1_link); - -static int ftmod_ss7_parse_mtp2_links(ftdm_conf_node_t *mtp2_links); -static int ftmod_ss7_parse_mtp2_link(ftdm_conf_node_t *mtp2_link); - -static int ftmod_ss7_parse_mtp3_links(ftdm_conf_node_t *mtp3_links); -static int ftmod_ss7_parse_mtp3_link(ftdm_conf_node_t *mtp3_link); - -static int ftmod_ss7_parse_mtp_linksets(ftdm_conf_node_t *mtp_linksets); -static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset); - -static int ftmod_ss7_parse_mtp_routes(ftdm_conf_node_t *mtp_routes); -static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route); - -static int ftmod_ss7_parse_isup_interfaces(ftdm_conf_node_t *isup_interfaces); -static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface); - -static int ftmod_ss7_parse_cc_spans(ftdm_conf_node_t *cc_spans); -static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span); - -static int ftmod_ss7_fill_in_relay_channel(sng_relay_t *relay_channel); -static int ftmod_ss7_fill_in_mtp1_link(sng_mtp1_link_t *mtp1Link); -static int ftmod_ss7_fill_in_mtp2_link(sng_mtp2_link_t *mtp1Link); -static int ftmod_ss7_fill_in_mtp3_link(sng_mtp3_link_t *mtp1Link); -static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet); -static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route); -static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route); -static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup); -static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap); -static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan); -static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, int ssf); -static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan); - -static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot); -static void ftmod_ss7_set_glare_resolution (const char *method); - -/******************************************************************************/ - -/* FUNCTIONS ******************************************************************/ - -int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) -{ - sng_route_t self_route; - sng_span_t sngSpan; - int i = 0; - const char *var = NULL; - const char *val = NULL; - ftdm_conf_node_t *ptr = NULL; - - /* clean out the isup ckt */ - memset(&sngSpan, 0x0, sizeof(sngSpan)); - - /* clean out the self route */ - memset(&self_route, 0x0, sizeof(self_route)); - - var = ftdm_parameters[i].var; - val = ftdm_parameters[i].val; - - g_ftdm_operating_mode = SNG_SS7_OPR_MODE_ISUP; - - /* confirm that the first parameter is the "operating-mode" */ - if(!strcasecmp(var, "operating-mode")){ - if(!strcasecmp(val, "ISUP")) { - g_ftdm_operating_mode = SNG_SS7_OPR_MODE_ISUP; - } - else if(!strcasecmp(val, "M2UA_SG")) { - g_ftdm_operating_mode = SNG_SS7_OPR_MODE_M2UA_SG; - } else { - SS7_DEBUG("Operating mode not specified, defaulting to ISUP\n"); - } - i++; - } - - - - var = ftdm_parameters[i].var; - val = ftdm_parameters[i].val; - ptr = (ftdm_conf_node_t *)ftdm_parameters[i].ptr; - - /* confirm that the 2nd parameter is the "confnode" */ - if (!strcasecmp(var, "confnode")) { - /* parse the confnode and fill in the global libsng_ss7 config structure */ - if (ftmod_ss7_parse_sng_isup(ptr)) { - SS7_ERROR("Failed to parse the \"confnode\"!\n"); - goto ftmod_ss7_parse_xml_error; - } - } else { - /* ERROR...exit */ - SS7_ERROR("The \"confnode\" configuration was not the first parameter!\n"); - SS7_ERROR("\tFound \"%s\" in the first slot\n", var); - goto ftmod_ss7_parse_xml_error; - } - - i++; - - while (ftdm_parameters[i].var != NULL) { - var = ftdm_parameters[i].var; - val = ftdm_parameters[i].val; - - if (!strcasecmp(var, "dialplan")) { - /* don't care for now */ - } else if (!strcasecmp(var, "context")) { - /* don't care for now */ - } else if (!strcasecmp(var, "span-id") || !strcasecmp(var, "ccSpanId")) { - sngSpan.ccSpanId = atoi(val); - SS7_DEBUG("Found an ccSpanId = %d\n",sngSpan.ccSpanId); - } else { - SS7_ERROR("Unknown parameter found =\"%s\"...ignoring it!\n", var); - } - - i++; - } /* while (ftdm_parameters[i].var != NULL) */ - - /* fill the pointer to span into isupCkt */ - sngSpan.span = span; - - if(SNG_SS7_OPR_MODE_ISUP == g_ftdm_operating_mode){ - /* setup the circuits structure */ - if(ftmod_ss7_fill_in_circuits(&sngSpan)) { - SS7_ERROR("Failed to fill in circuits structure!\n"); - goto ftmod_ss7_parse_xml_error; - } - } - - return FTDM_SUCCESS; - -ftmod_ss7_parse_xml_error: - return FTDM_FAIL; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup) -{ - ftdm_conf_node_t *gen_config = NULL; - ftdm_conf_node_t *relay_channels = NULL; - ftdm_conf_node_t *mtp1_links = NULL; - ftdm_conf_node_t *mtp2_links = NULL; - ftdm_conf_node_t *mtp3_links = NULL; - ftdm_conf_node_t *mtp_linksets = NULL; - ftdm_conf_node_t *mtp_routes = NULL; - ftdm_conf_node_t *isup_interfaces = NULL; - ftdm_conf_node_t *cc_spans = NULL; - ftdm_conf_node_t *tmp_node = NULL; - ftdm_conf_node_t *nif_ifaces = NULL; - ftdm_conf_node_t *m2ua_ifaces = NULL; - ftdm_conf_node_t *m2ua_peer_ifaces = NULL; - ftdm_conf_node_t *m2ua_clust_ifaces = NULL; - ftdm_conf_node_t *sctp_ifaces = NULL; - - /* confirm that we are looking at sng_isup */ - if (strcasecmp(sng_isup->name, "sng_isup")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_isup\"!\n",sng_isup->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"sng_isup\"...\n"); - } - - /* extract the main sections of the sng_isup block */ - tmp_node = sng_isup->child; - - while (tmp_node != NULL) { - /**************************************************************************/ - /* check the type of structure */ - if (!strcasecmp(tmp_node->name, "sng_gen")) { - /**********************************************************************/ - if (gen_config == NULL) { - gen_config = tmp_node; - SS7_DEBUG("Found a \"sng_gen\" section!\n"); - } else { - SS7_ERROR("Found a second \"sng_gen\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "sng_relay")) { - /**********************************************************************/ - if (relay_channels == NULL) { - relay_channels = tmp_node; - SS7_DEBUG("Found a \"sng_relay\" section!\n"); - } else { - SS7_ERROR("Found a second \"sng_relay\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - }else if (!strcasecmp(tmp_node->name, "mtp1_links")) { - /**********************************************************************/ - if (mtp1_links == NULL) { - mtp1_links = tmp_node; - SS7_DEBUG("Found a \"mtp1_links\" section!\n"); - } else { - SS7_ERROR("Found a second \"mtp1_links\" section!\n"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "mtp2_links")) { - /**********************************************************************/ - if (mtp2_links == NULL) { - mtp2_links = tmp_node; - SS7_DEBUG("Found a \"mtp2_links\" section!\n"); - } else { - SS7_ERROR("Found a second \"mtp2_links\" section!\n"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "mtp3_links")) { - /**********************************************************************/ - if (mtp3_links == NULL) { - mtp3_links = tmp_node; - SS7_DEBUG("Found a \"mtp3_links\" section!\n"); - } else { - SS7_ERROR("Found a second \"mtp3_links\" section!\n"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "mtp_linksets")) { - /**********************************************************************/ - if (mtp_linksets == NULL) { - mtp_linksets = tmp_node; - SS7_DEBUG("Found a \"mtp_linksets\" section!\n"); - } else { - SS7_ERROR("Found a second \"mtp_linksets\" section!\n"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "mtp_routes")) { - /**********************************************************************/ - if (mtp_routes == NULL) { - mtp_routes = tmp_node; - SS7_DEBUG("Found a \"mtp_routes\" section!\n"); - } else { - SS7_ERROR("Found a second \"mtp_routes\" section!\n"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "isup_interfaces")) { - /**********************************************************************/ - if (isup_interfaces == NULL) { - isup_interfaces = tmp_node; - SS7_DEBUG("Found a \"isup_interfaces\" section!\n"); - } else { - SS7_ERROR("Found a second \"isup_interfaces\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "cc_spans")) { - /**********************************************************************/ - if (cc_spans == NULL) { - cc_spans = tmp_node; - SS7_DEBUG("Found a \"cc_spans\" section!\n"); - } else { - SS7_ERROR("Found a second \"cc_spans\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "sng_nif_interfaces")) { - /**********************************************************************/ - if (nif_ifaces == NULL) { - nif_ifaces = tmp_node; - SS7_DEBUG("Found a \"sng_nif_interfaces\" section!\n"); - } else { - SS7_ERROR("Found a second \"sng_nif_interfaces\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "sng_m2ua_interfaces")) { - /**********************************************************************/ - if (m2ua_ifaces == NULL) { - m2ua_ifaces = tmp_node; - SS7_DEBUG("Found a \"sng_m2ua_interfaces\" section!\n"); - } else { - SS7_ERROR("Found a second \"sng_m2ua_interfaces\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "sng_m2ua_peer_interfaces")) { - /**********************************************************************/ - if (m2ua_peer_ifaces == NULL) { - m2ua_peer_ifaces = tmp_node; - SS7_DEBUG("Found a \"sng_m2ua_peer_interfaces\" section!\n"); - } else { - SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "sng_m2ua_cluster_interfaces")) { - /**********************************************************************/ - if (m2ua_clust_ifaces == NULL) { - m2ua_clust_ifaces = tmp_node; - SS7_DEBUG("Found a \"sng_m2ua_cluster_interfaces\" section!\n"); - } else { - SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(tmp_node->name, "sng_sctp_interfaces")) { - /**********************************************************************/ - if (sctp_ifaces == NULL) { - sctp_ifaces = tmp_node; - SS7_DEBUG("Found a section!\n"); - } else { - SS7_ERROR("Found a second section!\n"); - return FTDM_FAIL; - } - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("\tFound an unknown section \"%s\"!\n", tmp_node->name); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* go to the next sibling */ - tmp_node = tmp_node->next; - } /* while (tmp_node != NULL) */ - - /* now try to parse the sections */ - if (ftmod_ss7_parse_sng_gen(gen_config)) { - SS7_ERROR("Failed to parse \"gen_config\"!\n"); - return FTDM_FAIL; - } - - if (ftmod_ss7_parse_sng_relay(relay_channels)) { - SS7_ERROR("Failed to parse \"relay_channels\"!\n"); - return FTDM_FAIL; - } - - if (ftmod_ss7_parse_mtp1_links(mtp1_links)) { - SS7_ERROR("Failed to parse \"mtp1_links\"!\n"); - return FTDM_FAIL; - } - - if (ftmod_ss7_parse_mtp2_links(mtp2_links)) { - SS7_ERROR("Failed to parse \"mtp2_links\"!\n"); - return FTDM_FAIL; - } - - - switch(g_ftdm_operating_mode) - { - case SNG_SS7_OPR_MODE_ISUP: - { - if (mtp3_links && ftmod_ss7_parse_mtp3_links(mtp3_links)) { - SS7_ERROR("Failed to parse \"mtp3_links\"!\n"); - return FTDM_FAIL; - } - - if (ftmod_ss7_parse_mtp_linksets(mtp_linksets)) { - SS7_ERROR("Failed to parse \"mtp_linksets\"!\n"); - return FTDM_FAIL; - } - - if (ftmod_ss7_parse_mtp_routes(mtp_routes)) { - SS7_ERROR("Failed to parse \"mtp_routes\"!\n"); - return FTDM_FAIL; - } - - if (isup_interfaces && ftmod_ss7_parse_isup_interfaces(isup_interfaces)) { - SS7_ERROR("Failed to parse \"isup_interfaces\"!\n"); - return FTDM_FAIL; - } - - if (cc_spans && ftmod_ss7_parse_cc_spans(cc_spans)) { - SS7_ERROR("Failed to parse \"cc_spans\"!\n"); - return FTDM_FAIL; - } - break; - } - case SNG_SS7_OPR_MODE_M2UA_SG: - { - if (ftmod_ss7_parse_sctp_links(sctp_ifaces) != FTDM_SUCCESS) { - SS7_ERROR("Failed to parse !\n"); - return FTDM_FAIL; - } - - if (nif_ifaces && ftmod_ss7_parse_nif_interfaces(nif_ifaces)) { - SS7_ERROR("Failed to parse \"nif_ifaces\"!\n"); - return FTDM_FAIL; - } - - if (m2ua_ifaces && ftmod_ss7_parse_m2ua_interfaces(m2ua_ifaces)) { - SS7_ERROR("Failed to parse \"m2ua_ifaces\"!\n"); - return FTDM_FAIL; - } - if (m2ua_peer_ifaces && ftmod_ss7_parse_m2ua_peer_interfaces(m2ua_peer_ifaces)) { - SS7_ERROR("Failed to parse \"m2ua_peer_ifaces\"!\n"); - return FTDM_FAIL; - } - if (m2ua_clust_ifaces && ftmod_ss7_parse_m2ua_clust_interfaces(m2ua_clust_ifaces)) { - SS7_ERROR("Failed to parse \"m2ua_clust_ifaces\"!\n"); - return FTDM_FAIL; - } - break; - } - default: - SS7_ERROR("Invalid operating mode[%d]\n",g_ftdm_operating_mode); - break; - - } - - return FTDM_SUCCESS; -} - -static void ftmod_ss7_set_glare_resolution (const char *method) -{ - sng_glare_resolution iMethod=SNGSS7_GLARE_PC; - if (!method || (strlen (method) <=0) ) { - SS7_ERROR( "Wrong glare resolution parameter, using default. \n" ); - } else { - if (!strcasecmp( method, "PointCode")) { - iMethod = SNGSS7_GLARE_PC; - } else if (!strcasecmp( method, "Down")) { - iMethod = SNGSS7_GLARE_DOWN; - } else if (!strcasecmp( method, "Control")) { - iMethod = SNGSS7_GLARE_CONTROL; - } else { - SS7_ERROR( "Wrong glare resolution parameter, using default. \n" ); - iMethod = SNGSS7_GLARE_PC; - } - } - g_ftdm_sngss7_data.cfg.glareResolution = iMethod; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen) -{ - ftdm_conf_parameter_t *parm = sng_gen->parameters; - int num_parms = sng_gen->n_parameters; - int i = 0; - - /* Set the transparent_iam_max_size to default value */ - g_ftdm_sngss7_data.cfg.transparent_iam_max_size=800; - g_ftdm_sngss7_data.cfg.force_inr = 0; - - /* extract all the information from the parameters */ - for (i = 0; i < num_parms; i++) { - if (!strcasecmp(parm->var, "procId")) { - g_ftdm_sngss7_data.cfg.procId = atoi(parm->val); - SS7_DEBUG("Found a procId = %d\n", g_ftdm_sngss7_data.cfg.procId); - } - else if (!strcasecmp(parm->var, "license")) { - ftdm_set_string(g_ftdm_sngss7_data.cfg.license, parm->val); - snprintf(g_ftdm_sngss7_data.cfg.signature, sizeof(g_ftdm_sngss7_data.cfg.signature), "%s.sig", parm->val); - SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license); - SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature); - } - else if (!strcasecmp(parm->var, "transparent_iam_max_size")) { - g_ftdm_sngss7_data.cfg.transparent_iam_max_size = atoi(parm->val); - SS7_DEBUG("Found a transparent_iam max size = %d\n", g_ftdm_sngss7_data.cfg.transparent_iam_max_size); - } - else if (!strcasecmp(parm->var, "glare-reso")) { - ftmod_ss7_set_glare_resolution (parm->val); - SS7_DEBUG("Found glare resolution configuration = %d %s\n", g_ftdm_sngss7_data.cfg.glareResolution, parm->val ); - } - else if (!strcasecmp(parm->var, "force-inr")) { - if (ftdm_true(parm->val)) { - g_ftdm_sngss7_data.cfg.force_inr = 1; - } else { - g_ftdm_sngss7_data.cfg.force_inr = 0; - } - SS7_DEBUG("Found INR force configuration = %s\n", parm->val ); - } - else { - SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; - } - - /* move to the next parmeter */ - parm = parm + 1; - } /* for (i = 0; i < num_parms; i++) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_sng_relay(ftdm_conf_node_t *sng_relay) -{ - ftdm_conf_node_t *relay_chan = NULL; - - /* confirm that we are looking at sng_relay */ - if (strcasecmp(sng_relay->name, "sng_relay")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_relay\"!\n",sng_relay->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"sng_relay\"...\n"); - } - - relay_chan = sng_relay->child; - - if (relay_chan != NULL) { - while (relay_chan != NULL) { - /* try to the parse relay_channel */ - if (ftmod_ss7_parse_relay_channel(relay_chan)) { - SS7_ERROR("Failed to parse \"relay_channels\"!\n"); - return FTDM_FAIL; - } - - /* move on to the next linkset */ - relay_chan = relay_chan->next; - } /* while (relay_chan != NULL) */ - } /* if (relay_chan != NULL) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_relay_channel(ftdm_conf_node_t *relay_chan) -{ - sng_relay_t tmp_chan; - ftdm_conf_parameter_t *parm = relay_chan->parameters; - int num_parms = relay_chan->n_parameters; - int i = 0; - - /* confirm that we are looking at relay_channel */ - if (strcasecmp(relay_chan->name, "relay_channel")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"relay_channel\"!\n",relay_chan->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"relay_channel\"...\n"); - } - - /* initalize the tmp_chan structure */ - memset(&tmp_chan, 0x0, sizeof(tmp_chan)); - - /* extract all the information from the parameters */ - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)tmp_chan.name, parm->val); - SS7_DEBUG("Found an relay_channel named = %s\n", tmp_chan.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "type")) { - /**********************************************************************/ - if (!strcasecmp(parm->val, "listen")) { - tmp_chan.type = LRY_CT_TCP_LISTEN; - SS7_DEBUG("Found a type = LISTEN\n"); - } else if (!strcasecmp(parm->val, "server")) { - tmp_chan.type = LRY_CT_TCP_SERVER; - SS7_DEBUG("Found a type = SERVER\n"); - } else if (!strcasecmp(parm->val, "client")) { - tmp_chan.type = LRY_CT_TCP_CLIENT; - SS7_DEBUG("Found a type = CLIENT\n"); - } else { - SS7_ERROR("Found an invalid \"type\" = %s\n", parm->var); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "hostname")) { - /**********************************************************************/ - strcpy((char *)tmp_chan.hostname, parm->val); - SS7_DEBUG("Found a hostname = %s\n", tmp_chan.hostname); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "port")) { - /**********************************************************************/ - tmp_chan.port = atoi(parm->val); - SS7_DEBUG("Found a port = %d\n", tmp_chan.port); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "procId")) { - /**********************************************************************/ - tmp_chan.procId = atoi(parm->val); - SS7_DEBUG("Found a procId = %d\n", tmp_chan.procId); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parmeter */ - parm = parm + 1; - } /* for (i = 0; i < num_parms; i++) */ - - /* store the channel in the global structure */ - ftmod_ss7_fill_in_relay_channel(&tmp_chan); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp1_links(ftdm_conf_node_t *mtp1_links) -{ - ftdm_conf_node_t *mtp1_link = NULL; - - /* confirm that we are looking at mtp1_links */ - if (strcasecmp(mtp1_links->name, "mtp1_links")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp1_links\"!\n",mtp1_links->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp1_links\"...\n"); - } - - /* extract the mtp_links */ - mtp1_link = mtp1_links->child; - - /* run through all of the links found */ - while (mtp1_link != NULL) { - /* try to the parse mtp_link */ - if (ftmod_ss7_parse_mtp1_link(mtp1_link)) { - SS7_ERROR("Failed to parse \"mtp1_link\"!\n"); - return FTDM_FAIL; - } - - /* move on to the next link */ - mtp1_link = mtp1_link->next; - - } /* while (mtp_linkset != NULL) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp1_link(ftdm_conf_node_t *mtp1_link) -{ - sng_mtp1_link_t mtp1Link; - ftdm_conf_parameter_t *parm = mtp1_link->parameters; - int num_parms = mtp1_link->n_parameters; - int i; - - /* initalize the mtp1Link structure */ - memset(&mtp1Link, 0x0, sizeof(mtp1Link)); - - /* confirm that we are looking at an mtp_link */ - if (strcasecmp(mtp1_link->name, "mtp1_link")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp1_link\"!\n",mtp1_link->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp1_link\"...\n"); - } - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)mtp1Link.name, parm->val); - SS7_DEBUG("Found an mtp1_link named = %s\n", mtp1Link.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - mtp1Link.id = atoi(parm->val); - SS7_DEBUG("Found an mtp1_link id = %d\n", mtp1Link.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "span")) { - /**********************************************************************/ - mtp1Link.span = atoi(parm->val); - SS7_DEBUG("Found an mtp1_link span = %d\n", mtp1Link.span); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "chan")) { - /**********************************************************************/ - mtp1Link.chan = atoi(parm->val); - SS7_DEBUG("Found an mtp1_link chan = %d\n", mtp1Link.chan); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parmeter */ - parm = parm + 1; - - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* store the link in global structure */ - ftmod_ss7_fill_in_mtp1_link(&mtp1Link); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp2_links(ftdm_conf_node_t *mtp2_links) -{ - ftdm_conf_node_t *mtp2_link = NULL; - - /* confirm that we are looking at mtp2_links */ - if (strcasecmp(mtp2_links->name, "mtp2_links")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp2_links\"!\n",mtp2_links->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp2_links\"...\n"); - } - - /* extract the mtp_links */ - mtp2_link = mtp2_links->child; - - /* run through all of the links found */ - while (mtp2_link != NULL) { - /* try to the parse mtp_linkset */ - if (ftmod_ss7_parse_mtp2_link(mtp2_link)) { - SS7_ERROR("Failed to parse \"mtp2_link\"!\n"); - return FTDM_FAIL; - } - - /* move on to the next link */ - mtp2_link = mtp2_link->next; - - } /* while (mtp_linkset != NULL) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp2_link(ftdm_conf_node_t *mtp2_link) -{ - sng_mtp2_link_t mtp2Link; - ftdm_conf_parameter_t *parm = mtp2_link->parameters; - int num_parms = mtp2_link->n_parameters; - int i; - int ret; - - /* initalize the mtp1Link structure */ - memset(&mtp2Link, 0x0, sizeof(mtp2Link)); - - /* confirm that we are looking at an mtp2_link */ - if (strcasecmp(mtp2_link->name, "mtp2_link")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp2_link\"!\n",mtp2_link->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp2_link\"...\n"); - } - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)mtp2Link.name, parm->val); - SS7_DEBUG("Found an mtp2_link named = %s\n", mtp2Link.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - mtp2Link.id = atoi(parm->val); - SS7_DEBUG("Found an mtp2_link id = %d\n", mtp2Link.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp1Id")) { - /**********************************************************************/ - mtp2Link.mtp1Id = atoi(parm->val); - SS7_DEBUG("Found an mtp2_link mtp1Id = %d\n", mtp2Link.mtp1Id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "errorType")) { - /**********************************************************************/ - ret = find_mtp2_error_type_in_map(parm->val); - if (ret == -1) { - SS7_ERROR("Found an invalid mtp2_link errorType = %s\n", parm->var); - return FTDM_FAIL; - } else { - mtp2Link.errorType = sng_mtp2_error_type_map[ret].tril_type; - SS7_DEBUG("Found an mtp2_link errorType = %s\n", sng_mtp2_error_type_map[ret].sng_type); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "lssuLength")) { - /**********************************************************************/ - mtp2Link.lssuLength = atoi(parm->val); - SS7_DEBUG("Found an mtp2_link lssuLength = %d\n", mtp2Link.lssuLength); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "linkType")) { - /**********************************************************************/ - ret = find_link_type_in_map(parm->val); - if (ret == -1) { - SS7_ERROR("Found an invalid mtp2_link linkType = %s\n", parm->var); - return FTDM_FAIL; - } else { - mtp2Link.linkType = sng_link_type_map[ret].tril_mtp2_type; - SS7_DEBUG("Found an mtp2_link linkType = %s\n", sng_link_type_map[ret].sng_type); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t1")) { - /**********************************************************************/ - mtp2Link.t1 = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t1 = \"%d\"\n",mtp2Link.t1); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t2")) { - /**********************************************************************/ - mtp2Link.t2 = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t2 = \"%d\"\n",mtp2Link.t2); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t3")) { - /**********************************************************************/ - mtp2Link.t3 = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t3 = \"%d\"\n",mtp2Link.t3); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t4n")) { - /**********************************************************************/ - mtp2Link.t4n = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t4n = \"%d\"\n",mtp2Link.t4n); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t4e")) { - /**********************************************************************/ - mtp2Link.t4e = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t4e = \"%d\"\n",mtp2Link.t4e); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t5")) { - /**********************************************************************/ - mtp2Link.t5 = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t5 = \"%d\"\n",mtp2Link.t5); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t6")) { - /**********************************************************************/ - mtp2Link.t6 = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t6 = \"%d\"\n",mtp2Link.t6); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t7")) { - /**********************************************************************/ - mtp2Link.t7 = atoi(parm->val); - SS7_DEBUG("Found an mtp2 t7 = \"%d\"\n",mtp2Link.t7); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parmeter */ - parm = parm + 1; - - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* store the link in global structure */ - ftmod_ss7_fill_in_mtp2_link(&mtp2Link); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp3_links(ftdm_conf_node_t *mtp3_links) -{ - ftdm_conf_node_t *mtp3_link = NULL; - - /* confirm that we are looking at mtp3_links */ - if (strcasecmp(mtp3_links->name, "mtp3_links")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp3_links\"!\n",mtp3_links->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp3_links\"...\n"); - } - - /* extract the mtp_links */ - mtp3_link = mtp3_links->child; - - /* run through all of the links found */ - while (mtp3_link != NULL) { - /* try to the parse mtp_linkset */ - if (ftmod_ss7_parse_mtp3_link(mtp3_link)) { - SS7_ERROR("Failed to parse \"mtp3_link\"!\n"); - return FTDM_FAIL; - } - - /* move on to the next link */ - mtp3_link = mtp3_link->next; - - } /* while (mtp_linkset != NULL) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp3_link(ftdm_conf_node_t *mtp3_link) -{ - sng_mtp3_link_t mtp3Link; - ftdm_conf_parameter_t *parm = mtp3_link->parameters; - int num_parms = mtp3_link->n_parameters; - int i; - int ret; - - /* initalize the mtp3Link structure */ - memset(&mtp3Link, 0x0, sizeof(mtp3Link)); - - /* confirm that we are looking at an mtp_link */ - if (strcasecmp(mtp3_link->name, "mtp3_link")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp3_link\"!\n",mtp3_link->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp3_link\"...\n"); - } - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)mtp3Link.name, parm->val); - SS7_DEBUG("Found an mtp3_link named = %s\n", mtp3Link.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - mtp3Link.id = atoi(parm->val); - SS7_DEBUG("Found an mtp3_link id = %d\n", mtp3Link.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2Id")) { - /**********************************************************************/ - mtp3Link.mtp2Id = atoi(parm->val); - SS7_DEBUG("Found an mtp3_link mtp2Id = %d\n", mtp3Link.mtp2Id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2ProcId")) { - /**********************************************************************/ - mtp3Link.mtp2ProcId = atoi(parm->val); - SS7_DEBUG("Found an mtp3_link mtp2ProcId = %d\n", mtp3Link.mtp2ProcId); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "priority")) { - /**********************************************************************/ - mtp3Link.priority = atoi(parm->val); - SS7_DEBUG("Found an mtp3 Link priority = %d\n",mtp3Link.priority); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "linkType")) { - /**********************************************************************/ - ret = find_link_type_in_map(parm->val); - if (ret == -1) { - SS7_ERROR("Found an invalid mtp3_link linkType = %s\n", parm->var); - return FTDM_FAIL; - } else { - mtp3Link.linkType = sng_link_type_map[ret].tril_mtp3_type; - SS7_DEBUG("Found an mtp3_link linkType = %s\n", sng_link_type_map[ret].sng_type); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "switchType")) { - /**********************************************************************/ - ret = find_switch_type_in_map(parm->val); - if (ret == -1) { - SS7_ERROR("Found an invalid mtp3_link switchType = %s\n", parm->var); - return FTDM_FAIL; - } else { - mtp3Link.switchType = sng_switch_type_map[ret].tril_mtp3_type; - SS7_DEBUG("Found an mtp3_link switchType = %s\n", sng_switch_type_map[ret].sng_type); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "ssf")) { - /**********************************************************************/ - ret = find_ssf_type_in_map(parm->val); - if (ret == -1) { - SS7_ERROR("Found an invalid mtp3_link ssf = %s\n", parm->var); - return FTDM_FAIL; - } else { - mtp3Link.ssf = sng_ssf_type_map[ret].tril_type; - SS7_DEBUG("Found an mtp3_link ssf = %s\n", sng_ssf_type_map[ret].sng_type); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "slc")) { - /**********************************************************************/ - mtp3Link.slc = atoi(parm->val); - SS7_DEBUG("Found an mtp3 Link slc = %d\n",mtp3Link.slc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "linkset")) { - /**********************************************************************/ - mtp3Link.linkSetId = atoi(parm->val); - SS7_DEBUG("Found an mtp3 Link linkset = %d\n",mtp3Link.linkSetId); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t1")) { - /**********************************************************************/ - mtp3Link.t1 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t1 = %d\n",mtp3Link.t1); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t2")) { - /**********************************************************************/ - mtp3Link.t2 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t2 = %d\n",mtp3Link.t2); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t3")) { - /**********************************************************************/ - mtp3Link.t3 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t3 = %d\n",mtp3Link.t3); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t4")) { - /**********************************************************************/ - mtp3Link.t4 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t4 = %d\n",mtp3Link.t4); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t5")) { - /**********************************************************************/ - mtp3Link.t5 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t5 = %d\n",mtp3Link.t5); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t7")) { - /**********************************************************************/ - mtp3Link.t7 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t7 = %d\n",mtp3Link.t7); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t12")) { - /**********************************************************************/ - mtp3Link.t12 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t12 = %d\n",mtp3Link.t12); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t13")) { - /**********************************************************************/ - mtp3Link.t13 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t13 = %d\n",mtp3Link.t13); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t14")) { - /**********************************************************************/ - mtp3Link.t14 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t14 = %d\n",mtp3Link.t14); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t17")) { - /**********************************************************************/ - mtp3Link.t17 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t17 = %d\n",mtp3Link.t17); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t22")) { - /**********************************************************************/ - mtp3Link.t22 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t22 = %d\n",mtp3Link.t22); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t23")) { - /**********************************************************************/ - mtp3Link.t23 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t23 = %d\n",mtp3Link.t23); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t24")) { - /**********************************************************************/ - mtp3Link.t24 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t24 = %d\n",mtp3Link.t24); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t31")) { - mtp3Link.t31 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t31 = %d\n",mtp3Link.t31); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t32")) { - /**********************************************************************/ - mtp3Link.t32 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t32 = %d\n",mtp3Link.t32); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t33")) { - /**********************************************************************/ - mtp3Link.t33 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t33 = %d\n",mtp3Link.t33); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t34")) { - /**********************************************************************/ - mtp3Link.t34 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t34 = %d\n",mtp3Link.t34); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t35")) { - /**********************************************************************/ - mtp3Link.t35 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t35 = %d\n",mtp3Link.t35); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t36")) { - /**********************************************************************/ - mtp3Link.t36 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t36 = %d\n",mtp3Link.t36); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "t37")) { - /**********************************************************************/ - mtp3Link.t37 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t37 = %d\n",mtp3Link.t37); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "tcraft")) { - /**********************************************************************/ - mtp3Link.tcraft = atoi(parm->val); - SS7_DEBUG("Found an mtp3 tcraft = %d\n",mtp3Link.tcraft); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "tflc")) { - /**********************************************************************/ - mtp3Link.tflc = atoi(parm->val); - SS7_DEBUG("Found an mtp3 tflc = %d\n",mtp3Link.tflc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "tbnd")) { - /**********************************************************************/ - mtp3Link.tbnd = atoi(parm->val); - SS7_DEBUG("Found an mtp3 tbnd = %d\n",mtp3Link.tbnd); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter %s!\n", parm->val); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parmeter */ - parm = parm + 1; - - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* store the link in global structure */ - ftmod_ss7_fill_in_mtp3_link(&mtp3Link); - - /* move the linktype, switchtype and ssf to the linkset */ - if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType == 0) { - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType = mtp3Link.linkType; - } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType != mtp3Link.linkType) { - SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different linkType: mtp3.id=%d, mtp3.name=%s, mtp3.linktype=%d, linkset.id=%d, linkset.linktype=%d\n", - mtp3Link.id, mtp3Link.name, mtp3Link.linkType, - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType); - return FTDM_FAIL; - } else { - /* should print that all is ok...*/ - } - - if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType == 0) { - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType = mtp3Link.switchType; - } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType != mtp3Link.switchType) { - SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different switchType: mtp3.id=%d, mtp3.name=%s, mtp3.switchtype=%d, linkset.id=%d, linkset.switchtype=%d\n", - mtp3Link.id, mtp3Link.name, mtp3Link.switchType, - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType); - return FTDM_FAIL; - } else { - /* should print that all is ok...*/ - } - - if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf == 0) { - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf = mtp3Link.ssf; - } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf != mtp3Link.ssf) { - SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different ssf: mtp3.id=%d, mtp3.name=%s, mtp3.ssf=%d, linkset.id=%d, linkset.ssf=%d\n", - mtp3Link.id, mtp3Link.name, mtp3Link.ssf, - g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf); - return FTDM_FAIL; - } else { - /* should print that all is ok...*/ - } - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp_linksets(ftdm_conf_node_t *mtp_linksets) -{ - ftdm_conf_node_t *mtp_linkset = NULL; - - /* confirm that we are looking at mtp_linksets */ - if (strcasecmp(mtp_linksets->name, "mtp_linksets")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp_linksets\"!\n",mtp_linksets->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp_linksets\"...\n"); - } - - /* extract the mtp_links */ - mtp_linkset = mtp_linksets->child; - - /* run through all of the mtp_linksets found */ - while (mtp_linkset != NULL) { - /* try to the parse mtp_linkset */ - if (ftmod_ss7_parse_mtp_linkset(mtp_linkset)) { - SS7_ERROR("Failed to parse \"mtp_linkset\"!\n"); - return FTDM_FAIL; - } - - /* move on to the next linkset */ - mtp_linkset = mtp_linkset->next; - - } /* while (mtp_linkset != NULL) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) -{ - sng_link_set_t mtpLinkSet; - ftdm_conf_parameter_t *parm = mtp_linkset->parameters; - int num_parms = mtp_linkset->n_parameters; - int i; - - /* initalize the mtpLinkSet structure */ - memset(&mtpLinkSet, 0x0, sizeof(mtpLinkSet)); - - /* confirm that we are looking at mtp_linkset */ - if (strcasecmp(mtp_linkset->name, "mtp_linkset")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp_linkset\"!\n",mtp_linkset->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp_linkset\"...\n"); - } - - /* extract all the information from the parameters */ - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)mtpLinkSet.name, parm->val); - SS7_DEBUG("Found an mtpLinkSet named = %s\n", mtpLinkSet.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - mtpLinkSet.id = atoi(parm->val); - SS7_DEBUG("Found mtpLinkSet id = %d\n", mtpLinkSet.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "apc")) { - /**********************************************************************/ - mtpLinkSet.apc = atoi(parm->val); - SS7_DEBUG("Found mtpLinkSet apc = %d\n", mtpLinkSet.apc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "minActive")) { - /**********************************************************************/ - mtpLinkSet.minActive = atoi(parm->val); - SS7_DEBUG("Found mtpLinkSet minActive = %d\n", mtpLinkSet.minActive); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parmeter */ - parm = parm + 1; - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - ftmod_ss7_fill_in_mtpLinkSet(&mtpLinkSet); - - /* go through all the mtp3 links and fill in the apc */ - i = 1; - while (i < (MAX_MTP_LINKS)) { - if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == mtpLinkSet.id) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].apc = mtpLinkSet.apc; - } - - i++; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp_routes(ftdm_conf_node_t *mtp_routes) -{ - ftdm_conf_node_t *mtp_route = NULL; - - /* confirm that we are looking at an mtp_routes */ - if (strcasecmp(mtp_routes->name, "mtp_routes")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp_routes\"!\n",mtp_routes->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp_routes\"...\n"); - } - - /* extract the mtp_routes */ - mtp_route = mtp_routes->child; - - while (mtp_route != NULL) { - /* parse the found mtp_route */ - if (ftmod_ss7_parse_mtp_route(mtp_route)) { - SS7_ERROR("Failed to parse \"mtp_route\"\n"); - return FTDM_FAIL; - } - - /* go to the next mtp_route */ - mtp_route = mtp_route->next; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) -{ - sng_route_t mtpRoute; - ftdm_conf_parameter_t *parm = mtp_route->parameters; - int num_parms = mtp_route->n_parameters; - int i; - sng_link_set_list_t *lnkSet; - - ftdm_conf_node_t *linkset; - int numLinks; - - /* initalize the mtpRoute structure */ - memset(&mtpRoute, 0x0, sizeof(mtpRoute)); - - /* confirm that we are looking at an mtp_link */ - if (strcasecmp(mtp_route->name, "mtp_route")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp_route\"!\n",mtp_route->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp_route\"...\n"); - } - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - /* try to match the parameter to what we expect */ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)mtpRoute.name, parm->val); - SS7_DEBUG("Found an mtpRoute named = %s\n", mtpRoute.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - mtpRoute.id = atoi(parm->val); - SS7_DEBUG("Found an mtpRoute id = %d\n", mtpRoute.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "dpc")) { - /**********************************************************************/ - mtpRoute.dpc = atoi(parm->val); - SS7_DEBUG("Found an mtpRoute dpc = %d\n", mtpRoute.dpc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isSTP")) { - /**********************************************************************/ - if (!strcasecmp(parm->val, "no")) { - mtpRoute.isSTP = 0; - SS7_DEBUG("Found an mtpRoute isSTP = no\n"); - } else if (!strcasecmp(parm->val, "yes")) { - mtpRoute.isSTP = 1; - SS7_DEBUG("Found an mtpRoute isSTP = yes\n"); - } else { - SS7_ERROR("Found an invalid parameter for isSTP %s!\n", parm->val); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t6")) { - /**********************************************************************/ - mtpRoute.t6 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t6 = %d\n",mtpRoute.t6); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t8")) { - /**********************************************************************/ - mtpRoute.t8 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t8 = %d\n",mtpRoute.t8); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t10")) { - /**********************************************************************/ - mtpRoute.t10 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t10 = %d\n",mtpRoute.t10); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t11")) { - /**********************************************************************/ - mtpRoute.t11 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t11 = %d\n",mtpRoute.t11); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t15")) { - /**********************************************************************/ - mtpRoute.t15 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t15 = %d\n",mtpRoute.t15); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t16")) { - /**********************************************************************/ - mtpRoute.t16 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t16 = %d\n",mtpRoute.t16); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t18")) { - /**********************************************************************/ - mtpRoute.t18 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t18 = %d\n",mtpRoute.t18); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t19")) { - /**********************************************************************/ - mtpRoute.t19 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t19 = %d\n",mtpRoute.t19); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t21")) { - /**********************************************************************/ - mtpRoute.t21 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t21 = %d\n",mtpRoute.t21); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t25")) { - /**********************************************************************/ - mtpRoute.t25 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t25 = %d\n",mtpRoute.t25); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t26")) { - /**********************************************************************/ - mtpRoute.t26 = atoi(parm->val); - SS7_DEBUG("Found an mtp3 t26 = %d\n",mtpRoute.t26); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parameter */ - parm = parm + 1; - } - - /* fill in the rest of the values in the mtpRoute struct */ - mtpRoute.nwId = 0; - mtpRoute.cmbLinkSetId = mtpRoute.id; - - /* parse in the list of linksets this route is reachable by */ - linkset = mtp_route->child->child; - - /* initalize the link-list of linkSet Ids */ - lnkSet = &mtpRoute.lnkSets; - - while (linkset != NULL) { - /**************************************************************************/ - /* extract the linkset Id */ - lnkSet->lsId = atoi(linkset->parameters->val); - - if (g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].id != 0) { - SS7_DEBUG("Found mtpRoute linkset id = %d that is valid\n",lnkSet->lsId); - } else { - SS7_ERROR("Found mtpRoute linkset id = %d that is invalid\n",lnkSet->lsId); - goto move_along; - } - - /* pull up the linktype, switchtype, and SSF from the linkset */ - mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].linkType; - mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].switchType; - mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].ssf; - - /* extract the number of cmbLinkSetId aleady on this linkset */ - numLinks = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks; - - /* add this routes cmbLinkSetId to the list */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].links[numLinks] = mtpRoute.cmbLinkSetId; - - /* increment the number of cmbLinkSets on this linkset */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks++; - - /* update the linked list */ - lnkSet->next = ftdm_malloc(sizeof(sng_link_set_list_t)); - lnkSet = lnkSet->next; - lnkSet->lsId = 0; - lnkSet->next = NULL; - -move_along: - /* move to the next linkset element */ - linkset = linkset->next; - /**************************************************************************/ - } /* while (linkset != null) */ - - - ftmod_ss7_fill_in_mtp3_route(&mtpRoute); - - ftmod_ss7_fill_in_nsap(&mtpRoute); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_isup_interfaces(ftdm_conf_node_t *isup_interfaces) -{ - ftdm_conf_node_t *isup_interface = NULL; - - /* confirm that we are looking at isup_interfaces */ - if (strcasecmp(isup_interfaces->name, "isup_interfaces")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"isup_interfaces\"!\n",isup_interfaces->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"isup_interfaces\"...\n"); - } - - /* extract the isup_interfaces */ - isup_interface = isup_interfaces->child; - - while (isup_interface != NULL) { - /* parse the found mtp_route */ - if (ftmod_ss7_parse_isup_interface(isup_interface)) { - SS7_ERROR("Failed to parse \"isup_interface\"\n"); - return FTDM_FAIL; - } - - /* go to the next mtp_route */ - isup_interface = isup_interface->next; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) -{ - sng_isup_inf_t sng_isup; - sng_isap_t sng_isap; - sng_link_set_list_t *lnkSet; - ftdm_conf_parameter_t *parm = isup_interface->parameters; - int num_parms = isup_interface->n_parameters; - int i; - int ret; - - /* initalize the isup intf and isap structure */ - memset(&sng_isup, 0x0, sizeof(sng_isup)); - memset(&sng_isap, 0x0, sizeof(sng_isap)); - - /* confirm that we are looking at an mtp_link */ - if (strcasecmp(isup_interface->name, "isup_interface")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"isup_interface\"!\n",isup_interface->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"isup_interface\"...\n"); - } - - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - /* try to match the parameter to what we expect */ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)sng_isup.name, parm->val); - SS7_DEBUG("Found an isup_interface named = %s\n", sng_isup.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - sng_isup.id = atoi(parm->val); - SS7_DEBUG("Found an isup id = %d\n", sng_isup.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "spc")) { - /**********************************************************************/ - sng_isup.spc = atoi(parm->val); - SS7_DEBUG("Found an isup SPC = %d\n", sng_isup.spc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtprouteId")) { - /**********************************************************************/ - sng_isup.mtpRouteId=atoi(parm->val); - - SS7_DEBUG("Found an isup mptRouteId = %d\n", sng_isup.mtpRouteId); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "ssf")) { - /**********************************************************************/ - ret = find_ssf_type_in_map(parm->val); - if (ret == -1) { - SS7_ERROR("Found an invalid isup ssf = %s\n", parm->var); - return FTDM_FAIL; - } else { - sng_isup.ssf = sng_ssf_type_map[ret].tril_type; - sng_isap.ssf = sng_ssf_type_map[ret].tril_type; - SS7_DEBUG("Found an isup ssf = %s\n", sng_ssf_type_map[ret].sng_type); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t1")) { - /**********************************************************************/ - sng_isap.t1 = atoi(parm->val); - SS7_DEBUG("Found isup t1 = %d\n",sng_isap.t1); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t2")) { - /**********************************************************************/ - sng_isap.t2 = atoi(parm->val); - SS7_DEBUG("Found isup t2 = %d\n",sng_isap.t2); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t4")) { - /**********************************************************************/ - sng_isup.t4 = atoi(parm->val); - SS7_DEBUG("Found isup t4 = %d\n",sng_isup.t4); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t5")) { - /**********************************************************************/ - sng_isap.t5 = atoi(parm->val); - SS7_DEBUG("Found isup t5 = %d\n",sng_isap.t5); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t6")) { - /**********************************************************************/ - sng_isap.t6 = atoi(parm->val); - SS7_DEBUG("Found isup t6 = %d\n",sng_isap.t6); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t7")) { - /**********************************************************************/ - sng_isap.t7 = atoi(parm->val); - SS7_DEBUG("Found isup t7 = %d\n",sng_isap.t7); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t8")) { - /**********************************************************************/ - sng_isap.t8 = atoi(parm->val); - SS7_DEBUG("Found isup t8 = %d\n",sng_isap.t8); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t9")) { - /**********************************************************************/ - sng_isap.t9 = atoi(parm->val); - SS7_DEBUG("Found isup t9 = %d\n",sng_isap.t9); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t11")) { - /**********************************************************************/ - sng_isup.t11 = atoi(parm->val); - SS7_DEBUG("Found isup t11 = %d\n",sng_isup.t11); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t18")) { - /**********************************************************************/ - sng_isup.t18 = atoi(parm->val); - SS7_DEBUG("Found isup t18 = %d\n",sng_isup.t18); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t19")) { - /**********************************************************************/ - sng_isup.t19 = atoi(parm->val); - SS7_DEBUG("Found isup t19 = %d\n",sng_isup.t19); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t20")) { - /**********************************************************************/ - sng_isup.t20 = atoi(parm->val); - SS7_DEBUG("Found isup t20 = %d\n",sng_isup.t20); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t21")) { - /**********************************************************************/ - sng_isup.t21 = atoi(parm->val); - SS7_DEBUG("Found isup t21 = %d\n",sng_isup.t21); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t22")) { - /**********************************************************************/ - sng_isup.t22 = atoi(parm->val); - SS7_DEBUG("Found isup t22 = %d\n",sng_isup.t22); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t23")) { - /**********************************************************************/ - sng_isup.t23 = atoi(parm->val); - SS7_DEBUG("Found isup t23 = %d\n",sng_isup.t23); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t24")) { - /**********************************************************************/ - sng_isup.t24 = atoi(parm->val); - SS7_DEBUG("Found isup t24 = %d\n",sng_isup.t24); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t25")) { - /**********************************************************************/ - sng_isup.t25 = atoi(parm->val); - SS7_DEBUG("Found isup t25 = %d\n",sng_isup.t25); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t26")) { - /**********************************************************************/ - sng_isup.t26 = atoi(parm->val); - SS7_DEBUG("Found isup t26 = %d\n",sng_isup.t26); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t28")) { - /**********************************************************************/ - sng_isup.t28 = atoi(parm->val); - SS7_DEBUG("Found isup t28 = %d\n",sng_isup.t28); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t29")) { - /**********************************************************************/ - sng_isup.t29 = atoi(parm->val); - SS7_DEBUG("Found isup t29 = %d\n",sng_isup.t29); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t30")) { - /**********************************************************************/ - sng_isup.t30 = atoi(parm->val); - SS7_DEBUG("Found isup t30 = %d\n",sng_isup.t30); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t31")) { - /**********************************************************************/ - sng_isap.t31 = atoi(parm->val); - SS7_DEBUG("Found isup t31 = %d\n",sng_isap.t31); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t32")) { - /**********************************************************************/ - sng_isup.t32 = atoi(parm->val); - SS7_DEBUG("Found isup t32 = %d\n",sng_isup.t32); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t33")) { - /**********************************************************************/ - sng_isap.t33 = atoi(parm->val); - SS7_DEBUG("Found isup t33 = %d\n",sng_isap.t33); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t34")) { - /**********************************************************************/ - sng_isap.t34 = atoi(parm->val); - SS7_DEBUG("Found isup t34 = %d\n",sng_isap.t34); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t36")) { - /**********************************************************************/ - sng_isap.t36 = atoi(parm->val); - SS7_DEBUG("Found isup t36 = %d\n",sng_isap.t36); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t37")) { - /**********************************************************************/ - sng_isup.t37 = atoi(parm->val); - SS7_DEBUG("Found isup t37 = %d\n",sng_isup.t37); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t38")) { - /**********************************************************************/ - sng_isup.t38 = atoi(parm->val); - SS7_DEBUG("Found isup t38 = %d\n",sng_isup.t38); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t39")) { - /**********************************************************************/ - sng_isup.t39 = atoi(parm->val); - SS7_DEBUG("Found isup t39 = %d\n",sng_isup.t39); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tccr")) { - /**********************************************************************/ - sng_isap.tccr = atoi(parm->val); - SS7_DEBUG("Found isup tccr = %d\n",sng_isap.tccr); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tccrt")) { - /**********************************************************************/ - sng_isap.tccrt = atoi(parm->val); - SS7_DEBUG("Found isup tccrt = %d\n",sng_isap.tccrt); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tex")) { - /**********************************************************************/ - sng_isap.tex = atoi(parm->val); - SS7_DEBUG("Found isup tex = %d\n",sng_isap.tex); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tect")) { - /**********************************************************************/ - sng_isap.tect = atoi(parm->val); - SS7_DEBUG("Found isup tect = %d\n",sng_isap.tect); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tcrm")) { - /**********************************************************************/ - sng_isap.tcrm = atoi(parm->val); - SS7_DEBUG("Found isup tcrm = %d\n",sng_isap.tcrm); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tcra")) { - /**********************************************************************/ - sng_isap.tcra = atoi(parm->val); - SS7_DEBUG("Found isup tcra = %d\n",sng_isap.tcra); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tfgr")) { - /**********************************************************************/ - sng_isup.tfgr = atoi(parm->val); - SS7_DEBUG("Found isup tfgr = %d\n",sng_isup.tfgr); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.trelrsp")) { - /**********************************************************************/ - sng_isap.trelrsp = atoi(parm->val); - SS7_DEBUG("Found isup trelrsp = %d\n",sng_isap.trelrsp); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) { - /**********************************************************************/ - sng_isap.tfnlrelrsp = atoi(parm->val); - SS7_DEBUG("Found isup tfnlrelrsp = %d\n",sng_isap.tfnlrelrsp); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) { - /**********************************************************************/ - sng_isap.tfnlrelrsp = atoi(parm->val); - SS7_DEBUG("Found isup tfnlrelrsp = %d\n",sng_isap.tfnlrelrsp); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tpause")) { - /**********************************************************************/ - sng_isup.tpause = atoi(parm->val); - SS7_DEBUG("Found isup tpause = %d\n",sng_isup.tpause); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tstaenq")) { - /**********************************************************************/ - sng_isup.tstaenq = atoi(parm->val); - SS7_DEBUG("Found isup tstaenq = %d\n",sng_isup.tstaenq); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter %s!\n", parm->val); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parameter */ - parm = parm + 1; - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* default the interface to paused state */ - sngss7_set_flag(&sng_isup, SNGSS7_PAUSED); - - - - /* trickle down the SPC to all sub entities */ - lnkSet = &g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].lnkSets; - while (lnkSet->next != NULL) { - /**************************************************************************/ - /* go through all the links and check if they belong to this linkset*/ - i = 1; - while (i < (MAX_MTP_LINKS)) { - /* check if this link is in the linkset */ - if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == lnkSet->lsId) { - /* fill in the spc */ - g_ftdm_sngss7_data.cfg.mtp3Link[i].spc = sng_isup.spc; - } - - i++; - } - - /* move to the next lnkSet */ - lnkSet = lnkSet->next; - /**************************************************************************/ - } /* while (lnkSet->next != NULL) */ - - /* pull values from the lower levels */ - sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].switchType; - - /* fill in the isap */ - ftmod_ss7_fill_in_isap(&sng_isap); - - /* pull values from the lower levels */ - sng_isup.isap = sng_isap.id; - sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].dpc; - sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].switchType; - sng_isup.nwId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].nwId; - - /* fill in the isup interface */ - ftmod_ss7_fill_in_isup_interface(&sng_isup); - - /* setup the self mtp3 route */ - i = sng_isup.mtpRouteId; - if(ftmod_ss7_fill_in_self_route(sng_isup.spc, - g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType, - g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType, - g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf)) { - - SS7_ERROR("Failed to fill in self route structure!\n"); - return FTDM_FAIL; - - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_cc_spans(ftdm_conf_node_t *cc_spans) -{ - ftdm_conf_node_t *cc_span = NULL; - - /* confirm that we are looking at cc_spans */ - if (strcasecmp(cc_spans->name, "cc_spans")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_spans\"!\n",cc_spans->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"cc_spans\"...\n"); - } - - /* extract the cc_spans */ - cc_span = cc_spans->child; - - while (cc_span != NULL) { - /* parse the found cc_span */ - if (ftmod_ss7_parse_cc_span(cc_span)) { - SS7_ERROR("Failed to parse \"cc_span\"\n"); - return FTDM_FAIL; - } - - /* go to the next cc_span */ - cc_span = cc_span->next; - } - - return FTDM_SUCCESS; - -} - -/******************************************************************************/ -static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span) -{ - sng_ccSpan_t sng_ccSpan; - ftdm_conf_parameter_t *parm = cc_span->parameters; - int num_parms = cc_span->n_parameters; - int flag_clg_nadi = 0; - int flag_cld_nadi = 0; - int flag_rdnis_nadi = 0; - int flag_loc_nadi = 0; - int i; - int ret; - - /* initalize the ccSpan structure */ - memset(&sng_ccSpan, 0x0, sizeof(sng_ccSpan)); - - - /* confirm that we are looking at an mtp_link */ - if (strcasecmp(cc_span->name, "cc_span")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_span\"!\n",cc_span->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"cc_span\"...\n"); - } - - /* Backward compatible. - * If cpg_on_progress_media is not in the config file - * default the cpg on progress_media to TRUE */ - sng_ccSpan.cpg_on_progress_media=FTDM_TRUE; - /* If transparent_iam_max_size is not set in cc spans - * use the global value */ - sng_ccSpan.transparent_iam_max_size=g_ftdm_sngss7_data.cfg.transparent_iam_max_size; - - - for (i = 0; i < num_parms; i++) { - /**************************************************************************/ - - /* try to match the parameter to what we expect */ - if (!strcasecmp(parm->var, "name")) { - /**********************************************************************/ - strcpy((char *)sng_ccSpan.name, parm->val); - SS7_DEBUG("Found an ccSpan named = %s\n", sng_ccSpan.name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "id")) { - /**********************************************************************/ - sng_ccSpan.id = atoi(parm->val); - SS7_DEBUG("Found an ccSpan id = %d\n", sng_ccSpan.id); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "procid")) { - /**********************************************************************/ - sng_ccSpan.procId = atoi(parm->val); - SS7_DEBUG("Found an ccSpan procId = %d\n", sng_ccSpan.procId); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "ch_map")) { - /**********************************************************************/ - strcpy(sng_ccSpan.ch_map, parm->val); - SS7_DEBUG("Found channel map %s\n", sng_ccSpan.ch_map); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "typeCntrl")) { - /**********************************************************************/ - ret = find_cic_cntrl_in_map(parm->val); - if (ret == -1) { - SS7_ERROR("Found an invalid ccSpan typeCntrl = %s\n", parm->var); - return FTDM_FAIL; - } else { - sng_ccSpan.typeCntrl = sng_cic_cntrl_type_map[ret].tril_type; - SS7_DEBUG("Found an ccSpan typeCntrl = %s\n", sng_cic_cntrl_type_map[ret].sng_type); - } - } else if (!strcasecmp(parm->var, "itx_auto_reply")) { - sng_ccSpan.itx_auto_reply = ftdm_true(parm->val); - SS7_DEBUG("Found itx_auto_reply %d\n", sng_ccSpan.itx_auto_reply); - } else if (!strcasecmp(parm->var, "transparent_iam")) { -#ifndef HAVE_ZLIB - SS7_CRIT("Cannot enable transparent IAM becauze zlib not installed\n"); -#else - sng_ccSpan.transparent_iam = ftdm_true(parm->val); - SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam); -#endif - } else if (!strcasecmp(parm->var, "transparent_iam_max_size")) { - sng_ccSpan.transparent_iam_max_size = atoi(parm->val); - SS7_DEBUG("Found transparent_iam_max_size %d\n", sng_ccSpan.transparent_iam_max_size); - } else if (!strcasecmp(parm->var, "cpg_on_progress_media")) { - sng_ccSpan.cpg_on_progress_media = ftdm_true(parm->val); - SS7_DEBUG("Found cpg_on_progress_media %d\n", sng_ccSpan.cpg_on_progress_media); - } else if (!strcasecmp(parm->var, "cpg_on_progress")) { - sng_ccSpan.cpg_on_progress = ftdm_true(parm->val); - SS7_DEBUG("Found cpg_on_progress %d\n", sng_ccSpan.cpg_on_progress); - } else if (!strcasecmp(parm->var, "cicbase")) { - /**********************************************************************/ - sng_ccSpan.cicbase = atoi(parm->val); - SS7_DEBUG("Found a cicbase = %d\n", sng_ccSpan.cicbase); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup_interface")) { - /**********************************************************************/ - sng_ccSpan.isupInf = atoi(parm->val); - SS7_DEBUG("Found an isup_interface = %d\n",sng_ccSpan.isupInf); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "min_digits")) { - /**********************************************************************/ - sng_ccSpan.min_digits = atoi(parm->val); - SS7_DEBUG("Found a min_digits = %d\n",sng_ccSpan.min_digits); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "clg_nadi")) { - /**********************************************************************/ - /* throw the flag so that we know we got this optional parameter */ - flag_clg_nadi = 1; - sng_ccSpan.clg_nadi = atoi(parm->val); - SS7_DEBUG("Found default CLG_NADI parm->value = %d\n", sng_ccSpan.clg_nadi); - } else if (!strcasecmp(parm->var, "cld_nadi")) { - /* throw the flag so that we know we got this optional parameter */ - flag_cld_nadi = 1; - sng_ccSpan.cld_nadi = atoi(parm->val); - SS7_DEBUG("Found default CLD_NADI parm->value = %d\n", sng_ccSpan.cld_nadi); - } else if (!strcasecmp(parm->var, "rdnis_nadi")) { - /* throw the flag so that we know we got this optional parameter */ - flag_rdnis_nadi = 1; - sng_ccSpan.rdnis_nadi = atoi(parm->val); - SS7_DEBUG("Found default RDNIS_NADI parm->value = %d\n", sng_ccSpan.rdnis_nadi); - } else if (!strcasecmp(parm->var, "obci_bita")) { - if (*parm->val == '1') { - sngss7_set_options(&sng_ccSpan, SNGSS7_ACM_OBCI_BITA); - SS7_DEBUG("Found Optional Backwards Indicator: Bit A (early media) enable option\n"); - } else if (*parm->val == '0') { - sngss7_clear_options(&sng_ccSpan, SNGSS7_ACM_OBCI_BITA); - SS7_DEBUG("Found Optional Backwards Indicator: Bit A (early media) disable option\n"); - } else { - SS7_DEBUG("Invalid parm->value for obci_bita option\n"); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "loc_nadi")) { - /* add location reference number */ - flag_loc_nadi = 1; - sng_ccSpan.loc_nadi = atoi(parm->val); - SS7_DEBUG("Found default LOC_NADI parm->value = %d\n", sng_ccSpan.loc_nadi); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "lpa_on_cot")) { - /**********************************************************************/ - if (*parm->val == '1') { - sngss7_set_options(&sng_ccSpan, SNGSS7_LPA_FOR_COT); - SS7_DEBUG("Found Tx LPA on COT enable option\n"); - } else if (*parm->val == '0') { - sngss7_clear_options(&sng_ccSpan, SNGSS7_LPA_FOR_COT); - SS7_DEBUG("Found Tx LPA on COT disable option\n"); - } else { - SS7_DEBUG("Invalid parm->value for lpa_on_cot option\n"); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t3")) { - /**********************************************************************/ - sng_ccSpan.t3 = atoi(parm->val); - SS7_DEBUG("Found isup t3 = %d\n", sng_ccSpan.t3); - } else if (!strcasecmp(parm->var, "isup.t10")) { - /**********************************************************************/ - sng_ccSpan.t10 = atoi(parm->val); - SS7_DEBUG("Found isup t10 = %d\n", sng_ccSpan.t10); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t12")) { - /**********************************************************************/ - sng_ccSpan.t12 = atoi(parm->val); - SS7_DEBUG("Found isup t12 = %d\n", sng_ccSpan.t12); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t13")) { - /**********************************************************************/ - sng_ccSpan.t13 = atoi(parm->val); - SS7_DEBUG("Found isup t13 = %d\n", sng_ccSpan.t13); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t14")) { - /**********************************************************************/ - sng_ccSpan.t14 = atoi(parm->val); - SS7_DEBUG("Found isup t14 = %d\n", sng_ccSpan.t14); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t15")) { - /**********************************************************************/ - sng_ccSpan.t15 = atoi(parm->val); - SS7_DEBUG("Found isup t15 = %d\n", sng_ccSpan.t15); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t16")) { - /**********************************************************************/ - sng_ccSpan.t16 = atoi(parm->val); - SS7_DEBUG("Found isup t16 = %d\n", sng_ccSpan.t16); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t17")) { - /**********************************************************************/ - sng_ccSpan.t17 = atoi(parm->val); - SS7_DEBUG("Found isup t17 = %d\n", sng_ccSpan.t17); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t35")) { - /**********************************************************************/ - sng_ccSpan.t35 = atoi(parm->val); - SS7_DEBUG("Found isup t35 = %d\n",sng_ccSpan.t35); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t39")) { - /**********************************************************************/ - sng_ccSpan.t39 = atoi(parm->val); - SS7_DEBUG("Found isup t39 = %d\n",sng_ccSpan.t39); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.tval")) { - /**********************************************************************/ - sng_ccSpan.tval = atoi(parm->val); - SS7_DEBUG("Found isup tval = %d\n", sng_ccSpan.tval); - /**********************************************************************/ - } else { - /**********************************************************************/ - SS7_ERROR("Found an invalid parameter %s!\n", parm->var); - return FTDM_FAIL; - /**********************************************************************/ - } - - /* move to the next parameter */ - parm = parm + 1; - /**************************************************************************/ - } /* for (i = 0; i < num_parms; i++) */ - - /* check if the user filled in a nadi value by looking at flag */ - if (!flag_cld_nadi) { - /* default the nadi value to national */ - sng_ccSpan.cld_nadi = 0x03; - } - - if (!flag_clg_nadi) { - /* default the nadi value to national */ - sng_ccSpan.clg_nadi = 0x03; - } - - if (!flag_rdnis_nadi) { - /* default the nadi value to national */ - sng_ccSpan.rdnis_nadi = 0x03; - } - - if (!flag_loc_nadi) { - /* default the nadi value to national */ - sng_ccSpan.loc_nadi = 0x03; - } - - /* pull up the SSF and Switchtype from the isup interface */ - sng_ccSpan.ssf = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].ssf; - sng_ccSpan.switchType = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].switchType; - - /* add this span to our global listing */ - ftmod_ss7_fill_in_ccSpan(&sng_ccSpan); - - /* make sure the isup interface structure has something in it */ - if (g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].id == 0) { - /* fill in the id, so that we know it exists */ - g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].id = sng_ccSpan.isupInf; - - /* default the status to PAUSED */ - sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf], SNGSS7_PAUSED); - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_relay_channel(sng_relay_t *relay_channel) -{ - int i; - - /* go through all the existing channels and see if we find a match */ - i = 1; - while (g_ftdm_sngss7_data.cfg.relay[i].id != 0) { - if ((g_ftdm_sngss7_data.cfg.relay[i].type == relay_channel->type) && - (g_ftdm_sngss7_data.cfg.relay[i].port == relay_channel->port) && - (g_ftdm_sngss7_data.cfg.relay[i].procId == relay_channel->procId) && - (!strcasecmp(g_ftdm_sngss7_data.cfg.relay[i].hostname, relay_channel->hostname))) { - - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } - - /* if the id value is 0 that means we didn't find the relay channel */ - if (g_ftdm_sngss7_data.cfg.relay[i].id == 0) { - relay_channel->id = i; - SS7_DEBUG("found new relay channel on type:%d, hostname:%s, port:%d, procId:%d, id = %d\n", - relay_channel->type, - relay_channel->hostname, - relay_channel->port, - relay_channel->procId, - relay_channel->id); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY_PRESENT); - } else { - relay_channel->id = i; - SS7_DEBUG("found existing relay channel on type:%d, hostname:%s, port:%d, procId:%d, id = %d\n", - relay_channel->type, - relay_channel->hostname, - relay_channel->port, - relay_channel->procId, - relay_channel->id); - } - - g_ftdm_sngss7_data.cfg.relay[i].id = relay_channel->id; - g_ftdm_sngss7_data.cfg.relay[i].type = relay_channel->type; - g_ftdm_sngss7_data.cfg.relay[i].port = relay_channel->port; - g_ftdm_sngss7_data.cfg.relay[i].procId = relay_channel->procId; - strcpy(g_ftdm_sngss7_data.cfg.relay[i].hostname, relay_channel->hostname); - strcpy(g_ftdm_sngss7_data.cfg.relay[i].name, relay_channel->name); - - /* if this is THE listen channel grab the procId and use it */ - if (relay_channel->type == LRY_CT_TCP_LISTEN) { - g_ftdm_sngss7_data.cfg.procId = relay_channel->procId; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_mtp1_link(sng_mtp1_link_t *mtp1Link) -{ - int i = mtp1Link->id; - - /* check if this id value has been used already */ - if (g_ftdm_sngss7_data.cfg.mtp1Link[i].id == 0) { - SS7_DEBUG("Found new MTP1 Link: id=%d, name=%s\n", mtp1Link->id, mtp1Link->name); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1_PRESENT); - } else { - SS7_DEBUG("Found an existing MTP1 Link: id=%d, name=%s (old name=%s)\n", - mtp1Link->id, - mtp1Link->name, - g_ftdm_sngss7_data.cfg.mtp1Link[i].name); - } - - /* copy over the values */ - strcpy((char *)g_ftdm_sngss7_data.cfg.mtp1Link[i].name, (char *)mtp1Link->name); - - g_ftdm_sngss7_data.cfg.mtp1Link[i].id = mtp1Link->id; - g_ftdm_sngss7_data.cfg.mtp1Link[i].span = mtp1Link->span; - g_ftdm_sngss7_data.cfg.mtp1Link[i].chan = mtp1Link->chan; - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_mtp2_link(sng_mtp2_link_t *mtp2Link) -{ - int i = mtp2Link->id; - - /* check if this id value has been used already */ - if (g_ftdm_sngss7_data.cfg.mtp2Link[i].id == 0) { - SS7_DEBUG("Found new MTP2 Link: id=%d, name=%s\n", mtp2Link->id, mtp2Link->name); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2_PRESENT); - } else { - SS7_DEBUG("Found an existing MTP2 Link: id=%d, name=%s (old name=%s)\n", - mtp2Link->id, - mtp2Link->name, - g_ftdm_sngss7_data.cfg.mtp2Link[i].name); - } - - /* copy over the values */ - strcpy((char *)g_ftdm_sngss7_data.cfg.mtp2Link[i].name, (char *)mtp2Link->name); - - g_ftdm_sngss7_data.cfg.mtp2Link[i].id = mtp2Link->id; - g_ftdm_sngss7_data.cfg.mtp2Link[i].lssuLength = mtp2Link->lssuLength; - g_ftdm_sngss7_data.cfg.mtp2Link[i].errorType = mtp2Link->errorType; - g_ftdm_sngss7_data.cfg.mtp2Link[i].linkType = mtp2Link->linkType; - g_ftdm_sngss7_data.cfg.mtp2Link[i].mtp1Id = mtp2Link->mtp1Id; - g_ftdm_sngss7_data.cfg.mtp2Link[i].mtp1ProcId = mtp2Link->mtp1ProcId; - - if ( mtp2Link->t1 != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t1 = mtp2Link->t1; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t1 = 500; - } - - if ( mtp2Link->t2 != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t2 = mtp2Link->t2; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t2 = 250; - } - - if ( mtp2Link->t3 != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t3 = mtp2Link->t3; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t3 = 20; - } - - if ( mtp2Link->t4n != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t4n = mtp2Link->t4n; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t4n = 80; - } - - if ( mtp2Link->t4e != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t4e = mtp2Link->t4e; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t4e = 5; - } - - if ( mtp2Link->t5 != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t5 = mtp2Link->t5; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t5 = 1; - } - - if ( mtp2Link->t6 != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t6 = mtp2Link->t6; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t6 = 60; - } - - if ( mtp2Link->t7 != 0 ) { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t7 = mtp2Link->t7; - }else { - g_ftdm_sngss7_data.cfg.mtp2Link[i].t7 = 20; - } - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_mtp3_link(sng_mtp3_link_t *mtp3Link) -{ - int i = mtp3Link->id; - - /* check if this id value has been used already */ - if (g_ftdm_sngss7_data.cfg.mtp3Link[i].id == 0) { - SS7_DEBUG("Found new MTP3 Link: id=%d, name=%s\n", mtp3Link->id, mtp3Link->name); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3_PRESENT); - } else { - SS7_DEBUG("Found an existing MTP3 Link: id=%d, name=%s (old name=%s)\n", - mtp3Link->id, - mtp3Link->name, - g_ftdm_sngss7_data.cfg.mtp3Link[i].name); - } - - /* copy over the values */ - strcpy((char *)g_ftdm_sngss7_data.cfg.mtp3Link[i].name, (char *)mtp3Link->name); - - g_ftdm_sngss7_data.cfg.mtp3Link[i].id = mtp3Link->id; - g_ftdm_sngss7_data.cfg.mtp3Link[i].priority = mtp3Link->priority; - g_ftdm_sngss7_data.cfg.mtp3Link[i].linkType = mtp3Link->linkType; - g_ftdm_sngss7_data.cfg.mtp3Link[i].switchType = mtp3Link->switchType; - g_ftdm_sngss7_data.cfg.mtp3Link[i].apc = mtp3Link->apc; - g_ftdm_sngss7_data.cfg.mtp3Link[i].spc = mtp3Link->spc; /* unknown at this time */ - g_ftdm_sngss7_data.cfg.mtp3Link[i].ssf = mtp3Link->ssf; - g_ftdm_sngss7_data.cfg.mtp3Link[i].slc = mtp3Link->slc; - g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId = mtp3Link->linkSetId; - g_ftdm_sngss7_data.cfg.mtp3Link[i].mtp2Id = mtp3Link->mtp2Id; - g_ftdm_sngss7_data.cfg.mtp3Link[i].mtp2ProcId = mtp3Link->mtp2ProcId; - - if (mtp3Link->t1 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t1 = mtp3Link->t1; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t1 = 8; - } - if (mtp3Link->t2 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t2 = mtp3Link->t2; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t2 = 14; - } - if (mtp3Link->t3 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t3 = mtp3Link->t3; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t3 = 8; - } - if (mtp3Link->t4 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t4 = mtp3Link->t4; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t4 = 8; - } - if (mtp3Link->t5 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t5 = mtp3Link->t5; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t5 = 8; - } - if (mtp3Link->t7 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t7 = mtp3Link->t7; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t7 = 15; - } - if (mtp3Link->t12 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t12 = mtp3Link->t12; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t12 = 15; - } - if (mtp3Link->t13 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t13 = mtp3Link->t13; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t13 = 15; - } - if (mtp3Link->t14 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t14 = mtp3Link->t14; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t14 = 30; - } - if (mtp3Link->t17 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t17 = mtp3Link->t17; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t17 = 15; - } - if (mtp3Link->t22 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t22 = mtp3Link->t22; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t22 = 1800; - } - if (mtp3Link->t23 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t23 = mtp3Link->t23; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t23 = 1800; - } - if (mtp3Link->t24 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t24 = mtp3Link->t24; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t24 = 5; - } - if (mtp3Link->t31 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t31 = mtp3Link->t31; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t31 = 50; - } - if (mtp3Link->t32 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t32 = mtp3Link->t32; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t32 = 120; - } - if (mtp3Link->t33 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t33 = mtp3Link->t33; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t33 = 3000; - } - if (mtp3Link->t34 != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t34 = mtp3Link->t34; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].t34 = 600; - } - if (mtp3Link->tbnd != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].tbnd = mtp3Link->tbnd; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].tbnd = 30000; - } - if (mtp3Link->tflc != 0) { - g_ftdm_sngss7_data.cfg.mtp3Link[i].tflc = mtp3Link->tflc; - } else { - g_ftdm_sngss7_data.cfg.mtp3Link[i].tflc = 300; - } - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) -{ - int i = mtpLinkSet->id; - - strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name, MAX_NAME_LEN-1); - - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc; - - /* these values are filled in as we find routes and start allocating cmbLinkSetIds */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].minActive = mtpLinkSet->minActive; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = 0; - return 0; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) -{ - sng_link_set_list_t *lnkSet = NULL; - int i = mtp3_route->id; - int tmp = 0; - - - /* check if this id value has been used already */ - if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) { - SS7_DEBUG("Found new MTP3 Link: id=%d, name=%s\n", mtp3_route->id, mtp3_route->name); - } else { - SS7_DEBUG("Found an existing MTP3 Link: id=%d, name=%s (old name=%s)\n", - mtp3_route->id, - mtp3_route->name, - g_ftdm_sngss7_data.cfg.mtpRoute[i].name); - } - - /* fill in the cmbLinkSet in the linkset structure */ - lnkSet = &mtp3_route->lnkSets; - - tmp = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks; - g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].links[tmp] = mtp3_route->cmbLinkSetId; - g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks++; - - while (lnkSet->next != NULL) { - tmp = g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks; - g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].links[tmp] = mtp3_route->cmbLinkSetId; - g_ftdm_sngss7_data.cfg.mtpLinkSet[lnkSet->lsId].numLinks++; - - lnkSet = lnkSet->next; - } - - strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name); - - g_ftdm_sngss7_data.cfg.mtpRoute[i].id = mtp3_route->id; - g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc; - g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType = mtp3_route->linkType; - g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType = mtp3_route->switchType; - g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = mtp3_route->cmbLinkSetId; - g_ftdm_sngss7_data.cfg.mtpRoute[i].isSTP = mtp3_route->isSTP; - g_ftdm_sngss7_data.cfg.mtpRoute[i].nwId = mtp3_route->nwId; - g_ftdm_sngss7_data.cfg.mtpRoute[i].lnkSets = mtp3_route->lnkSets; - g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf = mtp3_route->ssf; - g_ftdm_sngss7_data.cfg.mtpRoute[i].dir = SNG_RTE_DN; - if (mtp3_route->t6 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t6 = mtp3_route->t6; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t6 = 8; - } - if (mtp3_route->t8 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t8 = mtp3_route->t8; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t8 = 12; - } - if (mtp3_route->t10 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t10 = mtp3_route->t10; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t10 = 300; - } - if (mtp3_route->t11 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t11 = mtp3_route->t11; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t11 = 300; - } - if (mtp3_route->t15 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t15 = mtp3_route->t15; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t15 = 30; - } - if (mtp3_route->t16 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t16 = mtp3_route->t16; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t16 = 20; - } - if (mtp3_route->t18 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t18 = mtp3_route->t18; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t18 = 200; - } - if (mtp3_route->t19 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t19 = mtp3_route->t19; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t19 = 690; - } - if (mtp3_route->t21 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t21 = mtp3_route->t21; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t21 = 650; - } - if (mtp3_route->t25 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t25 = mtp3_route->t25; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t25 = 100; - } - if (mtp3_route->t26 != 0) { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t26 = mtp3_route->t26; - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].t26 = 100; - } - - return 0; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, int ssf) -{ - int i = 1; - - while (i < (MAX_MTP_ROUTES)) { - if (g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc == spc) { - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } - - if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) { - /* this is a new route...find the first free spot */ - i = 1; - while (i < (MAX_MTP_ROUTES)) { - if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) { - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } - g_ftdm_sngss7_data.cfg.mtpRoute[i].id = i; - SS7_DEBUG("found new mtp3 self route\n"); - } else { - g_ftdm_sngss7_data.cfg.mtpRoute[i].id = i; - SS7_DEBUG("found existing mtp3 self route\n"); - } - - strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, "self-route", MAX_NAME_LEN-1); - - g_ftdm_sngss7_data.cfg.mtpRoute[i].id = i; - g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = spc; - g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType = linkType; - g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType = switchType; - g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = i; - g_ftdm_sngss7_data.cfg.mtpRoute[i].isSTP = 0; - g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf = ssf; - g_ftdm_sngss7_data.cfg.mtpRoute[i].dir = SNG_RTE_UP; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t6 = 8; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t8 = 12; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t10 = 300; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t11 = 300; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t15 = 30; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t16 = 20; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t18 = 200; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t19 = 690; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t21 = 650; - g_ftdm_sngss7_data.cfg.mtpRoute[i].t25 = 100; - - return 0; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) -{ - int i; - - /* go through all the existing interfaces and see if we find a match */ - i = 1; - while (g_ftdm_sngss7_data.cfg.nsap[i].id != 0) { - if ((g_ftdm_sngss7_data.cfg.nsap[i].linkType == mtp3_route->linkType) && - (g_ftdm_sngss7_data.cfg.nsap[i].switchType == mtp3_route->switchType)) { - - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } - - if (g_ftdm_sngss7_data.cfg.nsap[i].id == 0) { - g_ftdm_sngss7_data.cfg.nsap[i].id = i; - SS7_DEBUG("found new mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); - } else { - g_ftdm_sngss7_data.cfg.nsap[i].id = i; - SS7_DEBUG("found existing mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); - } - - g_ftdm_sngss7_data.cfg.nsap[i].spId = g_ftdm_sngss7_data.cfg.nsap[i].id; - g_ftdm_sngss7_data.cfg.nsap[i].suId = g_ftdm_sngss7_data.cfg.nsap[i].id; - g_ftdm_sngss7_data.cfg.nsap[i].nwId = mtp3_route->nwId; - g_ftdm_sngss7_data.cfg.nsap[i].linkType = mtp3_route->linkType; - g_ftdm_sngss7_data.cfg.nsap[i].switchType = mtp3_route->switchType; - g_ftdm_sngss7_data.cfg.nsap[i].ssf = mtp3_route->ssf; - - return 0; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) -{ - int i = sng_isup->id; - - /* check if this id value has been used already */ - if (g_ftdm_sngss7_data.cfg.isupIntf[i].id == 0) { - SS7_DEBUG("Found new ISUP Interface: id=%d, name=%s\n", sng_isup->id, sng_isup->name); - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_PRESENT); - } else { - SS7_DEBUG("Found an existing ISUP Interface: id=%d, name=%s (old name=%s)\n", - sng_isup->id, - sng_isup->name, - g_ftdm_sngss7_data.cfg.isupIntf[i].name); - } - - strncpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name, MAX_NAME_LEN-1); - - g_ftdm_sngss7_data.cfg.isupIntf[i].id = sng_isup->id; - g_ftdm_sngss7_data.cfg.isupIntf[i].mtpRouteId = sng_isup->mtpRouteId; - g_ftdm_sngss7_data.cfg.isupIntf[i].nwId = sng_isup->nwId; - g_ftdm_sngss7_data.cfg.isupIntf[i].dpc = sng_isup->dpc; - g_ftdm_sngss7_data.cfg.isupIntf[i].spc = sng_isup->spc; - g_ftdm_sngss7_data.cfg.isupIntf[i].switchType = sng_isup->switchType; - g_ftdm_sngss7_data.cfg.isupIntf[i].ssf = sng_isup->ssf; - g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap; - g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options; - if (sng_isup->t4 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = 3000; - } - if (sng_isup->t11 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t11 = sng_isup->t11; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t11 = 170; - } - if (sng_isup->t18 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t18 = sng_isup->t18; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t18 = 300; - } - if (sng_isup->t19 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t19 = sng_isup->t19; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t19 = 3000; - } - if (sng_isup->t20 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t20 = sng_isup->t20; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t20 = 300; - } - if (sng_isup->t21 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t21 = sng_isup->t21; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t21 = 3000; - } - if (sng_isup->t22 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t22 = sng_isup->t22; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t22 = 300; - } - if (sng_isup->t23 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t23 = sng_isup->t23; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t23 = 3000; - } - if (sng_isup->t24 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t24 = sng_isup->t24; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t24 = 10; - } - if (sng_isup->t25 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t25 = sng_isup->t25; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t25 = 20; - } - if (sng_isup->t26 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t26 = sng_isup->t26; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t26 = 600; - } - if (sng_isup->t28 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t28 = sng_isup->t28; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t28 = 100; - } - if (sng_isup->t29 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t29 = sng_isup->t29; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t29 = 6; - } - if (sng_isup->t30 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t30 = sng_isup->t30; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t30 = 50; - } - if (sng_isup->t32 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t32 = sng_isup->t32; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t32 = 30; - } - if (sng_isup->t37 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t37 = sng_isup->t37; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t37 = 20; - } - if (sng_isup->t38 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t38 = sng_isup->t38; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t38 = 1200; - } - if (sng_isup->t39 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t39 = sng_isup->t39; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t39 = 300; - } - if (sng_isup->tfgr != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].tfgr = sng_isup->tfgr; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].tfgr = 50; - } - if (sng_isup->tpause != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].tpause = sng_isup->tpause; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].tpause = 3000; - } - if (sng_isup->tstaenq != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].tstaenq = sng_isup->tstaenq; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].tstaenq = 5000; - } - - return 0; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap) -{ - int i; - - /* go through all the existing interfaces and see if we find a match */ - i = 1; - while (g_ftdm_sngss7_data.cfg.isap[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.isap[i].switchType == sng_isap->switchType) { - - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } - - if (g_ftdm_sngss7_data.cfg.isap[i].id == 0) { - sng_isap->id = i; - SS7_DEBUG("found new isup to cc interface, id is = %d\n", sng_isap->id); - } else { - sng_isap->id = i; - SS7_DEBUG("found existing isup to cc interface, id is = %d\n", sng_isap->id); - } - - g_ftdm_sngss7_data.cfg.isap[i].id = sng_isap->id; - g_ftdm_sngss7_data.cfg.isap[i].suId = sng_isap->id; - g_ftdm_sngss7_data.cfg.isap[i].spId = sng_isap->id; - g_ftdm_sngss7_data.cfg.isap[i].switchType = sng_isap->switchType; - g_ftdm_sngss7_data.cfg.isap[i].ssf = sng_isap->ssf; - - if (sng_isap->t1 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t1 = sng_isap->t1; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t1 = 150; - } - if (sng_isap->t2 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t2 = sng_isap->t2; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t2 = 1800; - } - if (sng_isap->t5 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t5 = sng_isap->t5; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t5 = 3000; - } - if (sng_isap->t6 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t6 = sng_isap->t6; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t6 = 600; - } - if (sng_isap->t7 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t7 = sng_isap->t7; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t7 = 200; - } - if (sng_isap->t8 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t8 = sng_isap->t8; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t8 = 100; - } - if (sng_isap->t9 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t9 = sng_isap->t9; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t9 = 1800; - } - if (sng_isap->t27 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t27 = sng_isap->t27; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t27 = 2400; - } - if (sng_isap->t31 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t31 = sng_isap->t31; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t31 = 3650; - } - if (sng_isap->t33 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t33 = sng_isap->t33; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t33 = 120; - } - if (sng_isap->t34 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t34 = sng_isap->t34; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t34 = 40; - } - if (sng_isap->t36 != 0) { - g_ftdm_sngss7_data.cfg.isap[i].t36 = sng_isap->t36; - } else { - g_ftdm_sngss7_data.cfg.isap[i].t36 = 120; - } - if (sng_isap->tccr != 0) { - g_ftdm_sngss7_data.cfg.isap[i].tccr = sng_isap->tccr; - } else { - g_ftdm_sngss7_data.cfg.isap[i].tccr = 200; - } - if (sng_isap->tccrt != 0) { - g_ftdm_sngss7_data.cfg.isap[i].tccrt = sng_isap->tccrt; - } else { - g_ftdm_sngss7_data.cfg.isap[i].tccrt = 20; - } - if (sng_isap->tex != 0) { - g_ftdm_sngss7_data.cfg.isap[i].tex = sng_isap->tex; - } else { - g_ftdm_sngss7_data.cfg.isap[i].tex = 1000; - } - if (sng_isap->tcrm != 0) { - g_ftdm_sngss7_data.cfg.isap[i].tcrm = sng_isap->tcrm; - } else { - g_ftdm_sngss7_data.cfg.isap[i].tcrm = 30; - } - if (sng_isap->tcra != 0) { - g_ftdm_sngss7_data.cfg.isap[i].tcra = sng_isap->tcra; - } else { - g_ftdm_sngss7_data.cfg.isap[i].tcra = 100; - } - if (sng_isap->tect != 0) { - g_ftdm_sngss7_data.cfg.isap[i].tect = sng_isap->tect; - } else { - g_ftdm_sngss7_data.cfg.isap[i].tect = 10; - } - if (sng_isap->trelrsp != 0) { - g_ftdm_sngss7_data.cfg.isap[i].trelrsp = sng_isap->trelrsp; - } else { - g_ftdm_sngss7_data.cfg.isap[i].trelrsp = 10; - } - if (sng_isap->tfnlrelrsp != 0) { - g_ftdm_sngss7_data.cfg.isap[i].tfnlrelrsp = sng_isap->tfnlrelrsp; - } else { - g_ftdm_sngss7_data.cfg.isap[i].tfnlrelrsp = 10; - } - - return 0; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) -{ - sng_timeslot_t timeslot; - sngss7_chan_data_t *ss7_info = NULL; - int x; - int count = 1; - int flag; - - while (ccSpan->ch_map[0] != '\0') { - /**************************************************************************/ - - /* pull out the next timeslot */ - if (ftmod_ss7_next_timeslot(ccSpan->ch_map, ×lot)) { - SS7_ERROR("Failed to parse the channel map!\n"); - return FTDM_FAIL; - } - - /* find a spot for this circuit in the global structure */ - x = (ccSpan->procId * 1000) + 1; - flag = 0; - while (flag == 0) { - /**********************************************************************/ - /* check the id value ( 0 = new, 0 > circuit can be existing) */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) { - /* we're at the end of the list of circuitsl aka this is new */ - SS7_DEBUG("Found a new circuit %d, ccSpanId=%d, chan=%d\n", - x, - ccSpan->id, - count); - - /* throw the flag to end the loop */ - flag = 1; - } else { - /* check the ccspan.id and chan to see if the circuit already exists */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId == ccSpan->id) && - (g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count)) { - - /* we are processing a circuit that already exists */ - SS7_DEVEL_DEBUG("Found an existing circuit %d, ccSpanId=%d, chan%d\n", - x, - ccSpan->id, - count); - - /* throw the flag to end the loop */ - flag = 1; - - /* not supporting reconfig at this time */ - SS7_DEVEL_DEBUG("Not supporting ckt reconfig at this time!\n"); - goto move_along; - } else { - /* this is not the droid you are looking for */ - x++; - } - } - /**********************************************************************/ - } /* while (flag == 0) */ - - /* prepare the global info sturcture */ - ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); - ss7_info->ftdmchan = NULL; - if (ftdm_queue_create(&ss7_info->event_queue, SNGSS7_CHAN_EVENT_QUEUE_SIZE) != FTDM_SUCCESS) { - SS7_CRITICAL("Failed to create ss7 cic event queue\n"); - } - ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; - - g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; - - /* fill in the rest of the global structure */ - g_ftdm_sngss7_data.cfg.isupCkt[x].procId = ccSpan->procId; - g_ftdm_sngss7_data.cfg.isupCkt[x].id = x; - g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId = ccSpan->id; - g_ftdm_sngss7_data.cfg.isupCkt[x].span = 0; - g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count; - - if (timeslot.siglink) { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = SNG_CKT_SIG; - } else if (timeslot.gap) { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = SNG_CKT_HOLE; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = SNG_CKT_VOICE; - - /* throw the flag to indicate that we need to start call control */ - sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC_PRESENT); - } - - if (timeslot.channel) { - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = ccSpan->cicbase; - ccSpan->cicbase++; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0; - } - - g_ftdm_sngss7_data.cfg.isupCkt[x].infId = ccSpan->isupInf; - g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = ccSpan->typeCntrl; - g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf; - g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi; - g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi; - g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi; - g_ftdm_sngss7_data.cfg.isupCkt[x].loc_nadi = ccSpan->loc_nadi; - g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options; - g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType; - g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits; - g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply; - g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam; - g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam_max_size = ccSpan->transparent_iam_max_size; - g_ftdm_sngss7_data.cfg.isupCkt[x].cpg_on_progress_media = ccSpan->cpg_on_progress_media; - g_ftdm_sngss7_data.cfg.isupCkt[x].cpg_on_progress = ccSpan->cpg_on_progress; - - if (ccSpan->t3 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = ccSpan->t3; - } - if (ccSpan->t10 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t10 = 50; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t10 = ccSpan->t10; - } - if (ccSpan->t12 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = ccSpan->t12; - } - if (ccSpan->t13 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = ccSpan->t13; - } - if (ccSpan->t14 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = ccSpan->t14; - } - if (ccSpan->t15 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = ccSpan->t15; - } - if (ccSpan->t16 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = ccSpan->t16; - } - if (ccSpan->t17 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = ccSpan->t17; - } - if (ccSpan->t35 == 0) { - /* Q.764 2.2.5 Address incomplete (T35 is 15-20 seconds according to Table A.1/Q.764) */ - g_ftdm_sngss7_data.cfg.isupCkt[x].t35 = 170; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t35 = ccSpan->t35; - } - if (ccSpan->t39 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = 120; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = ccSpan->t39; - } - - if (ccSpan->tval == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].tval = ccSpan->tval; - } - - SS7_INFO("Added procId=%d, spanId = %d, chan = %d, cic = %d, ISUP cirId = %d\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].procId, - g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId, - g_ftdm_sngss7_data.cfg.isupCkt[x].chan, - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - -move_along: - /* increment the span channel count */ - count++; - - /**************************************************************************/ - } /* while (ccSpan->ch_map[0] != '\0') */ - - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan) -{ - ftdm_channel_t *ftdmchan = NULL; - ftdm_span_t *ftdmspan = sngSpan->span; - sng_isup_ckt_t *isupCkt = NULL; - sngss7_chan_data_t *ss7_info = NULL; - int flag; - int i; - int x; - - /* go through all the channels on ftdm span */ - for (i = 1; i < (ftdmspan->chan_count+1); i++) { - /**************************************************************************/ - - /* extract the ftdmchan pointer */ - ftdmchan = ftdmspan->channels[i]; - - /* find the equivalent channel in the global structure */ - x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; - flag = 0; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /**********************************************************************/ - /* pull out the circuit to make it easier to work with */ - isupCkt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; - - /* if the ccSpanId's match fill in the span value...this is for sigs - * because they will never have a channel that matches since they - * have a ftdmchan at this time */ - if (sngSpan->ccSpanId == isupCkt->ccSpanId) { - isupCkt->span = ftdmchan->physical_span_id; - } - - /* check if the ccSpanId matches and the physical channel # match */ - if ((sngSpan->ccSpanId == isupCkt->ccSpanId) && - (ftdmchan->physical_chan_id == isupCkt->chan)) { - - /* we've found the channel in the ckt structure...raise the flag */ - flag = 1; - - /* now get out of the loop */ - break; - } - - /* move to the next ckt */ - x++; - - /* check if we are outside of the range of possible indexes */ - if (x == ((g_ftdm_sngss7_data.cfg.procId + 1) * 1000)) { - break; - } - /**********************************************************************/ - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - - /* check we found the ckt or not */ - if (!flag) { - SS7_ERROR_CHAN(ftdmchan, "Failed to find this channel in the global ckts!%s\n",""); - return FTDM_FAIL; - } - - /* fill in the rest of the global sngss7_chan_data_t structure */ - ss7_info = (sngss7_chan_data_t *)isupCkt->obj; - ss7_info->ftdmchan = ftdmchan; - - /* attach the sngss7_chan_data_t to the freetdm channel structure */ - ftdmchan->call_data = ss7_info; - - /* prepare the timer structures */ - ss7_info->t35.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched; - ss7_info->t35.counter = 1; - ss7_info->t35.beat = (isupCkt->t35) * 100; /* beat is in ms, t35 is in 100ms */ - ss7_info->t35.callback = handle_isup_t35; - ss7_info->t35.sngss7_info = ss7_info; - - ss7_info->t10.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched; - ss7_info->t10.counter = 1; - ss7_info->t10.beat = (isupCkt->t10) * 100; /* beat is in ms, t10 is in 100ms */ - ss7_info->t10.callback = handle_isup_t10; - ss7_info->t10.sngss7_info = ss7_info; - - /* prepare the timer structures */ - ss7_info->t39.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched; - ss7_info->t39.counter = 1; - ss7_info->t39.beat = (isupCkt->t39) * 100; /* beat is in ms, t39 is in 100ms */ - ss7_info->t39.callback = handle_isup_t39; - ss7_info->t39.sngss7_info = ss7_info; - - - /**************************************************************************/ - } /* for (i == 1; i < ftdmspan->chan_count; i++) */ - - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot) -{ - int i; - int x; - int lower; - int upper; - char tmp[5]; /*KONRAD FIX ME*/ - char new_ch_map[MAX_CIC_MAP_LENGTH]; - - memset(&tmp[0], '\0', sizeof(tmp)); - memset(&new_ch_map[0], '\0', sizeof(new_ch_map)); - memset(timeslot, 0x0, sizeof(sng_timeslot_t)); - - SS7_DEVEL_DEBUG("Old channel map = \"%s\"\n", ch_map); - - /* start at the beginning of the ch_map */ - x = 0; - - switch (ch_map[x]) { - /**************************************************************************/ - case 'S': - case 's': /* we have a sig link */ - timeslot->siglink = 1; - - /* check what comes next either a comma or a number */ - x++; - if (ch_map[x] == ',') { - timeslot->hole = 1; - SS7_DEVEL_DEBUG(" Found a siglink in the channel map with a hole in the cic map\n"); - } else if (isdigit(ch_map[x])) { - /* consume all digits until a comma as this is the channel */ - SS7_DEVEL_DEBUG(" Found a siglink in the channel map with out a hole in the cic map\n"); - } else { - SS7_ERROR("Found an illegal channel map character after signal link flag = \"%c\"!\n", ch_map[x]); - return FTDM_FAIL; - } - break; - /**************************************************************************/ - case 'G': - case 'g': /* we have a channel gap */ - timeslot->gap = 1; - - /* check what comes next either a comma or a number */ - x++; - if (ch_map[x] == ',') { - timeslot->hole = 1; - SS7_DEVEL_DEBUG(" Found a gap in the channel map with a hole in the cic map\n"); - } else if (isdigit(ch_map[x])) { - SS7_DEVEL_DEBUG(" Found a gap in the channel map with out a hole in the cic map\n"); - /* consume all digits until a comma as this is the channel */ - } else { - SS7_ERROR("Found an illegal channel map character after signal link flag = \"%c\"!\n", ch_map[x]); - return FTDM_FAIL; - } - break; - /**************************************************************************/ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': /* we have a channel */ - /* consume all digits until a comma or a dash */ - SS7_DEVEL_DEBUG("Found a starting channel in the channel map\n"); - break; - /**************************************************************************/ - default: - SS7_ERROR("Found an illegal channel map character = \"%c\"!\n", ch_map[x]); - return FTDM_FAIL; - /**************************************************************************/ - } /* switch (ch_map[x]) */ - - /* grab the first number in the string */ - i = 0; - while ((ch_map[x] != '\0') && (ch_map[x] != '-') && (ch_map[x] != ',')) { - tmp[i] = ch_map[x]; - i++; - x++; - } - tmp[i] = '\0'; - timeslot->channel = atoi(tmp); - lower = timeslot->channel + 1; - - /* check the next value in the list */ - if (ch_map[x] == '-') { - /* consume the number after the dash */ - x++; - i = 0; - while ((ch_map[x] != '\0') && (ch_map[x] != '-') && (ch_map[x] != ',')) { - tmp[i] = ch_map[x]; - i++; - x++; - } - tmp[i] = '\0'; - upper = atoi(tmp); - - /* check if the upper end of the range is the same as the lower end of the range */ - if (upper == lower) { - /* the range is completed, eat the next comma or \0 and write it */ - sprintf(new_ch_map, "%d", lower); - } else if ( upper > lower) { - /* the list continues, add 1 from the channel map value and re-insert it to the list */ - sprintf(new_ch_map, "%d-%d", lower, upper); - } else { - SS7_ERROR("The upper is less then the lower end of the range...should not happen!\n"); - return FTDM_FAIL; - } - - /* the the rest of ch_map to new_ch_map */ - strncat(new_ch_map, &ch_map[x], strlen(&ch_map[x])); - - - /* set the new cic map to ch_map*/ - memset(ch_map, '\0', sizeof(ch_map)); - strcpy(ch_map, new_ch_map); - - } else if (ch_map[x] == ',') { - /* move past the comma */ - x++; - - /* copy the rest of the list to new_ch_map */ - memset(new_ch_map, '\0', sizeof(new_ch_map)); - strcpy(new_ch_map, &ch_map[x]); - - /* copy the new_ch_map over the old one */ - memset(ch_map, '\0', sizeof(ch_map)); - strcpy(ch_map, new_ch_map); - - } else if (ch_map[x] == '\0') { - - /* we're at the end of the string...copy the rest of the list to new_ch_map */ - memset(new_ch_map, '\0', sizeof(new_ch_map)); - strcpy(new_ch_map, &ch_map[x]); - - /* set the new cic map to ch_map*/ - memset(ch_map, '\0', sizeof(ch_map)); - strcpy(ch_map, new_ch_map); - } else { - /* nothing to do */ - } - - SS7_DEVEL_DEBUG("New channel map = \"%s\"\n", ch_map); - - return FTDM_SUCCESS; -} - -/******************************************************************************/ - -/******************************************************************************/ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ -/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_skel/ftmod_skel.c b/libs/freetdm/src/ftmod/ftmod_skel/ftmod_skel.c deleted file mode 100644 index 7d8a9b7393..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_skel/ftmod_skel.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "private/ftdm_core.h" -//#include "ftdm_skel.h" - -static FIO_CONFIGURE_FUNCTION(skel_configure) -{ - ftdm_unused_arg(category); - ftdm_unused_arg(var); - ftdm_unused_arg(val); - ftdm_unused_arg(lineno); - return FTDM_FAIL; -} - -static FIO_CONFIGURE_SPAN_FUNCTION(skel_configure_span) -{ - ftdm_unused_arg(span); - ftdm_unused_arg(str); - ftdm_unused_arg(type); - ftdm_unused_arg(name); - ftdm_unused_arg(number); - return FTDM_FAIL; -} - -static FIO_OPEN_FUNCTION(skel_open) -{ - ftdm_unused_arg(ftdmchan); - return FTDM_FAIL; -} - -static FIO_CLOSE_FUNCTION(skel_close) -{ - ftdm_unused_arg(ftdmchan); - return FTDM_FAIL; -} - -static FIO_WAIT_FUNCTION(skel_wait) -{ - ftdm_unused_arg(ftdmchan); - ftdm_unused_arg(flags); - ftdm_unused_arg(to); - return FTDM_FAIL; -} - -static FIO_READ_FUNCTION(skel_read) -{ - ftdm_unused_arg(ftdmchan); - ftdm_unused_arg(data); - ftdm_unused_arg(datalen); - return FTDM_FAIL; -} - -static FIO_WRITE_FUNCTION(skel_write) -{ - ftdm_unused_arg(ftdmchan); - ftdm_unused_arg(data); - ftdm_unused_arg(datalen); - return FTDM_FAIL; -} - -static FIO_COMMAND_FUNCTION(skel_command) -{ - ftdm_unused_arg(ftdmchan); - ftdm_unused_arg(command); - ftdm_unused_arg(obj); - return FTDM_FAIL; -} - -static FIO_SPAN_POLL_EVENT_FUNCTION(skel_poll_event) -{ - ftdm_unused_arg(span); - ftdm_unused_arg(ms); - ftdm_unused_arg(poll_events); - return FTDM_FAIL; -} - -static FIO_SPAN_NEXT_EVENT_FUNCTION(skel_next_event) -{ - ftdm_unused_arg(span); - ftdm_unused_arg(event); - return FTDM_FAIL; -} - -static FIO_CHANNEL_DESTROY_FUNCTION(skel_channel_destroy) -{ - ftdm_unused_arg(ftdmchan); - return FTDM_FAIL; -} - -static FIO_SPAN_DESTROY_FUNCTION(skel_span_destroy) -{ - ftdm_unused_arg(span); - return FTDM_FAIL; -} - -static FIO_GET_ALARMS_FUNCTION(skel_get_alarms) -{ - ftdm_unused_arg(ftdmchan); - return FTDM_FAIL; -} - -static ftdm_io_interface_t skel_interface; - -static FIO_IO_LOAD_FUNCTION(skel_init) -{ - assert(fio != NULL); - memset(&skel_interface, 0, sizeof(skel_interface)); - - skel_interface.name = "skel"; - skel_interface.configure = skel_configure; - skel_interface.configure_span = skel_configure_span; - skel_interface.open = skel_open; - skel_interface.close = skel_close; - skel_interface.wait = skel_wait; - skel_interface.read = skel_read; - skel_interface.write = skel_write; - skel_interface.command = skel_command; - skel_interface.poll_event = skel_poll_event; - skel_interface.next_event = skel_next_event; - skel_interface.channel_destroy = skel_channel_destroy; - skel_interface.span_destroy = skel_span_destroy; - skel_interface.get_alarms = skel_get_alarms; - *fio = &skel_interface; - - return FTDM_SUCCESS; -} - -static FIO_IO_UNLOAD_FUNCTION(skel_destroy) -{ - return FTDM_SUCCESS; -} - - -ftdm_module_t ftdm_module = { - "skel", - skel_init, - skel_destroy, -}; - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2008.vcproj deleted file mode 100644 index 7fdb0ff592..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2008.vcproj +++ /dev/null @@ -1,355 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj.filters deleted file mode 100644 index 15a8bc3d35..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj.filters +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c deleted file mode 100755 index 58b5c9ca0e..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ /dev/null @@ -1,1807 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * David Yat Sin - * Nenad Corbic - * Arnaldo Pereira - * Gideon Sadan - * - */ -#ifdef WP_DEBUG_IO -#ifndef _DEFAULT_SOURCE -#define _DEFAULT_SOURCE -#endif -#define _BSD_SOURCE -#include -#endif - -#ifdef __sun -#include -#include -#endif -#include "private/ftdm_core.h" -#ifndef __WINDOWS__ -#include -#include -#endif -#include "libsangoma.h" - -#if defined(__WINDOWS__) -/*! Backward compatible defines - current code is all using the old names*/ -#define sangoma_open_tdmapi_span_chan sangoma_open_api_span_chan -#define sangoma_open_tdmapi_span sangoma_open_api_span -#define sangoma_open_tdmapi_ctrl sangoma_open_api_ctrl -#define sangoma_tdm_get_fe_status sangoma_get_fe_status -#define sangoma_socket_close sangoma_close -#define sangoma_tdm_get_hw_coding sangoma_get_hw_coding -#define sangoma_tdm_set_fe_status sangoma_set_fe_status -#define sangoma_tdm_get_link_status sangoma_get_link_status -#define sangoma_tdm_flush_bufs sangoma_flush_bufs -#define sangoma_tdm_cmd_exec sangoma_cmd_exec -#define sangoma_tdm_read_event sangoma_read_event -#define sangoma_readmsg_tdm sangoma_readmsg -#define sangoma_readmsg_socket sangoma_readmsg -#define sangoma_sendmsg_socket sangoma_writemsg -#define sangoma_writemsg_tdm sangoma_writemsg -#define sangoma_create_socket_intr sangoma_open_api_span_chan -#endif - -/*! Starting with libsangoma 3 we can use the new libsangoma waitable API, the poor souls of those using a release where LIBSANGOMA version - * is defined but the version is not higher or equal to 3.0.0 will be forced to upgrade - * */ -#ifdef LIBSANGOMA_VERSION -#if LIBSANGOMA_VERSION_CODE < LIBSANGOMA_VERSION(3,0,0) -#undef LIBSANGOMA_VERSION -#endif -#endif - -/** - * \brief Wanpipe flags - */ -typedef enum { - WP_RINGING = (1 << 0) -} wp_flag_t; - -/** - * \brief Wanpipe globals - */ -static struct { - uint32_t codec_ms; - uint32_t rxqueue_size; - uint32_t txqueue_size; - uint32_t wink_ms; - uint32_t flash_ms; - uint32_t ring_on_ms; - uint32_t ring_off_ms; -} wp_globals; - -typedef struct { - sangoma_wait_obj_t *waitobj; -#ifdef WP_DEBUG_IO - /* record the last reader threads */ - pid_t readers[10]; - int rindex; - ftdm_time_t last_read; -#endif -} wp_channel_t; -#define WP_GET_WAITABLE(fchan) ((wp_channel_t *)((fchan)->io_data))->waitobj - -/* a bunch of this stuff should go into the wanpipe_tdm_api_iface.h */ - -FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event); -FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event); -FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event); - -static void wp_swap16(char *data, int datalen) -{ - int i = 0; - uint16_t *samples = (uint16_t *)data; - for (i = 0; i < datalen/2; i++) { - uint16_t sample = ((samples[i] & 0x00FF) << 8) | ((samples[i] & 0xFF00) >> 8); - samples[i] = sample; - } -} - -/** - * \brief Poll for event on a wanpipe socket - * \param fd Wanpipe socket descriptor - * \param timeout Time to wait for event - * \param flags Sangoma event flags - * \return -1 on failure, wanpipe event flags on success - * - * a cross platform way to poll on an actual pollset (span and/or list of spans) will probably also be needed for analog - * so we can have one analong handler thread that will deal with all the idle analog channels for events - * the alternative would be for the driver to provide one socket for all of the oob events for all analog channels - */ -static __inline__ int tdmv_api_wait_socket(ftdm_channel_t *ftdmchan, int timeout, int *flags) -{ - -#ifdef LIBSANGOMA_VERSION - int err; - uint32_t inflags = *flags; - uint32_t outflags = 0; - sangoma_wait_obj_t *sangoma_wait_obj = WP_GET_WAITABLE(ftdmchan); - - if (timeout == -1) { - timeout = SANGOMA_WAIT_INFINITE; - } - - err = sangoma_waitfor(sangoma_wait_obj, inflags, &outflags, timeout); - *flags = 0; - if (err == SANG_STATUS_SUCCESS) { - *flags = outflags; - err = 1; /* ideally should be the number of file descriptors with something to read */ - } - if (err == SANG_STATUS_APIPOLL_TIMEOUT) { - err = 0; - } - return err; -#else - struct pollfd pfds[1]; - int res; - - memset(&pfds[0], 0, sizeof(pfds[0])); - pfds[0].fd = ftdmchan->sockfd; - pfds[0].events = *flags; - res = poll(pfds, 1, timeout); - *flags = 0; - - if (pfds[0].revents & POLLERR) { - res = -1; - } - - if (res > 0) { - *flags = pfds[0].revents; - } - - return res; -#endif - -} - -/** - * \brief Opens a sangoma channel socket (TDM API) - * \param span Span number - * \param chan Channel number - * \return 0 on success, wanpipe error code on failure - */ -static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan) -{ - return sangoma_open_tdmapi_span_chan(span, chan); -} - -#ifdef LIBSANGOMA_VERSION -static __inline__ sng_fd_t __tdmv_api_open_span_chan(int span, int chan) -{ - return __sangoma_open_tdmapi_span_chan(span, chan); -} -#endif - -static ftdm_io_interface_t wanpipe_interface; - -/** - * \brief Inverts bit string - * \param cas_bits CAS bit string - * \return Swapped bits - */ -static unsigned char wanpipe_swap_bits(unsigned char cas_bits) -{ - unsigned char swapped_bits = 0x0; - if (cas_bits & 0x8) { - swapped_bits |= 0x1; - } - if (cas_bits & 0x4) { - swapped_bits |= 0x2; - } - if (cas_bits & 0x2) { - swapped_bits |= 0x4; - } - if (cas_bits & 0x1) { - swapped_bits |= 0x8; - } - return swapped_bits; -} - -/** - * \brief Initialises a range of wanpipe channels - * \param span FreeTDM span - * \param spanno Wanpipe span number - * \param start Initial wanpipe channel number - * \param end Final wanpipe channel number - * \param type FreeTDM channel type - * \param name FreeTDM span name - * \param number FreeTDM span number - * \param cas_bits CAS bits - * \return number of spans configured - */ -static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start, unsigned end, ftdm_chan_type_t type, char *name, char *number, unsigned char cas_bits) -{ - unsigned configured = 0, x; -#ifdef LIBSANGOMA_VERSION - sangoma_status_t sangstatus; - sangoma_wait_obj_t *sangoma_wait_obj; -#endif - - if (type == FTDM_CHAN_TYPE_CAS) { - ftdm_log(FTDM_LOG_DEBUG, "Configuring Wanpipe CAS channels with abcd == 0x%X\n", cas_bits); - } - for(x = start; x < end; x++) { - ftdm_channel_t *chan; - ftdm_socket_t sockfd = FTDM_INVALID_SOCKET; - const char *dtmf = "none"; - const char *hwec_str = "none"; - const char *hwec_idle = "none"; - if (!strncasecmp(span->name, "smg_prid_nfas", 8) && span->trunk_type == FTDM_TRUNK_T1 && x == 24) { -#ifdef LIBSANGOMA_VERSION - sockfd = __tdmv_api_open_span_chan(spanno, x); -#else - ftdm_log(FTDM_LOG_ERROR, "span %d channel %d cannot be configured as smg_prid_nfas, you need to compile freetdm with newer libsangoma\n", spanno, x); -#endif - } else { -#ifdef LIBSANGOMA_VERSION - sockfd = __tdmv_api_open_span_chan(spanno, x); -#else - sockfd = tdmv_api_open_span_chan(spanno, x); -#endif - } - - if (sockfd == FTDM_INVALID_SOCKET) { - ftdm_log(FTDM_LOG_ERROR, "Failed to open wanpipe device span %d channel %d\n", spanno, x); - continue; - } - - if (ftdm_span_add_channel(span, sockfd, type, &chan) == FTDM_SUCCESS) { - wp_channel_t *wpchan = NULL; - wanpipe_tdm_api_t tdm_api; - memset(&tdm_api, 0, sizeof(tdm_api)); -#ifdef LIBSANGOMA_VERSION - wpchan = ftdm_calloc(1, sizeof(*wpchan)); - ftdm_assert(wpchan != NULL, "wpchan alloc failed\n"); - chan->io_data = wpchan; - /* we need SANGOMA_DEVICE_WAIT_OBJ_SIG and not SANGOMA_DEVICE_WAIT_OBJ alone because we need to call - * sangoma_wait_obj_sig to wake up any I/O waiters when closing the channel (typically on ftdm shutdown) - * this adds an extra pair of file descriptors to the waitable object - * */ - sangstatus = sangoma_wait_obj_create(&sangoma_wait_obj, sockfd, SANGOMA_DEVICE_WAIT_OBJ_SIG); - if (sangstatus != SANG_STATUS_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "failure create waitable object for s%dc%d\n", spanno, x); - continue; - } - WP_GET_WAITABLE(chan) = sangoma_wait_obj; -#endif - - chan->physical_span_id = spanno; - chan->physical_chan_id = x; - chan->rate = 8000; - - if (type == FTDM_CHAN_TYPE_FXS - || type == FTDM_CHAN_TYPE_FXO - || type == FTDM_CHAN_TYPE_CAS - || type == FTDM_CHAN_TYPE_B) { - int err; - - hwec_str = "unavailable"; - hwec_idle = "enabled"; - dtmf = "software"; - - err = sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api); - - - - if (tdm_api.wp_tdm_cmd.hw_tdm_coding) { - chan->native_codec = chan->effective_codec = FTDM_CODEC_ALAW; - } else { - chan->native_codec = chan->effective_codec = FTDM_CODEC_ULAW; - } - - - if ((span->trunk_type == FTDM_TRUNK_GSM) && (chan->type == FTDM_CHAN_TYPE_B)) { - chan->native_codec = FTDM_CODEC_SLIN; - chan->native_interval = 20; - chan->packet_len = 320; - } - - err = sangoma_tdm_get_hw_dtmf(chan->sockfd, &tdm_api); - if (err > 0) { - ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT); - dtmf = "hardware"; - } - - err = sangoma_tdm_get_hw_ec(chan->sockfd, &tdm_api); - if (err > 0) { - hwec_str = "available"; - ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC); - } - -#ifdef WP_API_FEATURE_HWEC_PERSIST - err = sangoma_tdm_get_hwec_persist_status(chan->sockfd, &tdm_api); - if (err == 0) { - ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE); - hwec_idle = "disabled"; - } -#else - if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - ftdm_log(FTDM_LOG_WARNING, "WP_API_FEATURE_HWEC_PERSIST feature is not supported \ - with your version of libsangoma, you should update your Wanpipe drivers\n"); - - } -#endif - - } - -#ifdef LIBSANGOMA_VERSION - if (type == FTDM_CHAN_TYPE_FXS) { - if (sangoma_tdm_disable_ring_trip_detect_events(chan->sockfd, &tdm_api)) { - /* we had problems of on-hook/off-hook detection due to how ring trip events were handled - * if this fails, I believe we will still work ok as long as we dont handle them incorrectly */ - ftdm_log(FTDM_LOG_WARNING, "Failed to disable ring trip events in channel s%dc%d\n", spanno, x); - } - } -#endif -#if 0 - if (type == FTDM_CHAN_TYPE_FXS || type == FTDM_CHAN_TYPE_FXO) { - /* Enable FLASH/Wink Events */ - int err=sangoma_set_rm_rxflashtime(chan->sockfd, &tdm_api, wp_globals.flash_ms); - if (err == 0) { - ftdm_log(FTDM_LOG_ERROR, "flash enabled s%dc%d\n", spanno, x); - } else { - ftdm_log(FTDM_LOG_ERROR, "flash disabled s%dc%d\n", spanno, x); - } - } -#endif - - if (type == FTDM_CHAN_TYPE_CAS || type == FTDM_CHAN_TYPE_EM) { -#ifdef LIBSANGOMA_VERSION - sangoma_tdm_write_rbs(chan->sockfd,&tdm_api,chan->physical_chan_id, wanpipe_swap_bits(cas_bits)); - - /* this should probably be done for old libsangoma but I am not sure if the API is available and I'm lazy to check, - The poll rate is hard coded to 100 per second (done in the driver, is the max rate of polling allowed by wanpipe) - */ - if (sangoma_tdm_enable_rbs_events(chan->sockfd, &tdm_api, 100)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to enable RBS/CAS events in device %d:%d fd:%d\n", chan->span_id, chan->chan_id, sockfd); - continue; - } - sangoma_flush_bufs(chan->sockfd, &tdm_api); - sangoma_flush_event_bufs(chan->sockfd, &tdm_api); -#else - /* - * With wanpipe 3.4.4.2 I get failure even though the events are enabled, /var/log/messages said: - * wanpipe4: WARNING: Event type 9 is already pending! - * wanpipe4: Failed to add new fe event 09 ch_map=FFFFFFFF! - * may be we should not send an error until that is fixed in the driver - */ - if (sangoma_tdm_enable_rbs_events(chan->sockfd, &tdm_api, 100)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to enable RBS/CAS events in device %d:%d fd:%d\n", chan->span_id, chan->chan_id, sockfd); - } - /* probably done by the driver but lets write defensive code this time */ - sangoma_tdm_flush_bufs(chan->sockfd, &tdm_api); - sangoma_tdm_write_rbs(chan->sockfd,&tdm_api, wanpipe_swap_bits(cas_bits)); -#endif - } - - if (!ftdm_strlen_zero(name)) { - ftdm_copy_string(chan->chan_name, name, sizeof(chan->chan_name)); - } - - if (!ftdm_strlen_zero(number)) { - ftdm_copy_string(chan->chan_number, number, sizeof(chan->chan_number)); - } - configured++; - ftdm_log_chan(chan, FTDM_LOG_INFO, "Configured wanpipe device FD: %d, DTMF: %s, HWEC: %s, HWEC_IDLE: %s\n", - sockfd, dtmf, hwec_str, hwec_idle); - - } else { - ftdm_log(FTDM_LOG_ERROR, "ftdm_span_add_channel failed for wanpipe span %d channel %d\n", spanno, x); - } - } - - return configured; -} - -/** - * \brief Process configuration variable for a Wanpipe profile - * \param category Wanpipe profile name - * \param var Variable name - * \param val Variable value - * \param lineno Line number from configuration file - * \return Success - */ -static FIO_CONFIGURE_FUNCTION(wanpipe_configure) -{ - int num; - - if (!strcasecmp(category, "defaults")) { - if (!strcasecmp(var, "codec_ms")) { - num = atoi(val); - if (num < 10 || num > 60) { - ftdm_log(FTDM_LOG_WARNING, "invalid codec ms at line %d\n", lineno); - } else { - wp_globals.codec_ms = num; - } - } else if (!strcasecmp(var, "rxqueue_size")) { - num = atoi(val); - if (num < 1 || num > 1000) { - ftdm_log(FTDM_LOG_WARNING, "invalid rx queue size at line %d\n", lineno); - } else { - wp_globals.rxqueue_size = num; - } - } else if (!strcasecmp(var, "txqueue_size")) { - num = atoi(val); - if (num < 1 || num > 1000) { - ftdm_log(FTDM_LOG_WARNING, "invalid tx queue size at line %d\n", lineno); - } else { - wp_globals.txqueue_size = num; - } - } else if (!strcasecmp(var, "wink_ms")) { - num = atoi(val); - if (num < 50 || num > 3000) { - ftdm_log(FTDM_LOG_WARNING, "invalid wink ms at line %d\n", lineno); - } else { - wp_globals.wink_ms = num; - } - } else if (!strcasecmp(var, "flash_ms")) { - num = atoi(val); - if (num < 50 || num > 3000) { - ftdm_log(FTDM_LOG_WARNING, "invalid flash ms at line %d\n", lineno); - } else { - wp_globals.flash_ms = num; - } - } else if (!strcasecmp(var, "ring_on_ms")) { - num = atoi(val); - if (num < 500 || num > 5000) { - ftdm_log(FTDM_LOG_WARNING, "invalid ring_on_ms at line %d (valid range 500 to 5000)\n", lineno); - } else { - wp_globals.ring_on_ms = num; - } - } else if (!strcasecmp(var, "ring_off_ms")) { - num = atoi(val); - if (num < 500 || num > 5000) { - ftdm_log(FTDM_LOG_WARNING, "invalid ring_off_ms at line %d (valid range 500 to 5000)\n", lineno); - } else { - wp_globals.ring_off_ms = num; - } - } - - } - - return FTDM_SUCCESS; -} - -/** - * \brief Initialises an freetdm Wanpipe span from a configuration string - * \param span FreeTDM span - * \param str Configuration string - * \param type FreeTDM span type - * \param name FreeTDM span name - * \param number FreeTDM span number - * \return Success or failure - */ -static FIO_CONFIGURE_SPAN_FUNCTION(wanpipe_configure_span) -{ - int items, i; - char *mydata, *item_list[10]; - char *sp, *ch, *mx; - unsigned char cas_bits = 0; - int channo; - int spanno; - int top = 0; - unsigned configured = 0; - - assert(str != NULL); - - - mydata = ftdm_strdup(str); - assert(mydata != NULL); - - - items = ftdm_separate_string(mydata, ',', item_list, (sizeof(item_list) / sizeof(item_list[0]))); - - for(i = 0; i < items; i++) { - sp = item_list[i]; - if ((ch = strchr(sp, ':'))) { - *ch++ = '\0'; - } - - if (!(sp && ch)) { - ftdm_log(FTDM_LOG_ERROR, "No valid wanpipe span and channel was specified\n"); - continue; - } - - channo = atoi(ch); - spanno = atoi(sp); - - if (channo < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid channel number %d\n", channo); - continue; - } - - if (spanno < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid span number %d\n", channo); - continue; - } - - if ((mx = strchr(ch, '-'))) { - mx++; - top = atoi(mx) + 1; - } else { - top = channo + 1; - } - - - if (top < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid range number %d\n", top); - continue; - } - if (FTDM_CHAN_TYPE_CAS == type && ftdm_config_get_cas_bits(ch, &cas_bits)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to get CAS bits in CAS channel\n"); - continue; - } - configured += wp_open_range(span, spanno, channo, top, type, name, number, cas_bits); - - } - - ftdm_safe_free(mydata); - - return configured; -} - -/** - * \brief Opens Wanpipe channel - * \param ftdmchan Channel to open - * \return Success or failure - */ -static FIO_OPEN_FUNCTION(wanpipe_open) -{ - - wanpipe_tdm_api_t tdm_api; - - memset(&tdm_api,0,sizeof(tdm_api)); - - sangoma_tdm_flush_bufs(ftdmchan->sockfd, &tdm_api); - sangoma_flush_stats(ftdmchan->sockfd, &tdm_api); - memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats)); - - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921 || ftdmchan->type == FTDM_CHAN_TYPE_DQ931) { - ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE; - } else { - ftdmchan->effective_codec = ftdmchan->native_codec; - - sangoma_tdm_set_usr_period(ftdmchan->sockfd, &tdm_api, wp_globals.codec_ms); - - ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL); - ftdmchan->effective_interval = ftdmchan->native_interval = wp_globals.codec_ms; - - /* The packet len will depend on the codec and interval */ - ftdmchan->packet_len = ftdmchan->native_interval * ((ftdmchan->native_codec==FTDM_CODEC_SLIN) ? 16 : 8); - if (wp_globals.txqueue_size > 0) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &wp_globals.txqueue_size); - } - if (wp_globals.rxqueue_size > 0) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &wp_globals.rxqueue_size); - } - } - - return FTDM_SUCCESS; -} - -/** - * \brief Closes Wanpipe channel - * \param ftdmchan Channel to close - * \return Success - */ -static FIO_CLOSE_FUNCTION(wanpipe_close) -{ -#ifdef LIBSANGOMA_VERSION - sangoma_wait_obj_t *waitobj = WP_GET_WAITABLE(ftdmchan); - /* kick any I/O waiters */ - sangoma_wait_obj_signal(waitobj); -#ifdef WP_DEBUG_IO - { - wp_channel_t *wchan = ftdmchan->io_data; - memset(wchan->readers, 0, sizeof(wchan->readers)); - wchan->rindex = 0; - } -#endif -#endif - return FTDM_SUCCESS; -} - -/** - * \brief Executes an FreeTDM command on a Wanpipe channel - * \param ftdmchan Channel to execute command on - * \param command FreeTDM command to execute - * \param obj Object (unused) - * \return Success or failure - */ -static FIO_COMMAND_FUNCTION(wanpipe_command) -{ - wanpipe_tdm_api_t tdm_api; - int err = 0; - - memset(&tdm_api, 0, sizeof(tdm_api)); - - switch(command) { - case FTDM_COMMAND_OFFHOOK: - { - err=sangoma_tdm_txsig_offhook(ftdmchan->sockfd,&tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "OFFHOOK Failed"); - return FTDM_FAIL; - } - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); - } - break; - case FTDM_COMMAND_ONHOOK: - { - err=sangoma_tdm_txsig_onhook(ftdmchan->sockfd,&tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ONHOOK Failed"); - return FTDM_FAIL; - } - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); - } - break; - case FTDM_COMMAND_GENERATE_RING_ON: - { - err=sangoma_tdm_txsig_start(ftdmchan->sockfd,&tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Ring Failed"); - return FTDM_FAIL; - } - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING); - ftdm_set_pflag_locked(ftdmchan, WP_RINGING); - ftdmchan->ring_time = ftdm_current_time_in_ms() + wp_globals.ring_on_ms; - } - break; - case FTDM_COMMAND_GENERATE_RING_OFF: - { - err=sangoma_tdm_txsig_offhook(ftdmchan->sockfd,&tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Ring-off Failed"); - return FTDM_FAIL; - } - ftdm_clear_pflag_locked(ftdmchan, WP_RINGING); - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING); - } - break; - case FTDM_COMMAND_GET_INTERVAL: - { - err=sangoma_tdm_get_usr_period(ftdmchan->sockfd, &tdm_api); - if (err > 0 ) { - FTDM_COMMAND_OBJ_INT = err; - err=0; - } - } - break; - case FTDM_COMMAND_ENABLE_ECHOCANCEL: - { -#ifdef WP_API_FEATURE_EC_CHAN_STAT - err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api); - if (err > 0) { - /* Hardware echo canceller already enabled */ - err = 0; - break; - } -#endif - err=sangoma_tdm_enable_hwec(ftdmchan->sockfd, &tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed"); - return FTDM_FAIL; - } - } - break; - case FTDM_COMMAND_DISABLE_ECHOCANCEL: - { -#ifdef WP_API_FEATURE_EC_CHAN_STAT - err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api); - if (!err) { - /* Hardware echo canceller already disabled */ - break; - } -#endif - err=sangoma_tdm_disable_hwec(ftdmchan->sockfd, &tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed"); - return FTDM_FAIL; - } - } - break; - case FTDM_COMMAND_DISABLE_ECHOTRAIN: { err = 0; } - break; - case FTDM_COMMAND_ENABLE_DTMF_DETECT: - { -#ifdef WP_API_FEATURE_DTMF_EVENTS - err = sangoma_tdm_enable_dtmf_events(ftdmchan->sockfd, &tdm_api); - if (err) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Enabling of Sangoma HW DTMF failed\n"); - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HW DTMF Enable Failed"); - return FTDM_FAIL; - } - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled DTMF events\n"); -#else - return FTDM_NOTIMPL; -#endif - } - break; - case FTDM_COMMAND_DISABLE_DTMF_DETECT: - { -#ifdef WP_API_FEATURE_DTMF_EVENTS - err = sangoma_tdm_disable_dtmf_events(ftdmchan->sockfd, &tdm_api); - if (err) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Disabling of Sangoma HW DTMF failed\n"); - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HW DTMF Disable Failed"); - return FTDM_FAIL; - } - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled DTMF events\n"); -#else - return FTDM_NOTIMPL; -#endif - } - break; - case FTDM_COMMAND_ENABLE_DTMF_REMOVAL: - { -#ifdef WP_API_FEATURE_DTMF_REMOVAL - int return_code = 0; - err = sangoma_hwec_set_hwdtmf_removal(ftdmchan->sockfd, ftdmchan->physical_chan_id, &return_code, 1, 0); - if (return_code) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to Enable HW-DTMF removal\n"); - } -#endif - } - break; - case FTDM_COMMAND_DISABLE_DTMF_REMOVAL: - { -#ifdef WP_API_FEATURE_DTMF_REMOVAL - int return_code = 0; - err = sangoma_hwec_set_hwdtmf_removal(ftdmchan->sockfd, ftdmchan->physical_chan_id, &return_code, 0, 0); - if (return_code) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to Disable HW-DTMF removal\n"); - } -#endif - } - break; - case FTDM_COMMAND_ENABLE_LOOP: - { -#ifdef WP_API_FEATURE_LOOP - err=sangoma_tdm_enable_loop(ftdmchan->sockfd, &tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Loop Enable Failed"); - return FTDM_FAIL; - } -#endif - } - break; - case FTDM_COMMAND_DISABLE_LOOP: - { -#ifdef WP_API_FEATURE_LOOP - err=sangoma_tdm_disable_loop(ftdmchan->sockfd, &tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Loop Disable Failed"); - return FTDM_FAIL; - } -#endif - } - break; - case FTDM_COMMAND_SET_INTERVAL: - { - err=sangoma_tdm_set_usr_period(ftdmchan->sockfd, &tdm_api, FTDM_COMMAND_OBJ_INT); - - ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); - } - break; - case FTDM_COMMAND_SET_CAS_BITS: - { -#ifdef LIBSANGOMA_VERSION - err = sangoma_tdm_write_rbs(ftdmchan->sockfd,&tdm_api, ftdmchan->physical_chan_id, wanpipe_swap_bits(FTDM_COMMAND_OBJ_INT)); -#else - err = sangoma_tdm_write_rbs(ftdmchan->sockfd, &tdm_api, wanpipe_swap_bits(FTDM_COMMAND_OBJ_INT)); -#endif - } - break; - case FTDM_COMMAND_GET_CAS_BITS: - { -#ifdef LIBSANGOMA_VERSION - unsigned char rbsbits; - err = sangoma_tdm_read_rbs(ftdmchan->sockfd, &tdm_api, ftdmchan->physical_chan_id, &rbsbits); - if (!err) { - FTDM_COMMAND_OBJ_INT = wanpipe_swap_bits(rbsbits); - } -#else - /* is sangoma_tdm_read_rbs available here? */ - FTDM_COMMAND_OBJ_INT = ftdmchan->rx_cas_bits; -#endif - } - break; - case FTDM_COMMAND_SET_LINK_STATUS: - { - ftdm_channel_hw_link_status_t status = FTDM_COMMAND_OBJ_INT; - char sangoma_status = status == FTDM_HW_LINK_CONNECTED ? FE_CONNECTED : FE_DISCONNECTED; - err = sangoma_tdm_set_fe_status(ftdmchan->sockfd, &tdm_api, sangoma_status); - } - break; - case FTDM_COMMAND_GET_LINK_STATUS: - { - unsigned char sangoma_status = 0; - err = sangoma_tdm_get_fe_status(ftdmchan->sockfd, &tdm_api, &sangoma_status); - if (!err) { - FTDM_COMMAND_OBJ_INT = sangoma_status == FE_CONNECTED ? FTDM_HW_LINK_CONNECTED : FTDM_HW_LINK_DISCONNECTED; - } - } - break; - case FTDM_COMMAND_FLUSH_BUFFERS: - { - err = sangoma_flush_bufs(ftdmchan->sockfd, &tdm_api); - } - break; - case FTDM_COMMAND_FLUSH_RX_BUFFERS: - { - err = sangoma_flush_rx_bufs(ftdmchan->sockfd, &tdm_api); - } - break; - case FTDM_COMMAND_FLUSH_TX_BUFFERS: - { - err = sangoma_flush_tx_bufs(ftdmchan->sockfd, &tdm_api); - } - break; - case FTDM_COMMAND_FLUSH_IOSTATS: - { - err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api); - memset(&ftdmchan->iostats, 0, sizeof(ftdmchan->iostats)); - } - break; - case FTDM_COMMAND_SET_RX_QUEUE_SIZE: - { - uint32_t queue_size = FTDM_COMMAND_OBJ_INT; - err = sangoma_set_rx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size); - } - break; - case FTDM_COMMAND_SET_TX_QUEUE_SIZE: - { - uint32_t queue_size = FTDM_COMMAND_OBJ_INT; - err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size); - } - break; - case FTDM_COMMAND_SET_POLARITY: - { - ftdm_polarity_t polarity = FTDM_COMMAND_OBJ_INT; - err = sangoma_tdm_set_polarity(ftdmchan->sockfd, &tdm_api, polarity); - if (!err) { - ftdmchan->polarity = polarity; - } - } - break; - default: - err = FTDM_NOTIMPL; - break; - }; - - if (err) { - int myerrno = errno; - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to execute command %d: %s\n", command, strerror(myerrno)); - errno = myerrno; - return err; - } - - return FTDM_SUCCESS; -} - -static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *tx_stats) -{ - ftdmchan->iostats.tx.errors = tx_stats->wp_api_tx_hdr_errors; - ftdmchan->iostats.tx.queue_size = tx_stats->wp_api_tx_hdr_max_queue_length; - ftdmchan->iostats.tx.queue_len = tx_stats->wp_api_tx_hdr_number_of_frames_in_queue; - - /* we don't test for 80% full in tx since is typically full for voice channels, should we test tx 80% full for D-channels? */ - if (ftdmchan->iostats.tx.queue_len >= ftdmchan->iostats.tx.queue_size) { - ftdm_set_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL); - } else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){ - ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL); - } - - if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_tx_idle_packets) { - ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets; - } - - if (!ftdmchan->iostats.tx.packets) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet write stats: Tx queue len: %d, Tx queue size: %d, Tx idle: %"FTDM_UINT64_FMT"\n", - ftdmchan->iostats.tx.queue_len, - ftdmchan->iostats.tx.queue_size, - ftdmchan->iostats.tx.idle_packets); - } - - ftdmchan->iostats.tx.packets++; -} - -static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats) -{ - ftdmchan->iostats.rx.errors = rx_stats->wp_api_rx_hdr_errors; - ftdmchan->iostats.rx.queue_size = rx_stats->wp_api_rx_hdr_max_queue_length; - ftdmchan->iostats.rx.queue_len = rx_stats->wp_api_rx_hdr_number_of_frames_in_queue; - - if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_ABORT_ERROR_BIT))) { - ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT); - } else { - ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT); - } - - if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_DMA_ERROR_BIT))) { - ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA); - } else { - ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA); - } - - if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FIFO_ERROR_BIT))) { - ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO); - } else { - ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO); - } - - if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_CRC_ERROR_BIT))) { - ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC); - } else { - ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC); - } - - if ((rx_stats->wp_api_rx_hdr_error_map & (1 << WP_FRAME_ERROR_BIT))) { - ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME); - } else { - ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME); - } - - if (ftdmchan->iostats.rx.queue_len >= (0.8 * ftdmchan->iostats.rx.queue_size)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length exceeded 80%% threshold (%d/%d)\n", - ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size); - ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES); - } else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length reduced 80%% threshold (%d/%d)\n", - ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size); - ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES); - } - - if (ftdmchan->iostats.rx.queue_len >= ftdmchan->iostats.rx.queue_size) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue Full (%d/%d)\n", - ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size); - ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL); - } else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue no longer full (%d/%d)\n", - ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size); - ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL); - } - - if (!ftdmchan->iostats.rx.packets) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "First packet read stats: Rx queue len: %d, Rx queue size: %d\n", - ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size); - } - - ftdmchan->iostats.rx.packets++; -} - -/** - * \brief Reads data from a Wanpipe channel - * \param ftdmchan Channel to read from - * \param data Data buffer - * \param datalen Size of data buffer - * \return Success, failure or timeout - */ - - -static FIO_READ_FUNCTION(wanpipe_read) -{ - int rx_len = 0; - int rq_len = (int)*datalen; - wp_tdm_api_rx_hdr_t hdrframe; - - -#ifdef WP_DEBUG_IO - wp_channel_t *wchan = ftdmchan->io_data; - ftdm_time_t time_diff = 0; - pid_t previous_thread = 1; - pid_t current_thread = 0; - int previous_thread_index = 0; - - previous_thread_index = wchan->rindex == 0 ? (ftdm_array_len(wchan->readers) - 1) : wchan->rindex - 1; - previous_thread = wchan->readers[previous_thread_index]; - current_thread = syscall(SYS_gettid); - if (current_thread && current_thread != wchan->readers[wchan->rindex]) { - if (!wchan->readers[wchan->rindex]) { - wchan->readers[wchan->rindex] = current_thread; - /* first read */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Initial reader thread is %d\n", current_thread); - previous_thread = current_thread; - } else { - previous_thread = wchan->readers[wchan->rindex]; - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Changed reader thread from %d to %d (rindex = %d)\n", - previous_thread, current_thread, wchan->rindex); - if (wchan->rindex == (ftdm_array_len(wchan->readers) - 1)) { - wchan->rindex = 0; - } else { - wchan->rindex++; - } - wchan->readers[wchan->rindex] = current_thread; - } - } - ftdm_time_t curr = ftdm_current_time_in_ms(); - if (wchan->last_read) { - time_diff = curr - wchan->last_read; - } -#endif - - memset(&hdrframe, 0, sizeof(hdrframe)); - rx_len = sangoma_readmsg_tdm(ftdmchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (int)*datalen, 0); - *datalen = 0; - - if (rx_len == 0) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Read 0 bytes\n"); - return FTDM_TIMEOUT; - } - - if (rx_len < 0) { -#ifdef WP_DEBUG_IO - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read %d bytes from sangoma device: %s (%d) " - "(read time diff = %llums, prev thread = %d, curr thread = %d)\n", rq_len, strerror(errno), rx_len, - time_diff, previous_thread, current_thread); -#else - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read %d bytes from sangoma device: %s (%d)\n", rq_len, strerror(errno), rx_len); -#endif - return FTDM_FAIL; - } - *datalen = rx_len; - - if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) { - wanpipe_read_stats(ftdmchan, &hdrframe); - } - - if ((ftdmchan->type == FTDM_CHAN_TYPE_B) && (ftdmchan->span->trunk_type == FTDM_TRUNK_GSM)) { - wp_swap16(data, *datalen); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Writes data to a Wanpipe channel - * \param ftdmchan Channel to write to - * \param data Data buffer - * \param datalen Size of data buffer - * \return Success or failure - */ -static FIO_WRITE_FUNCTION(wanpipe_write) -{ - int bsent = 0; - int err = 0; - wp_tdm_api_tx_hdr_t hdrframe; - - if ((ftdmchan->type == FTDM_CHAN_TYPE_B) && (ftdmchan->span->trunk_type == FTDM_TRUNK_GSM)) { - wp_swap16(data, *datalen); - } - - /* Do we even need the headerframe here? on windows, we don't even pass it to the driver */ - memset(&hdrframe, 0, sizeof(hdrframe)); - if (*datalen == 0) { - return FTDM_SUCCESS; - } - - if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS) && !ftdmchan->iostats.tx.packets) { - wanpipe_tdm_api_t tdm_api; - memset(&tdm_api, 0, sizeof(tdm_api)); - /* if this is the first write ever, flush the tx first to have clean stats */ - err = sangoma_flush_tx_bufs(ftdmchan->sockfd, &tdm_api); - if (err) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to flush on first write\n"); - } - } - - bsent = sangoma_writemsg_tdm(ftdmchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (unsigned short)(*datalen),0); - - /* should we be checking if bsent == *datalen here? */ - if (bsent > 0) { - *datalen = bsent; - if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) { - /* BRI cards do not support TX queues for now */ - if(!FTDM_SPAN_IS_BRI(ftdmchan->span)) { - wanpipe_write_stats(ftdmchan, &hdrframe); - } - } - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -/** - * \brief Waits for an event on a Wanpipe channel - * \param ftdmchan Channel to open - * \param flags Type of event to wait for - * \param to Time to wait (in ms) - * \return Success, failure or timeout - */ - -static FIO_WAIT_FUNCTION(wanpipe_wait) -{ - int32_t inflags = 0; - int result; - - if (*flags & FTDM_READ) { - inflags |= POLLIN; - } - - if (*flags & FTDM_WRITE) { - inflags |= POLLOUT; - } - - if (*flags & FTDM_EVENTS) { - inflags |= POLLPRI; - } - - result = tdmv_api_wait_socket(ftdmchan, to, &inflags); - - *flags = FTDM_NO_FLAGS; - - if (result < 0){ - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Poll failed"); - return FTDM_FAIL; - } - - if (result == 0) { - return FTDM_TIMEOUT; - } - - if (inflags & POLLIN) { - *flags |= FTDM_READ; - } - - if (inflags & POLLOUT) { - *flags |= FTDM_WRITE; - } - - if (inflags & POLLPRI) { - *flags |= FTDM_EVENTS; - } - - return FTDM_SUCCESS; -} - -/** - * \brief Checks for events on a Wanpipe span - * \param span Span to check for events - * \param ms Time to wait for event - * \return Success if event is waiting or failure if not - */ -FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event) -{ -#ifdef LIBSANGOMA_VERSION - sangoma_status_t sangstatus; - sangoma_wait_obj_t *pfds[FTDM_MAX_CHANNELS_SPAN] = { 0 }; - uint32_t inflags[FTDM_MAX_CHANNELS_SPAN]; - uint32_t outflags[FTDM_MAX_CHANNELS_SPAN]; -#else - struct pollfd pfds[FTDM_MAX_CHANNELS_SPAN]; -#endif - uint32_t i, j = 0, k = 0, l = 0; - int r; - - for(i = 1; i <= span->chan_count; i++) { - ftdm_channel_t *ftdmchan = span->channels[i]; - uint32_t chan_events = 0; - - /* translate events from ftdm to libsnagoma. if the user don't specify which events to poll the - * channel for, we just use SANG_WAIT_OBJ_HAS_EVENTS */ - if (poll_events) { - if (poll_events[j] & FTDM_READ) { - chan_events = SANG_WAIT_OBJ_HAS_INPUT; - } - if (poll_events[j] & FTDM_WRITE) { - chan_events |= SANG_WAIT_OBJ_HAS_OUTPUT; - } - if (poll_events[j] & FTDM_EVENTS) { - chan_events |= SANG_WAIT_OBJ_HAS_EVENTS; - } - } else { - chan_events = SANG_WAIT_OBJ_HAS_EVENTS; - } - -#ifdef LIBSANGOMA_VERSION - if (!ftdmchan->io_data) { - continue; /* should never happen but happens when shutting down */ - } - pfds[j] = WP_GET_WAITABLE(ftdmchan); - inflags[j] = chan_events; -#else - memset(&pfds[j], 0, sizeof(pfds[j])); - pfds[j].fd = span->channels[i]->sockfd; - pfds[j].events = chan_events; -#endif - - /* The driver probably should be able to do this wink/flash/ringing by itself this is sort of a hack to make it work! */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK) || ftdm_test_flag(ftdmchan, FTDM_CHANNEL_FLASH)) { - l = 5; - } - - j++; - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING)) { - l = 5; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING) && ftdm_current_time_in_ms() >= ftdmchan->ring_time) { - wanpipe_tdm_api_t tdm_api; - int err; - memset(&tdm_api, 0, sizeof(tdm_api)); - if (ftdm_test_pflag(ftdmchan, WP_RINGING)) { - err = sangoma_tdm_txsig_offhook(ftdmchan->sockfd,&tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Ring-off Failed"); - ftdm_log(FTDM_LOG_ERROR, "sangoma_tdm_txsig_offhook failed\n"); - return FTDM_FAIL; - } - ftdm_clear_pflag_locked(ftdmchan, WP_RINGING); - ftdmchan->ring_time = ftdm_current_time_in_ms() + wp_globals.ring_off_ms; - } else { - err=sangoma_tdm_txsig_start(ftdmchan->sockfd,&tdm_api); - if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Ring Failed"); - ftdm_log(FTDM_LOG_ERROR, "sangoma_tdm_txsig_start failed\n"); - return FTDM_FAIL; - } - ftdm_set_pflag_locked(ftdmchan, WP_RINGING); - ftdmchan->ring_time = ftdm_current_time_in_ms() + wp_globals.ring_on_ms; - } - } - } - - if (l) { - ms = l; - } -#ifdef LIBSANGOMA_VERSION - sangstatus = sangoma_waitfor_many(pfds, inflags, outflags, j, ms); - if (SANG_STATUS_APIPOLL_TIMEOUT == sangstatus) { - r = 0; - } else if (SANG_STATUS_SUCCESS == sangstatus) { - r = 1; /* hopefully we never need how many changed -_- */ - } else { - ftdm_log(FTDM_LOG_ERROR, "sangoma_waitfor_many failed: %d, %s\n", sangstatus, strerror(errno)); - r = -1; - } -#else - r = poll(pfds, j, ms); -#endif - - if (r == 0) { - return l ? FTDM_SUCCESS : FTDM_TIMEOUT; - } else if (r < 0) { - snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); - return FTDM_FAIL; - } - - for(i = 1; i <= span->chan_count; i++) { - ftdm_channel_t *ftdmchan = span->channels[i]; - -#ifdef LIBSANGOMA_VERSION - if (outflags[i-1] & POLLPRI) { -#else - if (pfds[i-1].revents & POLLPRI) { -#endif - ftdm_set_io_flag(ftdmchan, FTDM_CHANNEL_IO_EVENT); - ftdmchan->last_event_time = ftdm_current_time_in_ms(); - k++; - } -#ifdef LIBSANGOMA_VERSION - if (outflags[i-1] & POLLIN) { -#else - if (pfds[i-1].revents & POLLIN) { -#endif - ftdm_set_io_flag(ftdmchan, FTDM_CHANNEL_IO_READ); - } -#ifdef LIBSANGOMA_VERSION - if (outflags[i-1] & POLLOUT) { -#else - if (pfds[i-1].revents & POLLOUT) { -#endif - ftdm_set_io_flag(ftdmchan, FTDM_CHANNEL_IO_WRITE); - } - } - /* when k is 0 it might be that an async wanpipe device signal was delivered */ - return FTDM_SUCCESS; -} - -/** - * \brief Gets alarms from a Wanpipe Channel - * \param ftdmchan Channel to get alarms from - * \return Success or failure - */ -static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) -{ - wanpipe_tdm_api_t tdm_api; - unsigned int alarms = 0; - int err; - - memset(&tdm_api, 0, sizeof(tdm_api)); - -#ifdef LIBSANGOMA_VERSION - if ((err = sangoma_tdm_get_fe_alarms(ftdmchan->sockfd, &tdm_api, &alarms))) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ioctl failed (%s)", strerror(errno)); - snprintf(ftdmchan->span->last_error, sizeof(ftdmchan->span->last_error), "ioctl failed (%s)", strerror(errno)); - return FTDM_FAIL; - } -#else - if ((err = sangoma_tdm_get_fe_alarms(ftdmchan->sockfd, &tdm_api)) < 0){ - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ioctl failed (%s)", strerror(errno)); - snprintf(ftdmchan->span->last_error, sizeof(ftdmchan->span->last_error), "ioctl failed (%s)", strerror(errno)); - return FTDM_FAIL; - } - alarms = tdm_api.wp_tdm_cmd.fe_alarms; -#endif -#ifdef WIN32 - /* Temporary fix: in the current trunk of libsangoma, for BRI, - WAN_TE_BIT_ALARM_RED bit is set if the card is in disconnected state, but this has - not been ported to Windows-libsangoma yet */ - if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { - if (alarms) { - ftdmchan->alarm_flags |= FTDM_ALARM_RED; - alarms = 0; - } - } -#endif - - ftdmchan->alarm_flags = FTDM_ALARM_NONE; - - if (alarms & WAN_TE_BIT_ALARM_RED) { - ftdmchan->alarm_flags |= FTDM_ALARM_RED; - alarms &= ~WAN_TE_BIT_ALARM_RED; - } - - - if (alarms & WAN_TE_BIT_ALARM_AIS) { - ftdmchan->alarm_flags |= FTDM_ALARM_BLUE; - alarms &= ~WAN_TE_BIT_ALARM_AIS; - } - - if (alarms & WAN_TE_BIT_ALARM_RAI) { - ftdmchan->alarm_flags |= FTDM_ALARM_YELLOW; - alarms &= ~WAN_TE_BIT_ALARM_RAI; - } - - if (!ftdmchan->alarm_flags) { - /* there is a bug in wanpipe where alarms were not properly set when they should be - * on at application startup, until that is fixed we check the link status here too */ - ftdm_channel_hw_link_status_t sangoma_status = 0; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status); - ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? FTDM_ALARM_RED : FTDM_ALARM_NONE; - } - - if (alarms) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Unmapped wanpipe alarms: %d\n", alarms); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Process an event in a channel and set it's OOB event id. The channel must be locked. - * \param fchan Channel in which event occured - * \param event_id Pointer where we save the OOB event id - * \param tdm_api Wanpipe tdm struct that contain the event - * \return FTDM_SUCCESS or FTDM_FAIL - */ -static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fchan, ftdm_oob_event_t *event_id, wanpipe_tdm_api_t *tdm_api) -{ - ftdm_status_t status = FTDM_SUCCESS; - - switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type) { - case WP_API_EVENT_LINK_STATUS: - { - if (FTDM_IS_DIGITAL_CHANNEL(fchan)) { - switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) { - case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: - /* *event_id = FTDM_OOB_ALARM_CLEAR; */ - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link connected event\n"); - break; - default: - /* *event_id = FTDM_OOB_ALARM_TRAP; */ - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link disconnected event\n"); - break; - } - /* The WP_API_EVENT_ALARM event should be used to clear alarms */ - *event_id = FTDM_OOB_NOOP; - } else { - switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) { - case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: - /* *event_id = FTDM_OOB_ALARM_CLEAR; */ - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link connected event as alarm clear\n"); - *event_id = FTDM_OOB_ALARM_CLEAR; - fchan->alarm_flags = FTDM_ALARM_NONE; - break; - default: - /* *event_id = FTDM_OOB_ALARM_TRAP; */ - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link disconnected event as alarm trap\n"); - *event_id = FTDM_OOB_ALARM_TRAP; - fchan->alarm_flags = FTDM_ALARM_RED; - break; - } - } - } - break; - - case WP_API_EVENT_RXHOOK: - { - if (fchan->type == FTDM_CHAN_TYPE_FXS) { - *event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_hook_state - & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK; - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got wanpipe %s\n", ftdm_oob_event2str(*event_id)); - if (*event_id == FTDM_OOB_OFFHOOK) { - if (ftdm_test_flag(fchan, FTDM_CHANNEL_FLASH)) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_FLASH); - ftdm_clear_flag(fchan, FTDM_CHANNEL_WINK); - *event_id = FTDM_OOB_FLASH; - goto done; - } else { - ftdm_set_flag(fchan, FTDM_CHANNEL_WINK); - } - } else { - if (ftdm_test_flag(fchan, FTDM_CHANNEL_WINK)) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_WINK); - ftdm_clear_flag(fchan, FTDM_CHANNEL_FLASH); - *event_id = FTDM_OOB_WINK; - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Wink flag is set, delivering %s\n", - ftdm_oob_event2str(*event_id)); - goto done; - } else { - ftdm_set_flag(fchan, FTDM_CHANNEL_FLASH); - } - } - status = FTDM_BREAK; - } else { - ftdm_status_t status; - status = sangoma_tdm_txsig_onhook(fchan->sockfd, tdm_api); - if (status) { - snprintf(fchan->last_error, sizeof(fchan->last_error), "ONHOOK Failed"); - return FTDM_FAIL; - } - *event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_ONHOOK : FTDM_OOB_NOOP; - } - } - break; - case WP_API_EVENT_RING_DETECT: - { - *event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP; - } - break; - /* - disabled this ones when configuring, we don't need them, do we? - case WP_API_EVENT_RING_TRIP_DETECT: - { - *event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK; - } - break; - */ - case WP_API_EVENT_RBS: - { - *event_id = FTDM_OOB_CAS_BITS_CHANGE; - fchan->rx_cas_bits = wanpipe_swap_bits(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits); - } - break; - case WP_API_EVENT_DTMF: - { - char tmp_dtmf[2] = { tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 }; - *event_id = FTDM_OOB_NOOP; - - if (tmp_dtmf[0] == 'f') { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c, fax tones will be passed through!\n", tmp_dtmf[0]); - break; - } - - if (tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) { - ftdm_set_flag(fchan, FTDM_CHANNEL_MUTE); - if (fchan->dtmfdetect.duration_ms) { - fchan->dtmfdetect.start_time = ftdm_current_time_in_ms(); - } else if (fchan->dtmfdetect.trigger_on_start) { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]); - ftdm_channel_queue_dtmf(fchan, tmp_dtmf); - } - } - - if (tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_MUTE); - if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) { - if (fchan->dtmfdetect.duration_ms) { - ftdm_time_t diff = ftdm_current_time_in_ms() - fchan->dtmfdetect.start_time; - if (diff > fchan->dtmfdetect.duration_ms) { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c (duration:%"FTDM_TIME_FMT" min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms); - ftdm_channel_queue_dtmf(fchan, tmp_dtmf); - } else { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c (duration:%"FTDM_TIME_FMT" min:%d)\n", tmp_dtmf[0], diff, fchan->dtmfdetect.duration_ms); - } - } else if (!fchan->dtmfdetect.trigger_on_start) { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]); - ftdm_channel_queue_dtmf(fchan, tmp_dtmf); - } - } - } - } - break; - case WP_API_EVENT_ALARM: - { - if (tdm_api->wp_tdm_cmd.event.wp_api_event_alarm) { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got Wanpipe alarms %d\n", tdm_api->wp_tdm_cmd.event.wp_api_event_alarm); - *event_id = FTDM_OOB_ALARM_TRAP; - } else { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Wanpipe alarms cleared\n"); - *event_id = FTDM_OOB_ALARM_CLEAR; - } - } - break; - case WP_API_EVENT_POLARITY_REVERSE: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Got polarity reverse\n"); - *event_id = FTDM_OOB_POLARITY_REVERSE; - } - break; - default: - { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type); - *event_id = FTDM_OOB_INVALID; - } - break; - } -done: - return status; -} - -/** - * \brief Retrieves an event from a wanpipe channel - * \param channel Channel to retrieve event from - * \param event FreeTDM event to return - * \return Success or failure - */ -FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event) -{ - ftdm_status_t status; - ftdm_oob_event_t event_id; - wanpipe_tdm_api_t tdm_api; - ftdm_span_t *span = ftdmchan->span; - - memset(&tdm_api, 0, sizeof(tdm_api)); - status = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api); - if (status != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to read event from channel: %s\n", strerror(errno)); - return FTDM_FAIL; - } - - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); - status = wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api); - if (status == FTDM_BREAK) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Ignoring event for now\n"); - } else if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process event from channel\n"); - return FTDM_FAIL; - } else { - ftdmchan->last_event_time = 0; - } - - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = ftdmchan; - *event = &span->event_header; - return FTDM_SUCCESS; -} - -/** - * \brief Retrieves an event from a wanpipe span - * \param span Span to retrieve event from - * \param event FreeTDM event to return - * \return Success or failure - */ -FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) -{ - uint32_t i,err; - ftdm_oob_event_t event_id; - for(i = 1; i <= span->chan_count; i++) { - /* as a hack for wink/flash detection, wanpipe_poll_event overrides the timeout parameter - * to force the user to call this function each 5ms or so to detect the timeout of our wink/flash */ - if (span->channels[i]->last_event_time && !ftdm_test_io_flag(span->channels[i], FTDM_CHANNEL_IO_EVENT)) { - ftdm_time_t diff = ftdm_current_time_in_ms() - span->channels[i]->last_event_time; - /* XX printf("%u %u %u\n", diff, (unsigned)ftdm_current_time_in_ms(), (unsigned)span->channels[i]->last_event_time); */ - if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_WINK)) { - if (diff > wp_globals.wink_ms) { - ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_WINK); - ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_FLASH); - ftdm_set_flag_locked(span->channels[i], FTDM_CHANNEL_OFFHOOK); - event_id = FTDM_OOB_OFFHOOK; - ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %"FTDM_TIME_FMT" ms, delivering %s now\n", diff, ftdm_oob_event2str(event_id)); - goto event; - } - } - - if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_FLASH)) { - if (diff > wp_globals.flash_ms) { - ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_FLASH); - ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_WINK); - ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_OFFHOOK); - event_id = FTDM_OOB_ONHOOK; - - if (span->channels[i]->type == FTDM_CHAN_TYPE_FXO) { - ftdm_channel_t *ftdmchan = span->channels[i]; - wanpipe_tdm_api_t tdm_api; - memset(&tdm_api, 0, sizeof(tdm_api)); - - sangoma_tdm_txsig_onhook(ftdmchan->sockfd,&tdm_api); - } - ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %"FTDM_TIME_FMT" ms, delivering %s now\n", diff, ftdm_oob_event2str(event_id)); - goto event; - } - } - } - if (ftdm_test_io_flag(span->channels[i], FTDM_CHANNEL_IO_EVENT)) { - ftdm_status_t status; - wanpipe_tdm_api_t tdm_api; - ftdm_channel_t *ftdmchan = span->channels[i]; - memset(&tdm_api, 0, sizeof(tdm_api)); - ftdm_clear_io_flag(span->channels[i], FTDM_CHANNEL_IO_EVENT); - - err = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api); - if (err != FTDM_SUCCESS) { - ftdm_log_chan(span->channels[i], FTDM_LOG_ERROR, "read wanpipe event got error: %s\n", strerror(errno)); - return FTDM_FAIL; - } - ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); - - ftdm_channel_lock(ftdmchan); - status = wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api); - ftdm_channel_unlock(ftdmchan); - - if (status == FTDM_BREAK) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring event for now\n"); - continue; - } else if (status != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process event from channel\n"); - return FTDM_FAIL; - } - - event: - - span->channels[i]->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = span->channels[i]; - *event = &span->event_header; - return FTDM_SUCCESS; - } - } - return FTDM_BREAK; -} - -/** - * \brief Destroys a Wanpipe Channel - * \param ftdmchan Channel to destroy - * \return Success - */ -static FIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy) -{ -#ifdef LIBSANGOMA_VERSION - if (ftdmchan->io_data) { - sangoma_wait_obj_t *sangoma_wait_obj = WP_GET_WAITABLE(ftdmchan); - sangoma_wait_obj_delete(&sangoma_wait_obj); - ftdm_safe_free(ftdmchan->io_data); - ftdmchan->io_data = NULL; - } -#endif - - if (ftdmchan->sockfd != FTDM_INVALID_SOCKET) { - /* enable HW DTMF. As odd as it seems. Why enable when the channel is being destroyed and won't be used anymore? - * because that way we can transfer the DTMF state back to the driver, if we're being restarted we will set again - * the FEATURE_DTMF flag and use HW DTMF, if we don't enable here, then on module restart we won't see - * HW DTMF available and will use software */ - if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) { - wanpipe_tdm_api_t tdm_api; - int err; - memset(&tdm_api, 0, sizeof(tdm_api)); - err = sangoma_tdm_enable_dtmf_events(ftdmchan->sockfd, &tdm_api); - if (err) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed enabling Sangoma HW DTMF failed on channel destroy\n"); - } - } - sangoma_close(&ftdmchan->sockfd); - } - - return FTDM_SUCCESS; -} - -/** - * \brief Loads wanpipe IO module - * \param fio FreeTDM IO interface - * \return Success - */ -static FIO_IO_LOAD_FUNCTION(wanpipe_init) -{ - ftdm_assert(fio != NULL, "fio should not be null\n"); - - memset(&wanpipe_interface, 0, sizeof(wanpipe_interface)); - - wp_globals.codec_ms = 20; - wp_globals.wink_ms = 150; - wp_globals.flash_ms = 750; - wp_globals.ring_on_ms = 2000; - wp_globals.ring_off_ms = 4000; - /* 0 for queue size will leave driver defaults */ - wp_globals.txqueue_size = 0; - wp_globals.rxqueue_size = 0; - wanpipe_interface.name = "wanpipe"; - wanpipe_interface.configure_span = wanpipe_configure_span; - wanpipe_interface.configure = wanpipe_configure; - wanpipe_interface.open = wanpipe_open; - wanpipe_interface.close = wanpipe_close; - wanpipe_interface.command = wanpipe_command; - wanpipe_interface.wait = wanpipe_wait; - wanpipe_interface.read = wanpipe_read; - wanpipe_interface.write = wanpipe_write; - wanpipe_interface.poll_event = wanpipe_poll_event; - wanpipe_interface.next_event = wanpipe_span_next_event; - wanpipe_interface.channel_next_event = wanpipe_channel_next_event; - wanpipe_interface.channel_destroy = wanpipe_channel_destroy; - wanpipe_interface.get_alarms = wanpipe_get_alarms; - *fio = &wanpipe_interface; - - return FTDM_SUCCESS; -} - -/** - * \brief Unloads wanpipe IO module - * \return Success - */ -static FIO_IO_UNLOAD_FUNCTION(wanpipe_destroy) -{ - memset(&wanpipe_interface, 0, sizeof(wanpipe_interface)); - return FTDM_SUCCESS; -} - -/** - * \brief FreeTDM wanpipe IO module definition - */ -EX_DECLARE_DATA ftdm_module_t ftdm_module = { - "wanpipe", - wanpipe_init, - wanpipe_destroy, -}; - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet - */ diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c deleted file mode 100644 index 369a05d1d0..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ /dev/null @@ -1,1571 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * W McRoberts - * Puskás Zsolt - * - */ - -#include "private/ftdm_core.h" -#include "ftmod_zt.h" - -/* used by dahdi to indicate there is no data available, but events to read */ -#ifndef ELAST -#define ELAST 500 -#endif - -/** - * \brief Zaptel globals - */ -static struct { - uint32_t codec_ms; - uint32_t wink_ms; - uint32_t flash_ms; - uint32_t eclevel; - uint32_t etlevel; - float rxgain; - float txgain; -} zt_globals; - -#if defined(__FreeBSD__) -typedef unsigned long ioctlcmd; -#else -typedef int ioctlcmd; -#endif - -/** - * \brief General IOCTL codes - */ -struct ioctl_codes { - ioctlcmd GET_BLOCKSIZE; - ioctlcmd SET_BLOCKSIZE; - ioctlcmd FLUSH; - ioctlcmd SYNC; - ioctlcmd GET_PARAMS; - ioctlcmd SET_PARAMS; - ioctlcmd HOOK; - ioctlcmd GETEVENT; - ioctlcmd IOMUX; - ioctlcmd SPANSTAT; - ioctlcmd MAINT; - ioctlcmd GETCONF; - ioctlcmd SETCONF; - ioctlcmd CONFLINK; - ioctlcmd CONFDIAG; - ioctlcmd GETGAINS; - ioctlcmd SETGAINS; - ioctlcmd SPANCONFIG; - ioctlcmd CHANCONFIG; - ioctlcmd SET_BUFINFO; - ioctlcmd GET_BUFINFO; - ioctlcmd AUDIOMODE; - ioctlcmd ECHOCANCEL; - ioctlcmd HDLCRAWMODE; - ioctlcmd HDLCFCSMODE; - ioctlcmd SPECIFY; - ioctlcmd SETLAW; - ioctlcmd SETLINEAR; - ioctlcmd GETCONFMUTE; - ioctlcmd ECHOTRAIN; - ioctlcmd SETTXBITS; - ioctlcmd GETRXBITS; - ioctlcmd SETPOLARITY; - ioctlcmd TONEDETECT; -}; - -/** - * \brief Zaptel IOCTL codes - */ -static struct ioctl_codes zt_ioctl_codes = { - .GET_BLOCKSIZE = ZT_GET_BLOCKSIZE, - .SET_BLOCKSIZE = ZT_SET_BLOCKSIZE, - .FLUSH = ZT_FLUSH, - .SYNC = ZT_SYNC, - .GET_PARAMS = ZT_GET_PARAMS, - .SET_PARAMS = ZT_SET_PARAMS, - .HOOK = ZT_HOOK, - .GETEVENT = ZT_GETEVENT, - .IOMUX = ZT_IOMUX, - .SPANSTAT = ZT_SPANSTAT, - .MAINT = ZT_MAINT, - .GETCONF = ZT_GETCONF, - .SETCONF = ZT_SETCONF, - .CONFLINK = ZT_CONFLINK, - .CONFDIAG = ZT_CONFDIAG, - .GETGAINS = ZT_GETGAINS, - .SETGAINS = ZT_SETGAINS, - .SPANCONFIG = ZT_SPANCONFIG, - .CHANCONFIG = ZT_CHANCONFIG, - .SET_BUFINFO = ZT_SET_BUFINFO, - .GET_BUFINFO = ZT_GET_BUFINFO, - .AUDIOMODE = ZT_AUDIOMODE, - .ECHOCANCEL = ZT_ECHOCANCEL, - .HDLCRAWMODE = ZT_HDLCRAWMODE, - .HDLCFCSMODE = ZT_HDLCFCSMODE, - .SPECIFY = ZT_SPECIFY, - .SETLAW = ZT_SETLAW, - .SETLINEAR = ZT_SETLINEAR, - .GETCONFMUTE = ZT_GETCONFMUTE, - .ECHOTRAIN = ZT_ECHOTRAIN, - .SETTXBITS = ZT_SETTXBITS, - .GETRXBITS = ZT_GETRXBITS, - .TONEDETECT = ZT_TONEDETECT, -}; - -/** - * \brief Dahdi IOCTL codes - */ -static struct ioctl_codes dahdi_ioctl_codes = { - .GET_BLOCKSIZE = DAHDI_GET_BLOCKSIZE, - .SET_BLOCKSIZE = DAHDI_SET_BLOCKSIZE, - .FLUSH = DAHDI_FLUSH, - .SYNC = DAHDI_SYNC, - .GET_PARAMS = DAHDI_GET_PARAMS, - .SET_PARAMS = DAHDI_SET_PARAMS, - .HOOK = DAHDI_HOOK, - .GETEVENT = DAHDI_GETEVENT, - .IOMUX = DAHDI_IOMUX, - .SPANSTAT = DAHDI_SPANSTAT, - .MAINT = DAHDI_MAINT, - .GETCONF = DAHDI_GETCONF, - .SETCONF = DAHDI_SETCONF, - .CONFLINK = DAHDI_CONFLINK, - .CONFDIAG = DAHDI_CONFDIAG, - .GETGAINS = DAHDI_GETGAINS, - .SETGAINS = DAHDI_SETGAINS, - .SPANCONFIG = DAHDI_SPANCONFIG, - .CHANCONFIG = DAHDI_CHANCONFIG, - .SET_BUFINFO = DAHDI_SET_BUFINFO, - .GET_BUFINFO = DAHDI_GET_BUFINFO, - .AUDIOMODE = DAHDI_AUDIOMODE, - .ECHOCANCEL = DAHDI_ECHOCANCEL, - .HDLCRAWMODE = DAHDI_HDLCRAWMODE, - .HDLCFCSMODE = DAHDI_HDLCFCSMODE, - .SPECIFY = DAHDI_SPECIFY, - .SETLAW = DAHDI_SETLAW, - .SETLINEAR = DAHDI_SETLINEAR, - .GETCONFMUTE = DAHDI_GETCONFMUTE, - .ECHOTRAIN = DAHDI_ECHOTRAIN, - .SETTXBITS = DAHDI_SETTXBITS, - .GETRXBITS = DAHDI_GETRXBITS, - .SETPOLARITY = DAHDI_SETPOLARITY, - .TONEDETECT = DAHDI_TONEDETECT, -}; - -#define ZT_INVALID_SOCKET -1 -static struct ioctl_codes codes; -static const char *ctlpath = NULL; -static const char *chanpath = NULL; - -static const char dahdi_ctlpath[] = "/dev/dahdi/ctl"; -static const char dahdi_chanpath[] = "/dev/dahdi/channel"; - -static const char zt_ctlpath[] = "/dev/zap/ctl"; -static const char zt_chanpath[] = "/dev/zap/channel"; - -static ftdm_socket_t CONTROL_FD = ZT_INVALID_SOCKET; - -FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event); -FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event); -FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event); - -/** - * \brief Initialises codec, and rx/tx gains - * \param g Structure for gains to be initialised - * \param rxgain RX gain value - * \param txgain TX gain value - * \param codec Codec - */ -static void zt_build_gains(struct zt_gains *g, float rxgain, float txgain, int codec) -{ - int j; - int k; - float linear_rxgain = pow(10.0, rxgain / 20.0); - float linear_txgain = pow(10.0, txgain / 20.0); - - switch (codec) { - case FTDM_CODEC_ALAW: - for (j = 0; j < (sizeof(g->receive_gain) / sizeof(g->receive_gain[0])); j++) { - if (rxgain) { - k = (int) (((float) alaw_to_linear(j)) * linear_rxgain); - if (k > 32767) k = 32767; - if (k < -32767) k = -32767; - g->receive_gain[j] = linear_to_alaw(k); - } else { - g->receive_gain[j] = j; - } - if (txgain) { - k = (int) (((float) alaw_to_linear(j)) * linear_txgain); - if (k > 32767) k = 32767; - if (k < -32767) k = -32767; - g->transmit_gain[j] = linear_to_alaw(k); - } else { - g->transmit_gain[j] = j; - } - } - break; - case FTDM_CODEC_ULAW: - for (j = 0; j < (sizeof(g->receive_gain) / sizeof(g->receive_gain[0])); j++) { - if (rxgain) { - k = (int) (((float) ulaw_to_linear(j)) * linear_rxgain); - if (k > 32767) k = 32767; - if (k < -32767) k = -32767; - g->receive_gain[j] = linear_to_ulaw(k); - } else { - g->receive_gain[j] = j; - } - if (txgain) { - k = (int) (((float) ulaw_to_linear(j)) * linear_txgain); - if (k > 32767) k = 32767; - if (k < -32767) k = -32767; - g->transmit_gain[j] = linear_to_ulaw(k); - } else { - g->transmit_gain[j] = j; - } - } - break; - } -} - -/** - * \brief Initialises a range of Zaptel/DAHDI channels - * \param span FreeTDM span - * \param start Initial wanpipe channel number - * \param end Final wanpipe channel number - * \param type FreeTDM channel type - * \param name FreeTDM span name - * \param number FreeTDM span number - * \param cas_bits CAS bits - * \return number of spans configured - */ -static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, ftdm_chan_type_t type, char *name, char *number, unsigned char cas_bits) -{ - unsigned configured = 0, x; - zt_params_t ztp; - zt_tone_mode_t mode = 0; - - memset(&ztp, 0, sizeof(ztp)); - - if (type == FTDM_CHAN_TYPE_CAS) { - ftdm_log(FTDM_LOG_DEBUG, "Configuring CAS channels with abcd == 0x%X\n", cas_bits); - } - for(x = start; x < end; x++) { - ftdm_channel_t *ftdmchan; - ftdm_socket_t sockfd = ZT_INVALID_SOCKET; - int len; - - sockfd = open(chanpath, O_RDWR); - if (sockfd != ZT_INVALID_SOCKET && ftdm_span_add_channel(span, sockfd, type, &ftdmchan) == FTDM_SUCCESS) { - - if (ioctl(sockfd, codes.SPECIFY, &x)) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s chan %d fd %d (%s)\n", chanpath, x, sockfd, strerror(errno)); - close(sockfd); - continue; - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - struct zt_bufferinfo binfo; - memset(&binfo, 0, sizeof(binfo)); - binfo.txbufpolicy = 0; - binfo.rxbufpolicy = 0; - binfo.numbufs = 32; - binfo.bufsize = 1024; - if (ioctl(sockfd, codes.SET_BUFINFO, &binfo)) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd); - close(sockfd); - continue; - } - } - - if (type == FTDM_CHAN_TYPE_FXS || type == FTDM_CHAN_TYPE_FXO) { - struct zt_chanconfig cc; - memset(&cc, 0, sizeof(cc)); - cc.chan = cc.master = x; - - switch(type) { - case FTDM_CHAN_TYPE_FXS: - { - switch(span->start_type) { - case FTDM_ANALOG_START_KEWL: - cc.sigtype = ZT_SIG_FXOKS; - break; - case FTDM_ANALOG_START_LOOP: - cc.sigtype = ZT_SIG_FXOLS; - break; - case FTDM_ANALOG_START_GROUND: - cc.sigtype = ZT_SIG_FXOGS; - break; - default: - break; - } - } - break; - case FTDM_CHAN_TYPE_FXO: - { - switch(span->start_type) { - case FTDM_ANALOG_START_KEWL: - cc.sigtype = ZT_SIG_FXSKS; - break; - case FTDM_ANALOG_START_LOOP: - cc.sigtype = ZT_SIG_FXSLS; - break; - case FTDM_ANALOG_START_GROUND: - cc.sigtype = ZT_SIG_FXSGS; - break; - default: - break; - } - } - break; - default: - break; - } - - if (ioctl(CONTROL_FD, codes.CHANCONFIG, &cc)) { - ftdm_log(FTDM_LOG_WARNING, "this ioctl fails in older zaptel but is harmless if you used ztcfg\n[device %s chan %d fd %d (%s)]\n", chanpath, x, CONTROL_FD, strerror(errno)); - } - } - - if (type == FTDM_CHAN_TYPE_CAS) { - struct zt_chanconfig cc; - memset(&cc, 0, sizeof(cc)); - cc.chan = cc.master = x; - cc.sigtype = ZT_SIG_CAS; - cc.idlebits = cas_bits; - if (ioctl(CONTROL_FD, codes.CHANCONFIG, &cc)) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno)); - close(sockfd); - continue; - } - } - - if (ftdmchan->type != FTDM_CHAN_TYPE_DQ921 && ftdmchan->type != FTDM_CHAN_TYPE_DQ931) { - len = zt_globals.codec_ms * 8; - if (ioctl(ftdmchan->sockfd, codes.SET_BLOCKSIZE, &len)) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s\n", - chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno)); - close(sockfd); - continue; - } - - ftdmchan->packet_len = len; - ftdmchan->effective_interval = ftdmchan->native_interval = ftdmchan->packet_len / 8; - - if (ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - ftdmchan->packet_len *= 2; - } - } - - if (ioctl(sockfd, codes.GET_PARAMS, &ztp) < 0) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd); - close(sockfd); - continue; - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - if ( - (ztp.sig_type != ZT_SIG_HDLCRAW) && - (ztp.sig_type != ZT_SIG_HDLCFCS) && - (ztp.sig_type != ZT_SIG_HARDHDLC) - ) { - ftdm_log(FTDM_LOG_ERROR, "Failure configuring device %s as FreeTDM device %d:%d fd:%d, hardware signaling is not HDLC, fix your Zap/DAHDI configuration!\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd); - close(sockfd); - continue; - } - } - - ftdm_log(FTDM_LOG_INFO, "configuring device %s channel %d as FreeTDM device %d:%d fd:%d\n", chanpath, x, ftdmchan->span_id, ftdmchan->chan_id, sockfd); - - ftdmchan->rate = 8000; - ftdmchan->physical_span_id = ztp.span_no; - ftdmchan->physical_chan_id = ztp.chan_no; - - if (type == FTDM_CHAN_TYPE_FXS || type == FTDM_CHAN_TYPE_FXO || type == FTDM_CHAN_TYPE_EM || type == FTDM_CHAN_TYPE_B) { - if (ztp.g711_type == ZT_G711_ALAW) { - ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_ALAW; - } else if (ztp.g711_type == ZT_G711_MULAW) { - ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_ULAW; - } else { - int type; - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_E1) { - type = FTDM_CODEC_ALAW; - } else { - type = FTDM_CODEC_ULAW; - } - - ftdmchan->native_codec = ftdmchan->effective_codec = type; - - } - } - - ztp.wink_time = zt_globals.wink_ms; - ztp.flash_time = zt_globals.flash_ms; - - if (ioctl(sockfd, codes.SET_PARAMS, &ztp) < 0) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd); - close(sockfd); - continue; - } - - mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; - if (ioctl(sockfd, codes.TONEDETECT, &mode)) { - ftdm_log(FTDM_LOG_DEBUG, "HW DTMF not available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd); - } else { - ftdm_log(FTDM_LOG_DEBUG, "HW DTMF available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd); - ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT); - mode = 0; - ioctl(sockfd, codes.TONEDETECT, &mode); - } - - if (!ftdm_strlen_zero(name)) { - ftdm_copy_string(ftdmchan->chan_name, name, sizeof(ftdmchan->chan_name)); - } - if (!ftdm_strlen_zero(number)) { - ftdm_copy_string(ftdmchan->chan_number, number, sizeof(ftdmchan->chan_number)); - } - - configured++; - } else { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s\n", chanpath); - } - } - - - - return configured; -} - -/** - * \brief Initialises a freetdm Zaptel/DAHDI span from a configuration string - * \param span FreeTDM span - * \param str Configuration string - * \param type FreeTDM span type - * \param name FreeTDM span name - * \param number FreeTDM span number - * \return Success or failure - */ -static FIO_CONFIGURE_SPAN_FUNCTION(zt_configure_span) -{ - - int items, i; - char *mydata, *item_list[10]; - char *ch, *mx; - unsigned char cas_bits = 0; - int channo; - int top = 0; - unsigned configured = 0; - - assert(str != NULL); - - - mydata = ftdm_strdup(str); - assert(mydata != NULL); - - - items = ftdm_separate_string(mydata, ',', item_list, (sizeof(item_list) / sizeof(item_list[0]))); - - for(i = 0; i < items; i++) { - ch = item_list[i]; - - if (!(ch)) { - ftdm_log(FTDM_LOG_ERROR, "Invalid input\n"); - continue; - } - - channo = atoi(ch); - - if (channo < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid channel number %d\n", channo); - continue; - } - - if ((mx = strchr(ch, '-'))) { - mx++; - top = atoi(mx) + 1; - } else { - top = channo + 1; - } - - - if (top < 0) { - ftdm_log(FTDM_LOG_ERROR, "Invalid range number %d\n", top); - continue; - } - if (FTDM_CHAN_TYPE_CAS == type && ftdm_config_get_cas_bits(ch, &cas_bits)) { - ftdm_log(FTDM_LOG_ERROR, "Failed to get CAS bits in CAS channel\n"); - continue; - } - configured += zt_open_range(span, channo, top, type, name, number, cas_bits); - - } - - ftdm_safe_free(mydata); - - return configured; - -} - -/** - * \brief Process configuration variable for a Zaptel/DAHDI profile - * \param category Wanpipe profile name - * \param var Variable name - * \param val Variable value - * \param lineno Line number from configuration file - * \return Success - */ -static FIO_CONFIGURE_FUNCTION(zt_configure) -{ - - int num; - float fnum; - - if (!strcasecmp(category, "defaults")) { - if (!strcasecmp(var, "codec_ms")) { - num = atoi(val); - if (num < 10 || num > 60) { - ftdm_log(FTDM_LOG_WARNING, "invalid codec ms at line %d\n", lineno); - } else { - zt_globals.codec_ms = num; - } - } else if (!strcasecmp(var, "wink_ms")) { - num = atoi(val); - if (num < 50 || num > 3000) { - ftdm_log(FTDM_LOG_WARNING, "invalid wink ms at line %d\n", lineno); - } else { - zt_globals.wink_ms = num; - } - } else if (!strcasecmp(var, "flash_ms")) { - num = atoi(val); - if (num < 50 || num > 3000) { - ftdm_log(FTDM_LOG_WARNING, "invalid flash ms at line %d\n", lineno); - } else { - zt_globals.flash_ms = num; - } - } else if (!strcasecmp(var, "echo_cancel_level")) { - num = atoi(val); - if (num < 0 || num > 1024) { - ftdm_log(FTDM_LOG_WARNING, "invalid echo can val at line %d\n", lineno); - } else { - zt_globals.eclevel = num; - } - } else if (!strcasecmp(var, "echo_train_level")) { - if (zt_globals.eclevel < 1) { - ftdm_log(FTDM_LOG_WARNING, "can't set echo train level without setting echo cancel level first at line %d\n", lineno); - } else { - num = atoi(val); - if (num < 0 || num > 256) { - ftdm_log(FTDM_LOG_WARNING, "invalid echo train val at line %d\n", lineno); - } else { - zt_globals.etlevel = num; - } - } - } else if (!strcasecmp(var, "rxgain")) { - fnum = (float)atof(val); - if (fnum < -100.0 || fnum > 100.0) { - ftdm_log(FTDM_LOG_WARNING, "invalid rxgain val at line %d\n", lineno); - } else { - zt_globals.rxgain = fnum; - ftdm_log(FTDM_LOG_INFO, "Setting rxgain val to %f\n", fnum); - } - } else if (!strcasecmp(var, "txgain")) { - fnum = (float)atof(val); - if (fnum < -100.0 || fnum > 100.0) { - ftdm_log(FTDM_LOG_WARNING, "invalid txgain val at line %d\n", lineno); - } else { - zt_globals.txgain = fnum; - ftdm_log(FTDM_LOG_INFO, "Setting txgain val to %f\n", fnum); - } - } else { - ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown setting '%s'\n", var); - } - } - - return FTDM_SUCCESS; -} - -/** - * \brief Opens a Zaptel/DAHDI channel - * \param ftdmchan Channel to open - * \return Success or failure - */ -static FIO_OPEN_FUNCTION(zt_open) -{ - ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_INTERVAL); - - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921 || ftdmchan->type == FTDM_CHAN_TYPE_DQ931) { - ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE; - } else { - int blocksize = zt_globals.codec_ms * (ftdmchan->rate / 1000); - int err; - if ((err = ioctl(ftdmchan->sockfd, codes.SET_BLOCKSIZE, &blocksize))) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - return FTDM_FAIL; - } else { - ftdmchan->effective_interval = ftdmchan->native_interval; - ftdmchan->packet_len = blocksize; - ftdmchan->native_codec = ftdmchan->effective_codec; - } - - if (ftdmchan->type == FTDM_CHAN_TYPE_B) { - int one = 1; - if (ioctl(ftdmchan->sockfd, codes.AUDIOMODE, &one)) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - ftdm_log(FTDM_LOG_ERROR, "%s\n", ftdmchan->last_error); - return FTDM_FAIL; - } - } - if (zt_globals.rxgain || zt_globals.txgain) { - struct zt_gains gains; - memset(&gains, 0, sizeof(gains)); - - gains.chan_no = ftdmchan->physical_chan_id; - zt_build_gains(&gains, zt_globals.rxgain, zt_globals.txgain, ftdmchan->native_codec); - - if (zt_globals.rxgain) - ftdm_log(FTDM_LOG_INFO, "Setting rxgain to %f on channel %d\n", zt_globals.rxgain, gains.chan_no); - - if (zt_globals.txgain) - ftdm_log(FTDM_LOG_INFO, "Setting txgain to %f on channel %d\n", zt_globals.txgain, gains.chan_no); - - if (ioctl(ftdmchan->sockfd, codes.SETGAINS, &gains) < 0) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, ftdmchan->sockfd); - } - } - - if (1) { - int len = zt_globals.eclevel; - if (len) { - ftdm_log(FTDM_LOG_INFO, "Setting echo cancel to %d taps for %d:%d\n", len, ftdmchan->span_id, ftdmchan->chan_id); - } else { - ftdm_log(FTDM_LOG_INFO, "Disable echo cancel for %d:%d\n", ftdmchan->span_id, ftdmchan->chan_id); - } - if (ioctl(ftdmchan->sockfd, codes.ECHOCANCEL, &len)) { - ftdm_log(FTDM_LOG_WARNING, "Echo cancel not available for %d:%d\n", ftdmchan->span_id, ftdmchan->chan_id); - } else if (zt_globals.etlevel > 0) { - len = zt_globals.etlevel; - if (ioctl(ftdmchan->sockfd, codes.ECHOTRAIN, &len)) { - ftdm_log(FTDM_LOG_WARNING, "Echo training not available for %d:%d\n", ftdmchan->span_id, ftdmchan->chan_id); - } - } - } - } - return FTDM_SUCCESS; -} - -/** - * \brief Closes Zaptel/DAHDI channel - * \param ftdmchan Channel to close - * \return Success - */ -static FIO_CLOSE_FUNCTION(zt_close) -{ - if (ftdmchan->type == FTDM_CHAN_TYPE_B) { - int value = 0; /* disable audio mode */ - if (ioctl(ftdmchan->sockfd, codes.AUDIOMODE, &value)) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - ftdm_log(FTDM_LOG_ERROR, "%s\n", ftdmchan->last_error); - return FTDM_FAIL; - } - } - return FTDM_SUCCESS; -} - -/** - * \brief Executes a FreeTDM command on a Zaptel/DAHDI channel - * \param ftdmchan Channel to execute command on - * \param command FreeTDM command to execute - * \param obj Object (unused) - * \return Success or failure - */ -static FIO_COMMAND_FUNCTION(zt_command) -{ - zt_params_t ztp; - int err = 0; - - memset(&ztp, 0, sizeof(ztp)); - - switch(command) { - case FTDM_COMMAND_ENABLE_ECHOCANCEL: - { - int level = FTDM_COMMAND_OBJ_INT; - err = ioctl(ftdmchan->sockfd, codes.ECHOCANCEL, &level); - FTDM_COMMAND_OBJ_INT = level; - } - case FTDM_COMMAND_DISABLE_ECHOCANCEL: - { - int level = 0; - err = ioctl(ftdmchan->sockfd, codes.ECHOCANCEL, &level); - FTDM_COMMAND_OBJ_INT = level; - } - break; - case FTDM_COMMAND_ENABLE_ECHOTRAIN: - { - int level = FTDM_COMMAND_OBJ_INT; - err = ioctl(ftdmchan->sockfd, codes.ECHOTRAIN, &level); - FTDM_COMMAND_OBJ_INT = level; - } - case FTDM_COMMAND_DISABLE_ECHOTRAIN: - { - int level = 0; - err = ioctl(ftdmchan->sockfd, codes.ECHOTRAIN, &level); - FTDM_COMMAND_OBJ_INT = level; - } - break; - case FTDM_COMMAND_OFFHOOK: - { - int command = ZT_OFFHOOK; - if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "OFFHOOK Failed"); - return FTDM_FAIL; - } - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel is now offhook\n"); - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); - } - break; - case FTDM_COMMAND_ONHOOK: - { - int command = ZT_ONHOOK; - if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "ONHOOK Failed"); - return FTDM_FAIL; - } - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel is now onhook\n"); - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); - } - break; - case FTDM_COMMAND_FLASH: - { - int command = ZT_FLASH; - if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "FLASH Failed"); - return FTDM_FAIL; - } - } - break; - case FTDM_COMMAND_WINK: - { - int command = ZT_WINK; - if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "WINK Failed"); - return FTDM_FAIL; - } - } - break; - case FTDM_COMMAND_GENERATE_RING_ON: - { - int command = ZT_RING; - if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "RING Failed"); - return FTDM_FAIL; - } - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING); - } - break; - case FTDM_COMMAND_GENERATE_RING_OFF: - { - int command = ZT_RINGOFF; - if (ioctl(ftdmchan->sockfd, codes.HOOK, &command)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Ring-off Failed"); - return FTDM_FAIL; - } - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_RINGING); - } - break; - case FTDM_COMMAND_GET_INTERVAL: - { - - if (!(err = ioctl(ftdmchan->sockfd, codes.GET_BLOCKSIZE, &ftdmchan->packet_len))) { - ftdmchan->native_interval = ftdmchan->packet_len / 8; - if (ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - ftdmchan->packet_len *= 2; - } - FTDM_COMMAND_OBJ_INT = ftdmchan->native_interval; - } - } - break; - case FTDM_COMMAND_SET_INTERVAL: - { - int interval = FTDM_COMMAND_OBJ_INT; - int len = interval * 8; - - if (!(err = ioctl(ftdmchan->sockfd, codes.SET_BLOCKSIZE, &len))) { - ftdmchan->packet_len = len; - ftdmchan->effective_interval = ftdmchan->native_interval = ftdmchan->packet_len / 8; - - if (ftdmchan->effective_codec == FTDM_CODEC_SLIN) { - ftdmchan->packet_len *= 2; - } - } - } - break; - case FTDM_COMMAND_SET_CAS_BITS: - { - int bits = FTDM_COMMAND_OBJ_INT; - err = ioctl(ftdmchan->sockfd, codes.SETTXBITS, &bits); - } - break; - case FTDM_COMMAND_GET_CAS_BITS: - { - err = ioctl(ftdmchan->sockfd, codes.GETRXBITS, &ftdmchan->rx_cas_bits); - if (!err) { - FTDM_COMMAND_OBJ_INT = ftdmchan->rx_cas_bits; - } - } - break; - case FTDM_COMMAND_FLUSH_TX_BUFFERS: - { - int flushmode = ZT_FLUSH_WRITE; - err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode); - } - break; - case FTDM_COMMAND_SET_POLARITY: - { - ftdm_polarity_t polarity = FTDM_COMMAND_OBJ_INT; - err = ioctl(ftdmchan->sockfd, codes.SETPOLARITY, polarity); - if (!err) { - ftdmchan->polarity = polarity; - } - } - break; - case FTDM_COMMAND_FLUSH_RX_BUFFERS: - { - int flushmode = ZT_FLUSH_READ; - err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode); - } - break; - case FTDM_COMMAND_FLUSH_BUFFERS: - { - int flushmode = ZT_FLUSH_BOTH; - err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode); - } - break; - case FTDM_COMMAND_SET_RX_QUEUE_SIZE: - case FTDM_COMMAND_SET_TX_QUEUE_SIZE: - /* little white lie ... eventually we can implement this, in the meantime, not worth the effort - and this is only used by some sig modules such as ftmod_r2 to behave bettter under load */ - err = 0; - break; - case FTDM_COMMAND_ENABLE_DTMF_DETECT: - { - zt_tone_mode_t mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; - err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode); - } - break; - case FTDM_COMMAND_DISABLE_DTMF_DETECT: - { - zt_tone_mode_t mode = 0; - err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode); - } - break; - default: - err = FTDM_NOTIMPL; - break; - }; - - if (err && err != FTDM_NOTIMPL) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); - return FTDM_FAIL; - } - - - return err == 0 ? FTDM_SUCCESS : err; -} - -/** - * \brief Gets alarms from a Zaptel/DAHDI channel - * \param ftdmchan Channel to get alarms from - * \return Success or failure - */ -static FIO_GET_ALARMS_FUNCTION(zt_get_alarms) -{ - struct zt_spaninfo info; - zt_params_t params; - - memset(&info, 0, sizeof(info)); - info.span_no = ftdmchan->physical_span_id; - - memset(¶ms, 0, sizeof(params)); - - if (ioctl(CONTROL_FD, codes.SPANSTAT, &info)) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ioctl failed (%s)", strerror(errno)); - snprintf(ftdmchan->span->last_error, sizeof(ftdmchan->span->last_error), "ioctl failed (%s)", strerror(errno)); - return FTDM_FAIL; - } - - ftdmchan->alarm_flags = info.alarms; - - /* get channel alarms if span has no alarms */ - if (info.alarms == FTDM_ALARM_NONE) { - if (ioctl(ftdmchan->sockfd, codes.GET_PARAMS, ¶ms)) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ioctl failed (%s)", strerror(errno)); - snprintf(ftdmchan->span->last_error, sizeof(ftdmchan->span->last_error), "ioctl failed (%s)", strerror(errno)); - return FTDM_FAIL; - } - - if (params.chan_alarms > 0) { - if (params.chan_alarms == DAHDI_ALARM_YELLOW) { - ftdmchan->alarm_flags = FTDM_ALARM_YELLOW; - } - else if (params.chan_alarms == DAHDI_ALARM_BLUE) { - ftdmchan->alarm_flags = FTDM_ALARM_BLUE; - } - else { - ftdmchan->alarm_flags = FTDM_ALARM_RED; - } - } - } - - return FTDM_SUCCESS; -} - -#define ftdm_zt_set_event_pending(fchan) \ - do { \ - ftdm_set_io_flag(fchan, FTDM_CHANNEL_IO_EVENT); \ - fchan->last_event_time = ftdm_current_time_in_ms(); \ - } while (0); - -#define ftdm_zt_store_chan_event(fchan, revent) \ - do { \ - if (fchan->io_data) { \ - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Dropping event %d, not retrieved on time\n", revent); \ - } \ - fchan->io_data = (void *)zt_event_id; \ - ftdm_zt_set_event_pending(fchan); \ - } while (0); - -/** - * \brief Waits for an event on a Zaptel/DAHDI channel - * \param ftdmchan Channel to open - * \param flags Type of event to wait for - * \param to Time to wait (in ms) - * \return Success, failure or timeout - */ -static FIO_WAIT_FUNCTION(zt_wait) -{ - int32_t inflags = 0; - int result; - struct pollfd pfds[1]; - - if (*flags & FTDM_READ) { - inflags |= POLLIN; - } - - if (*flags & FTDM_WRITE) { - inflags |= POLLOUT; - } - - if (*flags & FTDM_EVENTS) { - inflags |= POLLPRI; - } - -pollagain: - memset(&pfds[0], 0, sizeof(pfds[0])); - pfds[0].fd = ftdmchan->sockfd; - pfds[0].events = inflags; - result = poll(pfds, 1, to); - *flags = FTDM_NO_FLAGS; - - if (result < 0 && errno == EINTR) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DAHDI wait got interrupted, trying again\n"); - goto pollagain; - } - - if (pfds[0].revents & POLLERR) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "DAHDI device got POLLERR\n"); - result = -1; - } - - if (result > 0) { - inflags = pfds[0].revents; - } - - if (result < 0){ - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Poll failed"); - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to poll DAHDI device: %s\n", strerror(errno)); - return FTDM_FAIL; - } - - if (result == 0) { - return FTDM_TIMEOUT; - } - - if (inflags & POLLIN) { - *flags |= FTDM_READ; - } - - if (inflags & POLLOUT) { - *flags |= FTDM_WRITE; - } - - if ((inflags & POLLPRI) || (ftdmchan->io_data && (*flags & FTDM_EVENTS))) { - *flags |= FTDM_EVENTS; - } - - return FTDM_SUCCESS; - -} - -/** - * \brief Checks for events on a Zaptel/DAHDI span - * \param span Span to check for events - * \param ms Time to wait for event - * \return Success if event is waiting or failure if not - */ -FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) -{ - struct pollfd pfds[FTDM_MAX_CHANNELS_SPAN]; - uint32_t i, j = 0, k = 0; - int r; - - ftdm_unused_arg(poll_events); - - for(i = 1; i <= span->chan_count; i++) { - memset(&pfds[j], 0, sizeof(pfds[j])); - pfds[j].fd = span->channels[i]->sockfd; - pfds[j].events = POLLPRI; - j++; - } - - r = poll(pfds, j, ms); - - if (r == 0) { - return FTDM_TIMEOUT; - } else if (r < 0) { - snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); - return FTDM_FAIL; - } - - for(i = 1; i <= span->chan_count; i++) { - - ftdm_channel_lock(span->channels[i]); - - if (pfds[i-1].revents & POLLERR) { - ftdm_log_chan(span->channels[i], FTDM_LOG_ERROR, "POLLERR, flags=%d\n", pfds[i-1].events); - - ftdm_channel_unlock(span->channels[i]); - - continue; - } - if ((pfds[i-1].revents & POLLPRI) || (span->channels[i]->io_data)) { - ftdm_zt_set_event_pending(span->channels[i]); - k++; - } - if (pfds[i-1].revents & POLLIN) { - ftdm_set_io_flag(span->channels[i], FTDM_CHANNEL_IO_READ); - } - if (pfds[i-1].revents & POLLOUT) { - ftdm_set_io_flag(span->channels[i], FTDM_CHANNEL_IO_WRITE); - } - - ftdm_channel_unlock(span->channels[i]); - - } - - if (!k) { - snprintf(span->last_error, sizeof(span->last_error), "no matching descriptor"); - } - - return k ? FTDM_SUCCESS : FTDM_FAIL; -} - -static __inline__ int handle_dtmf_event(ftdm_channel_t *fchan, zt_event_t zt_event_id) -{ - if ((zt_event_id & ZT_EVENT_DTMFUP)) { - int digit = (zt_event_id & (~ZT_EVENT_DTMFUP)); - char tmp_dtmf[2] = { digit, 0 }; - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF UP [%d]\n", digit); - ftdm_channel_queue_dtmf(fchan, tmp_dtmf); - return 0; - } else if ((zt_event_id & ZT_EVENT_DTMFDOWN)) { - int digit = (zt_event_id & (~ZT_EVENT_DTMFDOWN)); - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF DOWN [%d]\n", digit); - return 0; - } else { - return -1; - } -} - -/** - * \brief Process an event from a ftdmchan and set the proper OOB event_id. The channel must be locked. - * \param fchan Channel to retrieve event from - * \param event_id Pointer to OOB event id - * \param zt_event_id Zaptel event id - * \return FTDM_SUCCESS or FTDM_FAIL - */ -static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan, ftdm_oob_event_t *event_id, zt_event_t zt_event_id) -{ - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Processing zap hardware event %d\n", zt_event_id); - switch(zt_event_id) { - case ZT_EVENT_RINGEROFF: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "ZT RINGER OFF\n"); - *event_id = FTDM_OOB_NOOP; - } - break; - case ZT_EVENT_RINGERON: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "ZT RINGER ON\n"); - *event_id = FTDM_OOB_NOOP; - } - break; - case ZT_EVENT_RINGBEGIN: - { - *event_id = FTDM_OOB_RING_START; - } - break; - case ZT_EVENT_ONHOOK: - { - *event_id = FTDM_OOB_ONHOOK; - } - break; - case ZT_EVENT_WINKFLASH: - { - if (fchan->state == FTDM_CHANNEL_STATE_DOWN || fchan->state == FTDM_CHANNEL_STATE_DIALING) { - *event_id = FTDM_OOB_WINK; - } else { - *event_id = FTDM_OOB_FLASH; - } - } - break; - case ZT_EVENT_RINGOFFHOOK: - { - *event_id = FTDM_OOB_NOOP; - if (fchan->type == FTDM_CHAN_TYPE_FXS || (fchan->type == FTDM_CHAN_TYPE_EM && fchan->state != FTDM_CHANNEL_STATE_UP)) { - if (fchan->type != FTDM_CHAN_TYPE_EM) { - /* In E&M we're supposed to set this flag only when the local side goes offhook, not the remote */ - ftdm_set_flag_locked(fchan, FTDM_CHANNEL_OFFHOOK); - } - - /* For E&M let's count the ring count (it seems sometimes we receive RINGOFFHOOK once before the other end - * answers, then another RINGOFFHOOK when the other end answers?? anyways, now we count rings before delivering the - * offhook event ... the E&M signaling code in ftmod_analog_em also polls the RBS bits looking for answer, just to - * be safe and not rely on this event, so even if this event does not arrive, when there is answer supervision - * the analog signaling code should detect the cas persistance pattern and answer */ - if (fchan->type == FTDM_CHAN_TYPE_EM && ftdm_test_flag(fchan, FTDM_CHANNEL_OUTBOUND)) { - fchan->ring_count++; - /* perhaps some day we'll make this configurable, but since I am not even sure what the hell is going on - * no point in making a configuration option for something that may not be technically correct */ - if (fchan->ring_count == 2) { - *event_id = FTDM_OOB_OFFHOOK; - } - } else { - *event_id = FTDM_OOB_OFFHOOK; - } - } else if (fchan->type == FTDM_CHAN_TYPE_FXO) { - *event_id = FTDM_OOB_RING_START; - } - } - break; - case ZT_EVENT_ALARM: - { - *event_id = FTDM_OOB_ALARM_TRAP; - } - break; - case ZT_EVENT_NOALARM: - { - *event_id = FTDM_OOB_ALARM_CLEAR; - } - break; - case ZT_EVENT_BITSCHANGED: - { - *event_id = FTDM_OOB_CAS_BITS_CHANGE; - int bits = 0; - int err = ioctl(fchan->sockfd, codes.GETRXBITS, &bits); - if (err) { - return FTDM_FAIL; - } - fchan->rx_cas_bits = bits; - } - break; - case ZT_EVENT_BADFCS: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Bad frame checksum (ZT_EVENT_BADFCS)\n"); - *event_id = FTDM_OOB_NOOP; /* What else could we do? */ - } - break; - case ZT_EVENT_OVERRUN: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "HDLC frame overrun (ZT_EVENT_OVERRUN)\n"); - *event_id = FTDM_OOB_NOOP; /* What else could we do? */ - } - break; - case ZT_EVENT_ABORT: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "HDLC abort frame received (ZT_EVENT_ABORT)\n"); - *event_id = FTDM_OOB_NOOP; /* What else could we do? */ - } - break; - case ZT_EVENT_POLARITY: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Got polarity reverse (ZT_EVENT_POLARITY)\n"); - *event_id = FTDM_OOB_POLARITY_REVERSE; - } - break; - case ZT_EVENT_NONE: - { - ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "No event\n"); - *event_id = FTDM_OOB_NOOP; - } - break; - default: - { - if (handle_dtmf_event(fchan, zt_event_id)) { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id); - *event_id = FTDM_OOB_INVALID; - } else { - *event_id = FTDM_OOB_NOOP; - } - } - break; - } - return FTDM_SUCCESS; -} - -/** - * \brief Retrieves an event from a ftdm channel - * \param ftdmchan Channel to retrieve event from - * \param event FreeTDM event to return - * \return Success or failure - */ -FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event) -{ - uint32_t event_id = FTDM_OOB_INVALID; - zt_event_t zt_event_id = 0; - ftdm_span_t *span = ftdmchan->span; - - if (ftdm_test_io_flag(ftdmchan, FTDM_CHANNEL_IO_EVENT)) { - ftdm_clear_io_flag(ftdmchan, FTDM_CHANNEL_IO_EVENT); - } - - if (ftdmchan->io_data) { - zt_event_id = (zt_event_t)ftdmchan->io_data; - ftdmchan->io_data = NULL; - } else if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event from channel: %s\n", - strerror(errno)); - return FTDM_FAIL; - } - - /* the core already locked the channel for us, so it's safe to call zt_channel_process_event() here */ - if ((zt_channel_process_event(ftdmchan, &event_id, zt_event_id)) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to process DAHDI event %d from channel\n", zt_event_id); - return FTDM_FAIL; - } - - ftdmchan->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = ftdmchan; - *event = &span->event_header; - return FTDM_SUCCESS; -} - -/** - * \brief Retrieves an event from a Zaptel/DAHDI span - * \param span Span to retrieve event from - * \param event FreeTDM event to return - * \return Success or failure - */ -FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) -{ - uint32_t i, event_id = FTDM_OOB_INVALID; - zt_event_t zt_event_id = 0; - - for (i = 1; i <= span->chan_count; i++) { - ftdm_channel_t *fchan = span->channels[i]; - - ftdm_channel_lock(fchan); - - if (!ftdm_test_io_flag(fchan, FTDM_CHANNEL_IO_EVENT)) { - - ftdm_channel_unlock(fchan); - - continue; - } - - ftdm_clear_io_flag(fchan, FTDM_CHANNEL_IO_EVENT); - - if (fchan->io_data) { - zt_event_id = (zt_event_t)fchan->io_data; - fchan->io_data = NULL; - } else if (ioctl(fchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to retrieve DAHDI event from channel: %s\n", strerror(errno)); - - ftdm_channel_unlock(fchan); - - continue; - } - - if ((zt_channel_process_event(fchan, &event_id, zt_event_id)) != FTDM_SUCCESS) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to process DAHDI event %d from channel\n", zt_event_id); - - ftdm_channel_unlock(fchan); - - return FTDM_FAIL; - } - - fchan->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = fchan; - *event = &span->event_header; - - ftdm_channel_unlock(fchan); - - return FTDM_SUCCESS; - } - - return FTDM_FAIL; -} - -/** - * \brief Reads data from a Zaptel/DAHDI channel - * \param ftdmchan Channel to read from - * \param data Data buffer - * \param datalen Size of data buffer - * \return Success, failure or timeout - */ -static FIO_READ_FUNCTION(zt_read) -{ - ftdm_ssize_t r = 0; - int read_errno = 0; - int errs = 0; - - while (errs++ < 30) { - r = read(ftdmchan->sockfd, data, *datalen); - if (r > 0) { - /* successful read, bail out now ... */ - break; - } - - /* Timeout ... retry after a bit */ - if (r == 0) { - ftdm_sleep(10); - if (errs) errs--; - continue; - } - - /* This gotta be an error, save errno in case we do printf(), ioctl() or other operations which may reset it */ - read_errno = errno; - if (read_errno == EAGAIN || read_errno == EINTR) { - /* Reasonable to retry under those errors */ - continue; - } - - /* When ELAST is returned, it means DAHDI has an out of band event ready and we won't be able to read anything until - * we retrieve the event using an ioctl(), so we try to retrieve it here ... */ - if (read_errno == ELAST) { - zt_event_t zt_event_id = 0; - if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event after ELAST on read: %s\n", strerror(errno)); - r = -1; - break; - } - - if (handle_dtmf_event(ftdmchan, zt_event_id)) { - /* Enqueue this event for later */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Deferring event %d to be able to read data\n", zt_event_id); - ftdm_zt_store_chan_event(ftdmchan, zt_event_id); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Skipping one IO read cycle due to DTMF event processing\n"); - } - break; - } - - /* Read error, keep going unless to many errors force us to abort ...*/ - ftdm_log(FTDM_LOG_ERROR, "IO read failed: %s\n", strerror(read_errno)); - } - - if (r > 0) { - *datalen = r; - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - *datalen -= 2; - } - return FTDM_SUCCESS; - } - else if (read_errno == ELAST) { - return FTDM_SUCCESS; - } - return r == 0 ? FTDM_TIMEOUT : FTDM_FAIL; -} - -/** - * \brief Writes data to a Zaptel/DAHDI channel - * \param ftdmchan Channel to write to - * \param data Data buffer - * \param datalen Size of data buffer - * \return Success or failure - */ -static FIO_WRITE_FUNCTION(zt_write) -{ - ftdm_ssize_t w = 0; - ftdm_size_t bytes = *datalen; - - if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { - memset(data+bytes, 0, 2); - bytes += 2; - } - -tryagain: - w = write(ftdmchan->sockfd, data, bytes); - - if (w >= 0) { - *datalen = w; - return FTDM_SUCCESS; - } - - if (errno == ELAST) { - zt_event_t zt_event_id = 0; - if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event after ELAST on write: %s\n", strerror(errno)); - return FTDM_FAIL; - } - - if (handle_dtmf_event(ftdmchan, zt_event_id)) { - /* Enqueue this event for later */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Deferring event %d to be able to write data\n", zt_event_id); - ftdm_zt_store_chan_event(ftdmchan, zt_event_id); - } - - goto tryagain; - } - - return FTDM_FAIL; -} - -/** - * \brief Destroys a Zaptel/DAHDI Channel - * \param ftdmchan Channel to destroy - * \return Success - */ -static FIO_CHANNEL_DESTROY_FUNCTION(zt_channel_destroy) -{ - close(ftdmchan->sockfd); - ftdmchan->sockfd = ZT_INVALID_SOCKET; - return FTDM_SUCCESS; -} - -/** - * \brief Global FreeTDM IO interface for Zaptel/DAHDI - */ -static ftdm_io_interface_t zt_interface; - -/** - * \brief Loads Zaptel/DAHDI IO module - * \param fio FreeTDM IO interface - * \return Success or failure - */ -static FIO_IO_LOAD_FUNCTION(zt_init) -{ - assert(fio != NULL); - struct stat statbuf; - memset(&zt_interface, 0, sizeof(zt_interface)); - memset(&zt_globals, 0, sizeof(zt_globals)); - - if (!stat(zt_ctlpath, &statbuf)) { - ftdm_log(FTDM_LOG_NOTICE, "Using Zaptel control device\n"); - ctlpath = zt_ctlpath; - chanpath = zt_chanpath; - memcpy(&codes, &zt_ioctl_codes, sizeof(codes)); - } else if (!stat(dahdi_ctlpath, &statbuf)) { - ftdm_log(FTDM_LOG_NOTICE, "Using DAHDI control device\n"); - ctlpath = dahdi_ctlpath; - chanpath = dahdi_chanpath; - memcpy(&codes, &dahdi_ioctl_codes, sizeof(codes)); - } else { - ftdm_log(FTDM_LOG_ERROR, "No DAHDI or Zap control device found in /dev/\n"); - return FTDM_FAIL; - } - if ((CONTROL_FD = open(ctlpath, O_RDWR)) < 0) { - ftdm_log(FTDM_LOG_ERROR, "Cannot open control device %s: %s\n", ctlpath, strerror(errno)); - return FTDM_FAIL; - } - - zt_globals.codec_ms = 20; - zt_globals.wink_ms = 150; - zt_globals.flash_ms = 750; - zt_globals.eclevel = 0; - zt_globals.etlevel = 0; - - zt_interface.name = "zt"; - zt_interface.configure = zt_configure; - zt_interface.configure_span = zt_configure_span; - zt_interface.open = zt_open; - zt_interface.close = zt_close; - zt_interface.command = zt_command; - zt_interface.wait = zt_wait; - zt_interface.read = zt_read; - zt_interface.write = zt_write; - zt_interface.poll_event = zt_poll_event; - zt_interface.next_event = zt_next_event; - zt_interface.channel_next_event = zt_channel_next_event; - zt_interface.channel_destroy = zt_channel_destroy; - zt_interface.get_alarms = zt_get_alarms; - *fio = &zt_interface; - - return FTDM_SUCCESS; -} - -/** - * \brief Unloads Zaptel/DAHDI IO module - * \return Success - */ -static FIO_IO_UNLOAD_FUNCTION(zt_destroy) -{ - close(CONTROL_FD); - memset(&zt_interface, 0, sizeof(zt_interface)); - return FTDM_SUCCESS; -} - -/** - * \brief FreeTDM Zaptel/DAHDI IO module definition - */ -ftdm_module_t ftdm_module = { - "zt", - zt_init, - zt_destroy, -}; - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h deleted file mode 100644 index 99c7ef451f..0000000000 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * W McRoberts - * - */ - -#ifndef FTDM_ZT_H -#define FTDM_ZT_H -#include "freetdm.h" -#include -#include - -#ifdef __sun -#include -#include -#include -#endif - -/* Hardware interface structures and defines */ -/* Based on documentation of the structures required for the hardware interface */ -/* from http://wiki.freeswitch.org/wiki/Zapata_ftdmtel_interface */ - -/* Structures */ - -/* Used with ioctl: ZT_GET_PARAMS and ZT_SET_PARAMS */ -struct zt_params { - int chan_no; /* Channel Number */ - int span_no; /* Span Number */ - int chan_position; /* Channel Position */ - int sig_type; /* Signal Type (read-only) */ - int sig_cap; /* Signal Cap (read-only) */ - int receive_offhook; /* Receive is offhook (read-only) */ - int receive_bits; /* Number of bits in receive (read-only) */ - int transmit_bits; /* Number of bits in transmit (read-only) */ - int transmit_hook_sig; /* Transmit Hook Signal (read-only) */ - int receive_hook_sig; /* Receive Hook Signal (read-only) */ - int g711_type; /* Member of zt_g711_t (read-only) */ - int idlebits; /* bits for the idle state (read-only) */ - char chan_name[40]; /* Channel Name */ - int prewink_time; - int preflash_time; - int wink_time; - int flash_time; - int start_time; - int receive_wink_time; - int receive_flash_time; - int debounce_time; - int pulse_break_time; - int pulse_make_time; - int pulse_after_time; - /* latest version of this struct include chan_alarms field */ - uint32_t chan_alarms; -}; - -typedef struct zt_params zt_params_t; - -/* Used with ioctl: ZT_CONFLINK, ZT_GETCONF and ZT_SETCONF */ -struct zt_confinfo { - int chan_no; /* Channel Number, 0 for current */ - int conference_number; - int conference_mode; -}; - -/* Used with ioctl: ZT_GETGAINS and ZT_SETGAINS */ -struct zt_gains { - int chan_no; /* Channel Number, 0 for current */ - unsigned char receive_gain[256]; /* Receive gain table */ - unsigned char transmit_gain[256]; /* Transmit gain table */ -}; - -/* Used with ioctl: ZT_SPANSTAT */ -struct zt_spaninfo { - int span_no; /* span number (-1 to use name) */ - char name[20]; /* Name of span */ - char description[40]; /* Description of span */ - int alarms; /* alarms status */ - int transmit_level; /* Transmit level */ - int receive_level; /* Receive level */ - int bpv_count; /* Current BPV count */ - int crc4_count; /* Current CRC4 error count */ - int ebit_count; /* Current E-bit error count */ - int fas_count; /* Current FAS error count */ - int irq_misses; /* Current IRQ misses */ - int sync_src; /* Span # of sync source (0 = free run) */ - int configured_chan_count; /* Count of channels configured on the span */ - int channel_count; /* Total count of channels on the span */ - int span_count; /* Total count of ftdmtel spans on the system*/ - /* end v1 of the struct */ - /* as long as we don't use the fields below we should be ok regardless of the ftdmtel/dahdi version */ - int lbo; /* Line Build Out */ - int lineconfig; /* framing/coding */ - /* end of v2 of the struct */ - char lboname[40]; /* Line Build Out in text form */ - char location[40]; /* span's device location in system */ - char manufacturer[40]; /* manufacturer of span's device */ - char devicetype[40]; /* span's device type */ - int irq; /* span's device IRQ */ - int linecompat; /* signaling modes possible on this span */ - char spantype[6]; /* type of span in text form */ -}; - -struct zt_maintinfo { - int span_no; /* span number */ - int command; /* Maintenance mode to set (from zt_maintenance_mode_t) */ -}; - -struct zt_lineconfig { -/* Used in ZT_SPANCONFIG */ - int span; /* Which span number (0 to use name) */ - char name[20]; /* Name of span to use */ - int lbo; /* line build-outs */ - int lineconfig; /* line config parameters (framing, coding) */ - int sync; /* what level of sync source we are */ -}; - -struct zt_chanconfig { -/* Used in ZT_CHANCONFIG */ - int chan; /* Channel we're applying this to (0 to use name) */ - char name[40]; /* Name of channel to use */ - int sigtype; /* Signal type */ - int deflaw; /* Default law (ZT_LAW_DEFAULT, ZT_LAW_MULAW, or ZT_LAW_ALAW */ - int master; /* Master channel if sigtype is ZT_SLAVE */ - int idlebits; /* Idle bits (if this is a CAS channel) or channel to monitor (if this is DACS channel) */ - char netdev_name[16]; /* name for the hdlc network device */ -}; - -struct zt_bufferinfo { -/* used in ZT_SET_BUFINFO and ZT_GET_BUFINFO */ - int txbufpolicy; /* Policy for handling receive buffers */ - int rxbufpolicy; /* Policy for handling receive buffers */ - int numbufs; /* How many buffers to use */ - int bufsize; /* How big each buffer is */ - int readbufs; /* How many read buffers are full (read-only) */ - int writebufs; /* How many write buffers are full (read-only) */ -}; - -/* Enumerations */ - -/* Values in zt_params structure for member g711_type */ -typedef enum { - ZT_G711_DEFAULT = 0, /* Default mulaw/alaw from the span */ - ZT_G711_MULAW = 1, - ZT_G711_ALAW = 2 -} zt_g711_t; - -typedef enum { - ZT_EVENT_NONE = 0, - ZT_EVENT_ONHOOK = 1, - ZT_EVENT_RINGOFFHOOK = 2, - ZT_EVENT_WINKFLASH = 3, - ZT_EVENT_ALARM = 4, - ZT_EVENT_NOALARM = 5, - ZT_EVENT_ABORT = 6, - ZT_EVENT_OVERRUN = 7, - ZT_EVENT_BADFCS = 8, - ZT_EVENT_DIALCOMPLETE = 9, - ZT_EVENT_RINGERON = 10, - ZT_EVENT_RINGEROFF = 11, - ZT_EVENT_HOOKCOMPLETE = 12, - ZT_EVENT_BITSCHANGED = 13, - ZT_EVENT_PULSE_START = 14, - ZT_EVENT_TIMER_EXPIRED = 15, - ZT_EVENT_TIMER_PING = 16, - ZT_EVENT_POLARITY = 17, - ZT_EVENT_RINGBEGIN = 18, - ZT_EVENT_DTMFDOWN = (1 << 17), - ZT_EVENT_DTMFUP = (1 << 18), -} zt_event_t; - -typedef enum { - ZT_FLUSH_READ = 1, - ZT_FLUSH_WRITE = 2, - ZT_FLUSH_BOTH = (ZT_FLUSH_READ | ZT_FLUSH_WRITE), - ZT_FLUSH_EVENT = 4, - ZT_FLUSH_ALL = (ZT_FLUSH_READ | ZT_FLUSH_WRITE | ZT_FLUSH_EVENT) -} zt_flush_t; - -typedef enum { - ZT_IOMUX_READ = 1, - ZT_IOMUX_WRITE = 2, - ZT_IOMUX_WRITEEMPTY = 4, - ZT_IOMUX_SIGEVENT = 8, - ZT_IOMUX_NOWAIT = 256 -} zt_iomux_t; - -typedef enum { - ZT_ONHOOK = 0, - ZT_OFFHOOK = 1, - ZT_WINK = 2, - ZT_FLASH = 3, - ZT_START = 4, - ZT_RING = 5, - ZT_RINGOFF = 6 -} zt_hookstate_t; - -typedef enum { - ZT_MAINT_NONE = 0, /* Normal Mode */ - ZT_MAINT_LOCALLOOP = 1, /* Local Loopback */ - ZT_MAINT_REMOTELOOP = 2, /* Remote Loopback */ - ZT_MAINT_LOOPUP = 3, /* Send Loopup Code */ - ZT_MAINT_LOOPDOWN = 4, /* Send Loopdown Code */ - ZT_MAINT_LOOPSTOP = 5 /* Stop Sending Loop Codes */ -} zt_maintenance_mode_t; - -typedef enum { -/* Signalling type */ -ZT_SIG_NONE = 0, /* chan not configured. */ - -ZT_SIG_FXSLS = ((1 << 0) | (1 << 13)), /* FXS, Loopstart */ -ZT_SIG_FXSGS = ((1 << 1) | (1 << 13)), /* FXS, Groundstart */ -ZT_SIG_FXSKS = ((1 << 2) | (1 << 13)), /* FXS, Kewlstart */ -ZT_SIG_FXOLS = ((1 << 3) | (1 << 12)), /* FXO, Loopstart */ -ZT_SIG_FXOGS = ((1 << 4) | (1 << 12)), /* FXO, Groupstart */ -ZT_SIG_FXOKS = ((1 << 5) | (1 << 12)), /* FXO, Kewlstart */ -ZT_SIG_EM = (1 << 6), /* E&M */ -ZT_SIG_CLEAR = (1 << 7), -ZT_SIG_HDLCRAW = ((1 << 8) | ZT_SIG_CLEAR), -ZT_SIG_HDLCFCS = ((1 << 9) | ZT_SIG_HDLCRAW), -ZT_SIG_CAS = (1 << 15), -ZT_SIG_HARDHDLC = ((1 << 19) | ZT_SIG_CLEAR), -} zt_sigtype_t; - -typedef enum { -ZT_DBIT = 1, -ZT_CBIT = 2, -ZT_BBIT = 4, -ZT_ABIT = 8 -} zt_cas_bit_t; - -typedef enum { -/* Tone Detection */ -ZT_TONEDETECT_ON = (1 << 0), /* Detect tones */ -ZT_TONEDETECT_MUTE = (1 << 1) /* Mute audio in received channel */ -} zt_tone_mode_t; - -/* Defines */ - -#define ZT_MAX_BLOCKSIZE 8192 -#define ZT_DEFAULT_MTU_MRU 2048 - -/* ioctl defines */ - -#define ZT_CODE 'J' -#define DAHDI_CODE 0xDA - - -#define ZT_GET_BLOCKSIZE _IOR (ZT_CODE, 1, int) /* Get Transfer Block Size. */ -#define ZT_SET_BLOCKSIZE _IOW (ZT_CODE, 2, int) /* Set Transfer Block Size. */ -#define ZT_FLUSH _IOW (ZT_CODE, 3, int) /* Flush Buffer(s) and stop I/O */ -#define ZT_SYNC _IOW (ZT_CODE, 4, int) /* Wait for Write to Finish */ -#define ZT_GET_PARAMS _IOR (ZT_CODE, 5, struct zt_params) /* Get channel parameters */ -#define ZT_SET_PARAMS _IOW (ZT_CODE, 6, struct zt_params) /* Set channel parameters */ -#define ZT_HOOK _IOW (ZT_CODE, 7, int) /* Set Hookswitch Status */ -#define ZT_GETEVENT _IOR (ZT_CODE, 8, int) /* Get Signalling Event */ -#define ZT_IOMUX _IOWR (ZT_CODE, 9, int) /* Wait for something to happen (IO Mux) */ -#define ZT_SPANSTAT _IOWR (ZT_CODE, 10, struct zt_spaninfo) /* Get Span Status */ -#define ZT_MAINT _IOW (ZT_CODE, 11, struct zt_maintinfo)/* Set Maintenance Mode for a span */ -#define ZT_GETCONF _IOWR (ZT_CODE, 12, struct zt_confinfo) /* Get Conference Mode */ -#define ZT_SETCONF _IOWR (ZT_CODE, 13, struct zt_confinfo) /* Set Conference Mode */ -#define ZT_CONFLINK _IOW (ZT_CODE, 14, struct zt_confinfo) /* Setup or Remove Conference Link */ -#define ZT_CONFDIAG _IOR (ZT_CODE, 15, int) /* Display Conference Diagnostic Information on Console */ - -#define ZT_GETGAINS _IOWR (ZT_CODE, 16, struct zt_gains) /* Get Channel audio gains */ -#define ZT_SETGAINS _IOWR (ZT_CODE, 17, struct zt_gains) /* Set Channel audio gains */ -#define ZT_SPANCONFIG _IOW (ZT_CODE, 18, struct zt_lineconfig)/* Set Line (T1) Configurations and start system */ -#define ZT_CHANCONFIG _IOW (ZT_CODE, 19, struct zt_chanconfig)/* Set Channel Configuration */ -#define ZT_SET_BUFINFO _IOW (ZT_CODE, 27, struct zt_bufferinfo)/* Set buffer policy */ -#define ZT_GET_BUFINFO _IOR (ZT_CODE, 28, struct zt_bufferinfo)/* Get current buffer info */ -#define ZT_AUDIOMODE _IOW (ZT_CODE, 32, int) /* Set a clear channel into audio mode */ -#define ZT_ECHOCANCEL _IOW (ZT_CODE, 33, int) /* Control Echo Canceller */ -#define ZT_HDLCRAWMODE _IOW (ZT_CODE, 36, int) /* Set a clear channel into HDLC w/out FCS checking/calculation mode */ -#define ZT_HDLCFCSMODE _IOW (ZT_CODE, 37, int) /* Set a clear channel into HDLC w/ FCS mode */ - -/* Specify a channel on /dev/ftdm/chan -- must be done before any other ioctl's and is only valid on /dev/ftdm/chan */ -#define ZT_SPECIFY _IOW (ZT_CODE, 38, int) - -/* Temporarily set the law on a channel to ZT_LAW_DEFAULT, ZT_LAW_ALAW, or ZT_LAW_MULAW. Is reset on close. */ -#define ZT_SETLAW _IOW (ZT_CODE, 39, int) - -/* Temporarily set the channel to operate in linear mode when non-zero or default law if 0 */ -#define ZT_SETLINEAR _IOW (ZT_CODE, 40, int) - -#define ZT_GETCONFMUTE _IOR (ZT_CODE, 49, int) /* Get Conference to mute mode */ -#define ZT_ECHOTRAIN _IOW (ZT_CODE, 50, int) /* Control Echo Trainer */ - -/* Set/Get CAS bits */ -#define ZT_SETTXBITS _IOW (ZT_CODE, 43, int) -#define ZT_GETRXBITS _IOR (ZT_CODE, 45, int) - -/* - * Enable tone detection -- implemented by low level driver - */ -#define ZT_TONEDETECT _IOW(ZT_CODE, 91, int) - -#define DAHDI_GET_BLOCKSIZE _IOR (DAHDI_CODE, 1, int) /* Get Transfer Block Size. */ -#define DAHDI_SET_BLOCKSIZE _IOW (DAHDI_CODE, 1, int) /* Set Transfer Block Size. */ -#define DAHDI_FLUSH _IOW (DAHDI_CODE, 3, int) /* Flush Buffer(s) and stop I/O */ -#define DAHDI_SYNC _IO (DAHDI_CODE, 4) /* Wait for Write to Finish */ -#define DAHDI_GET_PARAMS _IOR (DAHDI_CODE, 5, struct zt_params) /* Get channel parameters */ -#define DAHDI_SET_PARAMS _IOW (DAHDI_CODE, 5, struct zt_params) /* Set channel parameters */ -#define DAHDI_HOOK _IOW (DAHDI_CODE, 7, int) /* Set Hookswitch Status */ -#define DAHDI_GETEVENT _IOR (DAHDI_CODE, 8, int) /* Get Signalling Event */ -#define DAHDI_IOMUX _IOWR (DAHDI_CODE, 9, int) /* Wait for something to happen (IO Mux) */ -#define DAHDI_SPANSTAT _IOWR (DAHDI_CODE, 10, struct zt_spaninfo) /* Get Span Status */ -#define DAHDI_MAINT _IOW (DAHDI_CODE, 11, struct zt_maintinfo) /* Set Maintenance Mode for a span */ -#define DAHDI_GETCONF _IOR (DAHDI_CODE, 12, struct zt_confinfo) /* Get Conference Mode */ -#define DAHDI_SETCONF _IOW (DAHDI_CODE, 12, struct zt_confinfo) /* Set Conference Mode */ -#define DAHDI_CONFLINK _IOW (DAHDI_CODE, 14, struct zt_confinfo) /* Setup or Remove Conference Link */ -#define DAHDI_CONFDIAG _IOR (DAHDI_CODE, 15, int) /* Display Conference Diagnostic Information on Console */ - -#define DAHDI_GETGAINS _IOR (DAHDI_CODE, 16, struct zt_gains) /* Get Channel audio gains */ -#define DAHDI_SETGAINS _IOW (DAHDI_CODE, 16, struct zt_gains) /* Set Channel audio gains */ -#define DAHDI_SPANCONFIG _IOW (DAHDI_CODE, 18, struct zt_lineconfig)/* Set Line (T1) Configurations and start system */ -#define DAHDI_CHANCONFIG _IOW (DAHDI_CODE, 19, struct zt_chanconfig)/* Set Channel Configuration */ -#define DAHDI_SET_BUFINFO _IOW (DAHDI_CODE, 27, struct zt_bufferinfo)/* Set buffer policy */ -#define DAHDI_GET_BUFINFO _IOR (DAHDI_CODE, 27, struct zt_bufferinfo)/* Get current buffer info */ -#define DAHDI_AUDIOMODE _IOW (DAHDI_CODE, 32, int) /* Set a clear channel into audio mode */ -#define DAHDI_ECHOCANCEL _IOW (DAHDI_CODE, 33, int) /* Control Echo Canceller */ -#define DAHDI_HDLCRAWMODE _IOW (DAHDI_CODE, 36, int) /* Set a clear channel into HDLC w/out FCS checking/calculation mode */ -#define DAHDI_HDLCFCSMODE _IOW (DAHDI_CODE, 37, int) /* Set a clear channel into HDLC w/ FCS mode */ - -/* Dahdi channel alarms */ -#define DAHDI_ALARM_YELLOW (1 << 2) /* Yellow Alarm */ -#define DAHDI_ALARM_BLUE (1 << 4) /* Blue Alarm */ - -/* Specify a channel on /dev/dahdi/chan -- must be done before any other ioctl's and is only valid on /dev/dahdi/chan */ -#define DAHDI_SPECIFY _IOW (DAHDI_CODE, 38, int) - -/* Temporarily set the law on a channel to DAHDI_LAW_DEFAULT, DAHDI_LAW_ALAW, or DAHDI_LAW_MULAW. Is reset on close. */ -#define DAHDI_SETLAW _IOW (DAHDI_CODE, 39, int) - -/* Temporarily set the channel to operate in linear mode when non-zero or default law if 0 */ -#define DAHDI_SETLINEAR _IOW (DAHDI_CODE, 40, int) - -#define DAHDI_GETCONFMUTE _IOR (DAHDI_CODE, 49, int) /* Get Conference to mute mode */ -#define DAHDI_ECHOTRAIN _IOW (DAHDI_CODE, 50, int) /* Control Echo Trainer */ - -/* Set/Get CAS bits */ -#define DAHDI_SETTXBITS _IOW (DAHDI_CODE, 43, int) -#define DAHDI_GETRXBITS _IOR (DAHDI_CODE, 43, int) - -#define DAHDI_SETPOLARITY _IOW (DAHDI_CODE, 92, int) /* Polarity setting for FXO lines */ - -/* - * Enable tone detection -- implemented by low level driver - */ -#define DAHDI_TONEDETECT _IOW(DAHDI_CODE, 91, int) - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/g711.c b/libs/freetdm/src/g711.c deleted file mode 100644 index e113db5811..0000000000 --- a/libs/freetdm/src/g711.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * g711.c - A-law and u-law transcoding routines - * - * Written by Steve Underwood - * - * Copyright (C) 2006 Steve Underwood - * - * Despite my general liking of the GPL, I place this code in the - * public domain for the benefit of all mankind - even the slimy - * ones who might try to proprietize my work and use it to my - * detriment. - * - * $Id: g711.c,v 1.1 2006/06/07 15:46:39 steveu Exp $ - */ - -/*! \file */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#ifndef _MSC_VER -#include -#ifdef HAVE_TGMATH_H -#include -#endif -#endif - -#include "g711.h" - -/* Copied from the CCITT G.711 specification */ -static const uint8_t ulaw_to_alaw_table[256] = - { - 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, - 58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, - 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26, - 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106, - 104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120, - 126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77, - 66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93, - 82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85, - 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, - 186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181, - 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154, - 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234, - 232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248, - 254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205, - 194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221, - 210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213 - }; - -/* These transcoding tables are copied from the CCITT G.711 specification. To achieve - optimal results, do not change them. */ - -static const uint8_t alaw_to_ulaw_table[256] = - { - 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, - 57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52, - 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5, - 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, - 98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94, - 116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109, - 72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67, - 86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81, - 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, - 185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180, - 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133, - 154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, - 226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222, - 244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237, - 200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195, - 214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209 - }; - -uint8_t alaw_to_ulaw(uint8_t alaw) -{ - return alaw_to_ulaw_table[alaw]; -} -/*- End of function --------------------------------------------------------*/ - -uint8_t ulaw_to_alaw(uint8_t ulaw) -{ - return ulaw_to_alaw_table[ulaw]; -} -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/hashtable.c b/libs/freetdm/src/hashtable.c deleted file mode 100644 index 4b39e8599a..0000000000 --- a/libs/freetdm/src/hashtable.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "private/ftdm_core.h" -#include "hashtable.h" -#include "hashtable_private.h" -#include -#include -#include -#include - -/* - Credit for primes table: Aaron Krowne - http://br.endernet.org/~akrowne/ - http://planetmath.org/encyclopedia/GoodHashTablePrimes.html -*/ -static const unsigned int primes[] = { - 53, 97, 193, 389, - 769, 1543, 3079, 6151, - 12289, 24593, 49157, 98317, - 196613, 393241, 786433, 1572869, - 3145739, 6291469, 12582917, 25165843, - 50331653, 100663319, 201326611, 402653189, - 805306457, 1610612741 -}; -const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]); -const float max_load_factor = 0.65f; - -/*****************************************************************************/ -FT_DECLARE(struct hashtable *) -create_hashtable(unsigned int minsize, - unsigned int (*hashf) (void*), - int (*eqf) (void*,void*)) -{ - struct hashtable *h; - unsigned int pindex, size = primes[0]; - /* Check requested hashtable isn't too large */ - if (minsize > (1u << 30)) return NULL; - /* Enforce size as prime */ - for (pindex=0; pindex < prime_table_length; pindex++) { - if (primes[pindex] > minsize) { size = primes[pindex]; break; } - } - h = (struct hashtable *)ftdm_malloc(sizeof(struct hashtable)); - if (NULL == h) return NULL; /*oom*/ - h->table = (struct entry **)ftdm_malloc(sizeof(struct entry*) * size); - if (NULL == h->table) { ftdm_safe_free(h); return NULL; } /*oom*/ - memset(h->table, 0, size * sizeof(struct entry *)); - h->tablelength = size; - h->primeindex = pindex; - h->entrycount = 0; - h->hashfn = hashf; - h->eqfn = eqf; - h->loadlimit = (unsigned int) ceil(size * max_load_factor); - return h; -} - -/*****************************************************************************/ -unsigned int -hash(struct hashtable *h, void *k) -{ - /* Aim to protect against poor hash functions by adding logic here - * - logic taken from java 1.4 hashtable source */ - unsigned int i = h->hashfn(k); - i += ~(i << 9); - i ^= ((i >> 14) | (i << 18)); /* >>> */ - i += (i << 4); - i ^= ((i >> 10) | (i << 22)); /* >>> */ - return i; -} - -/*****************************************************************************/ -static int -hashtable_expand(struct hashtable *h) -{ - /* Double the size of the table to accomodate more entries */ - struct entry **newtable; - struct entry *e; - struct entry **pE; - unsigned int newsize, i, index; - /* Check we're not hitting max capacity */ - if (h->primeindex == (prime_table_length - 1)) return 0; - newsize = primes[++(h->primeindex)]; - - newtable = (struct entry **)ftdm_malloc(sizeof(struct entry*) * newsize); - if (NULL != newtable) - { - memset(newtable, 0, newsize * sizeof(struct entry *)); - /* This algorithm is not 'stable'. ie. it reverses the list - * when it transfers entries between the tables */ - for (i = 0; i < h->tablelength; i++) { - while (NULL != (e = h->table[i])) { - h->table[i] = e->next; - index = indexFor(newsize,e->h); - e->next = newtable[index]; - newtable[index] = e; - } - } - ftdm_safe_free(h->table); - h->table = newtable; - } - /* Plan B: realloc instead */ - else - { - newtable = (struct entry **) - realloc(h->table, newsize * sizeof(struct entry *)); - if (NULL == newtable) { (h->primeindex)--; return 0; } - h->table = newtable; - memset(newtable[h->tablelength], 0, newsize - h->tablelength); - for (i = 0; i < h->tablelength; i++) { - for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { - index = indexFor(newsize,e->h); - if (index == i) - { - pE = &(e->next); - } - else - { - *pE = e->next; - e->next = newtable[index]; - newtable[index] = e; - } - } - } - } - h->tablelength = newsize; - h->loadlimit = (unsigned int) ceil(newsize * max_load_factor); - return -1; -} - -/*****************************************************************************/ -FT_DECLARE(unsigned int) -hashtable_count(struct hashtable *h) -{ - return h->entrycount; -} - -/*****************************************************************************/ -FT_DECLARE(int) -hashtable_insert(struct hashtable *h, void *k, void *v, hashtable_flag_t flags) -{ - /* This method allows duplicate keys - but they shouldn't be used */ - unsigned int index; - struct entry *e; - if (++(h->entrycount) > h->loadlimit) - { - /* Ignore the return value. If expand fails, we should - * still try cramming just this value into the existing table - * -- we may not have memory for a larger table, but one more - * element may be ok. Next time we insert, we'll try expanding again.*/ - hashtable_expand(h); - } - e = (struct entry *)ftdm_malloc(sizeof(struct entry)); - if (NULL == e) { --(h->entrycount); return 0; } /*oom*/ - e->h = hash(h,k); - index = indexFor(h->tablelength,e->h); - e->k = k; - e->v = v; - e->flags = flags; - e->next = h->table[index]; - h->table[index] = e; - return -1; -} - -/*****************************************************************************/ -FT_DECLARE(void *) /* returns value associated with key */ -hashtable_search(struct hashtable *h, void *k) -{ - struct entry *e; - unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); - e = h->table[index]; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v; - e = e->next; - } - return NULL; -} - -/*****************************************************************************/ -FT_DECLARE(void *) /* returns value associated with key */ -hashtable_remove(struct hashtable *h, void *k) -{ - /* TODO: consider compacting the table when the load factor drops enough, - * or provide a 'compact' method. */ - - struct entry *e; - struct entry **pE; - void *v; - unsigned int hashvalue, index; - - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hash(h,k)); - pE = &(h->table[index]); - e = *pE; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - { - *pE = e->next; - h->entrycount--; - v = e->v; - if (e->flags & HASHTABLE_FLAG_FREE_KEY) { - freekey(e->k); - } - ftdm_safe_free(e); - return v; - } - pE = &(e->next); - e = e->next; - } - return NULL; -} - -/*****************************************************************************/ -/* destroy */ -FT_DECLARE(void) -hashtable_destroy(struct hashtable *h) -{ - unsigned int i; - struct entry *e, *f; - struct entry **table = h->table; - - for (i = 0; i < h->tablelength; i++) - { - e = table[i]; - while (NULL != e) - { f = e; e = e->next; if (f->flags & HASHTABLE_FLAG_FREE_KEY) freekey(f->k); if (f->flags & HASHTABLE_FLAG_FREE_VALUE) ftdm_safe_free(f->v); ftdm_safe_free(f); } - } - - ftdm_safe_free(h->table); - ftdm_safe_free(h); -} - -FT_DECLARE(struct hashtable_iterator *) hashtable_next(struct hashtable_iterator *i) -{ - - if (i->e) { - if ((i->e = i->e->next) != 0) { - return i; - } else { - i->pos++; - } - } - - while(i->pos < i->h->tablelength && !i->h->table[i->pos]) { - i->pos++; - } - - if (i->pos >= i->h->tablelength) { - return NULL; - } - - if ((i->e = i->h->table[i->pos]) != 0) { - return i; - } - - return NULL; -} - -FT_DECLARE(struct hashtable_iterator *) hashtable_first(struct hashtable *h) -{ - h->iterator.pos = 0; - h->iterator.e = NULL; - h->iterator.h = h; - return hashtable_next(&h->iterator); -} - - - -FT_DECLARE(void) hashtable_this(struct hashtable_iterator *i, const void **key, int *klen, void **val) -{ - if (i->e) { - if (key) { - *key = i->e->k; - } - if (klen) { - *klen = (int)strlen(i->e->k); - } - if (val) { - *val = i->e->v; - } - } else { - if (key) { - *key = NULL; - } - if (klen) { - *klen = 0; - } - if (val) { - *val = NULL; - } - } -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/hashtable_itr.c b/libs/freetdm/src/hashtable_itr.c deleted file mode 100644 index 113d1ea503..0000000000 --- a/libs/freetdm/src/hashtable_itr.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2002, 2004, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "private/ftdm_core.h" -#include "hashtable.h" -#include "hashtable_private.h" -#include "hashtable_itr.h" -#include /* defines NULL */ - -/*****************************************************************************/ -/* hashtable_iterator - iterator constructor */ - -struct hashtable_itr * -hashtable_iterator(struct hashtable *h) -{ - unsigned int i, tablelength; - struct hashtable_itr *itr = ftdm_malloc(sizeof(struct hashtable_itr)); - if (NULL == itr) return NULL; - itr->h = h; - itr->e = NULL; - itr->parent = NULL; - tablelength = h->tablelength; - itr->index = tablelength; - if (0 == h->entrycount) return itr; - - for (i = 0; i < tablelength; i++) - { - if (NULL != h->table[i]) - { - itr->e = h->table[i]; - itr->index = i; - break; - } - } - return itr; -} - -/*****************************************************************************/ -/* advance - advance the iterator to the next element - * returns zero if advanced to end of table */ - -int -hashtable_iterator_advance(struct hashtable_itr *itr) -{ - unsigned int j,tablelength; - struct entry **table; - struct entry *next; - if (NULL == itr->e) return 0; /* stupidity check */ - - next = itr->e->next; - if (NULL != next) - { - itr->parent = itr->e; - itr->e = next; - return -1; - } - tablelength = itr->h->tablelength; - itr->parent = NULL; - if (tablelength <= (j = ++(itr->index))) - { - itr->e = NULL; - return 0; - } - table = itr->h->table; - while (NULL == (next = table[j])) - { - if (++j >= tablelength) - { - itr->index = tablelength; - itr->e = NULL; - return 0; - } - } - itr->index = j; - itr->e = next; - return -1; -} - -/*****************************************************************************/ -/* remove - remove the entry at the current iterator position - * and advance the iterator, if there is a successive - * element. - * If you want the value, read it before you remove: - * beware memory leaks if you don't. - * Returns zero if end of iteration. */ - -int -hashtable_iterator_remove(struct hashtable_itr *itr) -{ - struct entry *remember_e, *remember_parent; - int ret; - - /* Do the removal */ - if (NULL == (itr->parent)) - { - /* element is head of a chain */ - itr->h->table[itr->index] = itr->e->next; - } else { - /* element is mid-chain */ - itr->parent->next = itr->e->next; - } - /* itr->e is now outside the hashtable */ - remember_e = itr->e; - itr->h->entrycount--; - freekey(remember_e->k); - - /* Advance the iterator, correcting the parent */ - remember_parent = itr->parent; - ret = hashtable_iterator_advance(itr); - if (itr->parent == remember_e) { itr->parent = remember_parent; } - ftdm_safe_free(remember_e); - return ret; -} - -/*****************************************************************************/ -int /* returns zero if not found */ -hashtable_iterator_search(struct hashtable_itr *itr, - struct hashtable *h, void *k) -{ - struct entry *e, *parent; - unsigned int hashvalue, index; - - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); - - e = h->table[index]; - parent = NULL; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - { - itr->index = index; - itr->e = e; - itr->parent = parent; - itr->h = h; - return -1; - } - parent = e; - e = e->next; - } - return 0; -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h deleted file mode 100755 index f90744df8d..0000000000 --- a/libs/freetdm/src/include/freetdm.h +++ /dev/null @@ -1,2023 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * David Yat Sin - * - */ - -#ifndef FREETDM_H -#define FREETDM_H - -#include "ftdm_declare.h" -#include "ftdm_call_utils.h" - -/*! \brief Max number of channels per physical span */ -#define FTDM_MAX_CHANNELS_PHYSICAL_SPAN 32 - -/*! \brief Max number of physical spans per logical span */ -#define FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN 128 - -/*! \brief Max number of channels a logical span can contain */ -#define FTDM_MAX_CHANNELS_SPAN FTDM_MAX_CHANNELS_PHYSICAL_SPAN * FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN - -/*! \brief Max number of logical spans */ -#define FTDM_MAX_SPANS_INTERFACE 128 - -/*! \brief Max number of channels per hunting group */ -#define FTDM_MAX_CHANNELS_GROUP 2048 - -/*! \brief Max number of groups */ -#define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE - -/*! \brief Max number of key=value pairs to be sent as signaling stack parameters */ -#define FTDM_MAX_SIG_PARAMETERS 30 - -#define FTDM_INVALID_INT_PARM 0xFF - -/*! \brief Thread/Mutex OS abstraction API. */ -#include "ftdm_os.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*! \brief Limit to span names */ -#define FTDM_MAX_NAME_STR_SZ 128 - -/*! \brief Limit to channel number strings */ -#define FTDM_MAX_NUMBER_STR_SZ 32 - -/*! \brief Hangup cause codes */ -typedef enum { - FTDM_CAUSE_NONE = 0, - FTDM_CAUSE_UNALLOCATED = 1, - FTDM_CAUSE_NO_ROUTE_TRANSIT_NET = 2, - FTDM_CAUSE_NO_ROUTE_DESTINATION = 3, - FTDM_CAUSE_SEND_SPECIAL_INFO_TONE = 4, - FTDM_CAUSE_MISDIALED_TRUNK_PREFIX = 5, - FTDM_CAUSE_CHANNEL_UNACCEPTABLE = 6, - FTDM_CAUSE_CALL_AWARDED_DELIVERED = 7, - FTDM_CAUSE_PREEMPTION = 8, - FTDM_CAUSE_PREEMPTION_CIRCUIT_RESERVED = 9, - FTDM_CAUSE_NORMAL_CLEARING = 16, - FTDM_CAUSE_USER_BUSY = 17, - FTDM_CAUSE_NO_USER_RESPONSE = 18, - FTDM_CAUSE_NO_ANSWER = 19, - FTDM_CAUSE_SUBSCRIBER_ABSENT = 20, - FTDM_CAUSE_CALL_REJECTED = 21, - FTDM_CAUSE_NUMBER_CHANGED = 22, - FTDM_CAUSE_REDIRECTION_TO_NEW_DESTINATION = 23, - FTDM_CAUSE_EXCHANGE_ROUTING_ERROR = 25, - FTDM_CAUSE_DESTINATION_OUT_OF_ORDER = 27, - FTDM_CAUSE_INVALID_NUMBER_FORMAT = 28, - FTDM_CAUSE_FACILITY_REJECTED = 29, - FTDM_CAUSE_RESPONSE_TO_STATUS_ENQUIRY = 30, - FTDM_CAUSE_NORMAL_UNSPECIFIED = 31, - FTDM_CAUSE_NORMAL_CIRCUIT_CONGESTION = 34, - FTDM_CAUSE_NETWORK_OUT_OF_ORDER = 38, - FTDM_CAUSE_PERMANENT_FRAME_MODE_CONNECTION_OOS = 39, - FTDM_CAUSE_PERMANENT_FRAME_MODE_OPERATIONAL = 40, - FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE = 41, - FTDM_CAUSE_SWITCH_CONGESTION = 42, - FTDM_CAUSE_ACCESS_INFO_DISCARDED = 43, - FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL = 44, - FTDM_CAUSE_PRE_EMPTED = 45, - FTDM_CAUSE_PRECEDENCE_CALL_BLOCKED = 46, - FTDM_CAUSE_RESOURCE_UNAVAILABLE_UNSPECIFIED = 47, - FTDM_CAUSE_QOS_NOT_AVAILABLE = 49, - FTDM_CAUSE_FACILITY_NOT_SUBSCRIBED = 50, - FTDM_CAUSE_OUTGOING_CALL_BARRED = 53, - FTDM_CAUSE_INCOMING_CALL_BARRED = 55, - FTDM_CAUSE_BEARERCAPABILITY_NOTAUTH = 57, - FTDM_CAUSE_BEARERCAPABILITY_NOTAVAIL = 58, - FTDM_CAUSE_INCONSISTENCY_IN_INFO = 62, - FTDM_CAUSE_SERVICE_UNAVAILABLE = 63, - FTDM_CAUSE_BEARERCAPABILITY_NOTIMPL = 65, - FTDM_CAUSE_CHAN_NOT_IMPLEMENTED = 66, - FTDM_CAUSE_FACILITY_NOT_IMPLEMENTED = 69, - FTDM_CAUSE_ONLY_DIGITAL_INFO_BC_AVAIL = 70, - FTDM_CAUSE_SERVICE_NOT_IMPLEMENTED = 79, - FTDM_CAUSE_INVALID_CALL_REFERENCE = 81, - FTDM_CAUSE_IDENTIFIED_CHAN_NOT_EXIST = 82, - FTDM_CAUSE_SUSPENDED_CALL_EXISTS_BUT_CALL_ID_DOES_NOT = 83, - FTDM_CAUSE_CALL_ID_IN_USE = 84, - FTDM_CAUSE_NO_CALL_SUSPENDED = 85, - FTDM_CAUSE_CALL_WITH_CALL_ID_CLEARED = 86, - FTDM_CAUSE_USER_NOT_CUG = 87, - FTDM_CAUSE_INCOMPATIBLE_DESTINATION = 88, - FTDM_CAUSE_NON_EXISTENT_CUG = 90, - FTDM_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION = 91, - FTDM_CAUSE_INVALID_MSG_UNSPECIFIED = 95, - FTDM_CAUSE_MANDATORY_IE_MISSING = 96, - FTDM_CAUSE_MESSAGE_TYPE_NONEXIST = 97, - FTDM_CAUSE_WRONG_MESSAGE = 98, - FTDM_CAUSE_IE_NONEXIST = 99, - FTDM_CAUSE_INVALID_IE_CONTENTS = 100, - FTDM_CAUSE_WRONG_CALL_STATE = 101, - FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE = 102, - FTDM_CAUSE_MANDATORY_IE_LENGTH_ERROR = 103, - FTDM_CAUSE_MSG_WITH_UNRECOGNIZED_PARAM_DISCARDED = 110, - FTDM_CAUSE_PROTOCOL_ERROR = 111, - FTDM_CAUSE_INTERWORKING = 127, - FTDM_CAUSE_SUCCESS = 142, - FTDM_CAUSE_ORIGINATOR_CANCEL = 487, - FTDM_CAUSE_CRASH = 500, - FTDM_CAUSE_SYSTEM_SHUTDOWN = 501, - FTDM_CAUSE_LOSE_RACE = 502, - FTDM_CAUSE_MANAGER_REQUEST = 503, - FTDM_CAUSE_BLIND_TRANSFER = 600, - FTDM_CAUSE_ATTENDED_TRANSFER = 601, - FTDM_CAUSE_ALLOTTED_TIMEOUT = 602, - FTDM_CAUSE_USER_CHALLENGE = 603, - FTDM_CAUSE_MEDIA_TIMEOUT = 604 -} ftdm_call_cause_t; - -/*! \brief Hunting direction (when hunting for free channels) */ -typedef enum { - FTDM_HUNT_TOP_DOWN, - FTDM_HUNT_BOTTOM_UP, - FTDM_HUNT_RR_DOWN, - FTDM_HUNT_RR_UP, -} ftdm_hunt_direction_t; - -/*! \brief Legacy Hunting direction (Top down and Bottom up were reversed), keep for source backwards compatibility of freetdm user applications - * \deprecated - * \see ftdm_hunt_direction_t - */ -typedef enum { - FTDM_BOTTOM_UP, - FTDM_TOP_DOWN, - FTDM_RR_UP, - FTDM_RR_DOWN, -} ftdm_direction_t; - -/*! \brief I/O channel type */ -typedef enum { - FTDM_CHAN_TYPE_B, /*!< Bearer channel */ - FTDM_CHAN_TYPE_DQ921, /*!< DQ921 channel (D-channel) */ - FTDM_CHAN_TYPE_DQ931, /*!< DQ931 channel */ - FTDM_CHAN_TYPE_FXS, /*!< FXS analog channel */ - FTDM_CHAN_TYPE_FXO, /*!< FXO analog channel */ - FTDM_CHAN_TYPE_EM, /*!< E & M channel */ - FTDM_CHAN_TYPE_CAS, /*!< CAS channel */ - FTDM_CHAN_TYPE_COUNT /*!< Count of channel types */ -} ftdm_chan_type_t; -#define CHAN_TYPE_STRINGS "B", "DQ921", "DQ931", "FXS", "FXO", "EM", "CAS", "INVALID" -/*! \brief transform from channel type to string and from string to channel type - * ftdm_str2ftdm_chan_type transforms a channel string (ie: "FXO" to FTDM_CHAN_TYPE_FXO) - * ftdm_chan_type2str transforms a channel type to string (ie: FTDM_CHAN_TYPE_B to "B") - */ -FTDM_STR2ENUM_P(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t) - -/*! \brief Test if a channel is a voice channel */ -#define FTDM_IS_VOICE_CHANNEL(fchan) ((fchan)->type != FTDM_CHAN_TYPE_DQ921 && (fchan)->type != FTDM_CHAN_TYPE_DQ931) - -/*! \brief Test if a channel is a D-channel */ -#define FTDM_IS_DCHAN(fchan) ((fchan)->type == FTDM_CHAN_TYPE_DQ921 || (fchan)->type == FTDM_CHAN_TYPE_DQ931) - -/*! \brief Test if a channel is digital channel */ -#define FTDM_IS_DIGITAL_CHANNEL(fchan) ((fchan)->span->trunk_type == FTDM_TRUNK_E1 || \ - (fchan)->span->trunk_type == FTDM_TRUNK_T1 || \ - (fchan)->span->trunk_type == FTDM_TRUNK_J1 || \ - (fchan)->span->trunk_type == FTDM_TRUNK_BRI || \ - (fchan)->span->trunk_type == FTDM_TRUNK_BRI_PTMP) - -/*! \brief Test if a span is digital */ -#define FTDM_SPAN_IS_DIGITAL(span) \ - ((span)->trunk_type == FTDM_TRUNK_E1 || \ - (span)->trunk_type == FTDM_TRUNK_T1 || \ - (span)->trunk_type == FTDM_TRUNK_J1 || \ - (span)->trunk_type == FTDM_TRUNK_GSM || \ - (span)->trunk_type == FTDM_TRUNK_BRI || \ - (span)->trunk_type == FTDM_TRUNK_BRI_PTMP) - - -/*! \brief Logging function prototype to be used for all FreeTDM logs - * you should use ftdm_global_set_logger to set your own logger - */ -typedef void (*ftdm_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...) __ftdm_check_printf(5, 6); - -/*! \brief Data queue operation functions - * you can use ftdm_global_set_queue_handler if you want to override the default implementation (not recommended) - */ -typedef ftdm_status_t (*ftdm_queue_create_func_t)(ftdm_queue_t **queue, ftdm_size_t capacity); -typedef ftdm_status_t (*ftdm_queue_enqueue_func_t)(ftdm_queue_t *queue, void *obj); -typedef void *(*ftdm_queue_dequeue_func_t)(ftdm_queue_t *queue); -typedef ftdm_status_t (*ftdm_queue_wait_func_t)(ftdm_queue_t *queue, int ms); -typedef ftdm_status_t (*ftdm_queue_get_interrupt_func_t)(ftdm_queue_t *queue, ftdm_interrupt_t **interrupt); -typedef ftdm_status_t (*ftdm_queue_destroy_func_t)(ftdm_queue_t **queue); - -typedef struct ftdm_queue_handler { - ftdm_queue_create_func_t create; - ftdm_queue_enqueue_func_t enqueue; - ftdm_queue_dequeue_func_t dequeue; - ftdm_queue_wait_func_t wait; - ftdm_queue_get_interrupt_func_t get_interrupt; - ftdm_queue_destroy_func_t destroy; -} ftdm_queue_handler_t; - -/*! \brief Type Of Number (TON) */ -typedef enum { - FTDM_TON_UNKNOWN = 0, - FTDM_TON_INTERNATIONAL, - FTDM_TON_NATIONAL, - FTDM_TON_NETWORK_SPECIFIC, - FTDM_TON_SUBSCRIBER_NUMBER, - FTDM_TON_ABBREVIATED_NUMBER, - FTDM_TON_RESERVED, - FTDM_TON_INVALID -} ftdm_ton_t; -#define TON_STRINGS "unknown", "international", "national", "network-specific", "subscriber-number", "abbreviated-number", "reserved", "invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t) - -/*! Numbering Plan Identification (NPI) */ -typedef enum { - FTDM_NPI_UNKNOWN = 0, - FTDM_NPI_ISDN, - FTDM_NPI_DATA, - FTDM_NPI_TELEX, - FTDM_NPI_NATIONAL, - FTDM_NPI_PRIVATE, - FTDM_NPI_RESERVED, - FTDM_NPI_INVALID -} ftdm_npi_t; -#define NPI_STRINGS "unknown", "ISDN", "data", "telex", "national", "private", "reserved", "invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t) - -/*! Presentation Ind */ -typedef enum { - FTDM_PRES_ALLOWED, - FTDM_PRES_RESTRICTED, - FTDM_PRES_NOT_AVAILABLE, - FTDM_PRES_RESERVED, - FTDM_PRES_INVALID -} ftdm_presentation_t; -#define PRESENTATION_STRINGS "presentation-allowed", "presentation-restricted", "number-not-available", "reserved", "Invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t) - -/*! Screening Ind */ -typedef enum { - FTDM_SCREENING_NOT_SCREENED, - FTDM_SCREENING_VERIFIED_PASSED, - FTDM_SCREENING_VERIFIED_FAILED, - FTDM_SCREENING_NETWORK_PROVIDED, - FTDM_SCREENING_INVALID -} ftdm_screening_t; -#define SCREENING_STRINGS "user-provided-not-screened", "user-provided-verified-and-passed", "user-provided-verified-and-failed", "network-provided", "invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t) - -/*! \brief bearer capability */ -typedef enum { - FTDM_BEARER_CAP_SPEECH = 0x00, /* Speech */ - FTDM_BEARER_CAP_UNRESTRICTED, /* Unrestricted Digital */ - FTDM_BEARER_CAP_RESTRICTED, /* Restricted Digital */ - FTDM_BEARER_CAP_3_1KHZ_AUDIO, /* 3.1 Khz Audio */ - FTDM_BEARER_CAP_7KHZ_AUDIO, /* 7 Khz Audio or Unrestricted digital w tones */ - FTDM_BEARER_CAP_15KHZ_AUDIO, /* 15 Khz Audio */ - FTDM_BEARER_CAP_VIDEO, /* Video */ - FTDM_BEARER_CAP_INVALID -} ftdm_bearer_cap_t; -#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "restricted-digital-information", "3.1-Khz-audio", "7-Khz-audio", "15-Khz-audio", "video", "invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t) - -/*! \brief user information layer 1 protocol */ -typedef enum { - FTDM_USER_LAYER1_PROT_V110 = 0x01, - FTDM_USER_LAYER1_PROT_ULAW = 0x02, - FTDM_USER_LAYER1_PROT_ALAW = 0x03, - FTDM_USER_LAYER1_PROT_INVALID -} ftdm_user_layer1_prot_t; -#define USER_LAYER1_PROT_STRINGS "V.110", "ulaw", "alaw", "Invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t) - -/*! Calling Party Category */ -typedef enum { - FTDM_CPC_UNKNOWN, - FTDM_CPC_OPERATOR, - FTDM_CPC_OPERATOR_FRENCH, - FTDM_CPC_OPERATOR_ENGLISH, - FTDM_CPC_OPERATOR_GERMAN, - FTDM_CPC_OPERATOR_RUSSIAN, - FTDM_CPC_OPERATOR_SPANISH, - FTDM_CPC_ORDINARY, - FTDM_CPC_PRIORITY, - FTDM_CPC_DATA, - FTDM_CPC_TEST, - FTDM_CPC_PAYPHONE, - FTDM_CPC_INVALID -} ftdm_calling_party_category_t; -#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "operator-french", "operator-english", "operator-german", "operator-russian", "operator-spanish", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t) - -/*! Network responses to transfer requests */ -typedef enum { - FTDM_TRANSFER_RESPONSE_OK, /* Call is being transferred */ - FTDM_TRANSFER_RESPONSE_CP_DROP_OFF, /* Calling Party drop off */ - FTDM_TRANSFER_RESPONSE_LIMITS_EXCEEDED, /* Cannot redirect, limits exceeded */ - FTDM_TRANSFER_RESPONSE_INVALID_NUM, /* Network did not receive or recognize dialed number */ - FTDM_TRANSFER_RESPONSE_INVALID_COMMAND, /* Network received an invalid command */ - FTDM_TRANSFER_RESPONSE_TIMEOUT, /* We did not receive a response from Network */ - FTDM_TRANSFER_RESPONSE_INVALID, -} ftdm_transfer_response_t; -#define TRANSFER_RESPONSE_STRINGS "transfer-ok", "cp-drop-off", "limits-exceeded", "invalid-num", "invalid-command", "timeout", "invalid" -FTDM_STR2ENUM_P(ftdm_str2ftdm_transfer_response, ftdm_transfer_response2str, ftdm_transfer_response_t) - -/*! \brief Digit limit used in DNIS/ANI */ -#define FTDM_DIGITS_LIMIT 64 - -#define FTDM_SILENCE_VALUE(fchan) (fchan)->native_codec == FTDM_CODEC_ULAW ? 255 : (fchan)->native_codec == FTDM_CODEC_ALAW ? 0xD5 : 0x00 - -/*! \brief Number abstraction */ -typedef struct { - char digits[FTDM_DIGITS_LIMIT]; - uint8_t type; - uint8_t plan; -} ftdm_number_t; - -typedef struct { - char from[FTDM_MAX_NUMBER_STR_SZ]; - char body[FTDM_MAX_NAME_STR_SZ]; -} ftdm_sms_data_t; - -/*! \brief Caller information */ -typedef struct ftdm_caller_data { - char cid_date[8]; /*!< Caller ID date */ - char cid_name[80]; /*!< Caller ID name */ - ftdm_number_t cid_num; /*!< Caller ID number */ - ftdm_number_t ani; /*!< ANI (Automatic Number Identification) */ - ftdm_number_t dnis; /*!< DNIS (Dialed Number Identification Service) */ - ftdm_number_t rdnis; /*!< RDNIS (Redirected Dialed Number Identification Service) */ - ftdm_number_t loc; /*!< LOC (Location Reference Code) */ - char aniII[FTDM_DIGITS_LIMIT]; /*! ANI II */ - uint8_t screen; /*!< Screening */ - uint8_t pres; /*!< Presentation*/ - char collected[FTDM_DIGITS_LIMIT]; /*!< Collected digits so far */ - int hangup_cause; /*!< Hangup cause */ - /* these 2 are undocumented right now, only used by boost: */ - /* bearer capability */ - ftdm_bearer_cap_t bearer_capability; - /* user information layer 1 protocol */ - ftdm_user_layer1_prot_t bearer_layer1; - ftdm_calling_party_category_t cpc; /*!< Calling party category */ - uint32_t call_reference; - - ftdm_channel_t *fchan; /*!< FreeTDM channel associated (can be NULL) */ - - /* - * We need call_id inside caller_data for the user to be able to retrieve - * the call_id when ftdm_channel_call_place is called. This is the only time - * that the user can use caller_data.call_id to obtain the call_id. The user - * should use the call_id from sigmsg otherwise - */ - uint32_t call_id; /*!< Unique call ID for this call */ - - void *priv; /*!< Private data for the FreeTDM user */ -} ftdm_caller_data_t; - -/*! \brief Hunting mode */ -typedef enum { - FTDM_HUNT_SPAN, /*!< Hunt channels in a given span */ - FTDM_HUNT_GROUP, /*!< Hunt channels in a given group */ - FTDM_HUNT_CHAN, /*!< Hunt for a specific channel */ -} ftdm_hunt_mode_t; - -/*! \brief Structure used for FTDM_HUNT_SPAN mode */ -typedef struct { - uint32_t span_id; - ftdm_hunt_direction_t direction; -} ftdm_span_hunt_t; - -/*! \brief Structure used for FTDM_HUNT_GROUP mode */ -typedef struct { - uint32_t group_id; - ftdm_hunt_direction_t direction; -} ftdm_group_hunt_t; - -/*! \brief Structure used for FTDM_HUNT_CHAN mode */ -typedef struct { - uint32_t span_id; - uint32_t chan_id; -} ftdm_chan_hunt_t; - -/*! \brief Function called before placing the call in the hunted channel - * The user can have a last saying in whether to proceed or abort - * the call attempt. Be aware that this callback will be called with - * the channel lock and you must not do any blocking operations during - * its execution. - * \param fchan The channel that will be used to place the call - * \param caller_data The caller data provided to ftdm_call_place - * \return FTDM_SUCCESS to proceed or FTDM_BREAK to abort the hunting - */ -typedef ftdm_status_t (*ftdm_hunt_result_cb_t)(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data); - -/*! \brief Channel Hunting provided to ftdm_call_place() */ -typedef struct { - ftdm_hunt_mode_t mode; - union { - ftdm_span_hunt_t span; - ftdm_group_hunt_t group; - ftdm_chan_hunt_t chan; - } mode_data; - ftdm_hunt_result_cb_t result_cb; -} ftdm_hunting_scheme_t; - - -/*! \brief Tone type */ -typedef enum { - FTDM_TONE_DTMF = (1 << 0) -} ftdm_tone_type_t; - -/*! \brief Signaling messages sent by the stacks */ -typedef enum { - FTDM_SIGEVENT_START,/*!< Incoming call (ie: incoming SETUP msg or Ring) */ - FTDM_SIGEVENT_STOP, /*!< Hangup */ - FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */ - FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */ - FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */ - FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got an initial positive response from the other end */ - FTDM_SIGEVENT_RINGING, /*!< Remote side is in ringing state */ - FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */ - FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */ - FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */ - FTDM_SIGEVENT_ALARM_CLEAR, /*!< Hardware alarm OFF */ - FTDM_SIGEVENT_COLLECTED_DIGIT, /*!< Digit collected (in signalings where digits are collected one by one) */ - FTDM_SIGEVENT_ADD_CALL, /*!< New call should be added to the channel */ - FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */ - FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */ - FTDM_SIGEVENT_FACILITY, /*!< In call facility event */ - FTDM_SIGEVENT_TRACE, /*!priv */ - ftdm_variable_container_t variables; - union { - ftdm_event_sigstatus_t sigstatus; /*!< valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED */ - ftdm_event_trace_t trace; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */ - ftdm_event_collected_t collected; /*!< valid if event_id is FTDM_SIGEVENT_COLLECTED_DIGIT */ - ftdm_event_indication_completed_t indication_completed; /*!< valid if the event_id is FTDM_SIGEVENT_INDICATION_COMPLETED */ - ftdm_event_transfer_completed_t transfer_completed; - } ev_data; - ftdm_raw_data_t raw; -}; - -/*! \brief Generic user message sent to the stack */ -struct ftdm_usrmsg { - ftdm_variable_container_t variables; - ftdm_raw_data_t raw; -}; - -/*! \brief Crash policy - * Useful for debugging only, default policy is never, if you wish to crash on asserts then use ftdm_global_set_crash_policy */ -typedef enum { - FTDM_CRASH_NEVER = 0, - FTDM_CRASH_ON_ASSERT -} ftdm_crash_policy_t; - -/*! \brief Signaling configuration parameter for the stacks (variable=value pair) */ -typedef struct ftdm_conf_parameter { - const char *var; - const char *val; - void *ptr; -} ftdm_conf_parameter_t; - -/*! \brief Opaque general purpose iterator */ -typedef struct ftdm_iterator ftdm_iterator_t; - -/*! \brief Channel commands that can be executed through ftdm_channel_command() */ -typedef enum { - FTDM_COMMAND_NOOP = 0, - FTDM_COMMAND_SET_INTERVAL = 1, - FTDM_COMMAND_GET_INTERVAL = 2, - FTDM_COMMAND_SET_CODEC = 3, - FTDM_COMMAND_GET_CODEC = 4, - FTDM_COMMAND_SET_NATIVE_CODEC = 5, - FTDM_COMMAND_GET_NATIVE_CODEC = 6, - FTDM_COMMAND_ENABLE_DTMF_DETECT = 7, - FTDM_COMMAND_DISABLE_DTMF_DETECT = 8, - FTDM_COMMAND_SEND_DTMF = 9, - FTDM_COMMAND_SET_DTMF_ON_PERIOD = 10, - FTDM_COMMAND_GET_DTMF_ON_PERIOD = 11, - FTDM_COMMAND_SET_DTMF_OFF_PERIOD = 12, - FTDM_COMMAND_GET_DTMF_OFF_PERIOD = 13, - FTDM_COMMAND_GENERATE_RING_ON = 14, - FTDM_COMMAND_GENERATE_RING_OFF = 15, - FTDM_COMMAND_OFFHOOK = 16, - FTDM_COMMAND_ONHOOK = 17, - FTDM_COMMAND_FLASH = 18, - FTDM_COMMAND_WINK = 19, - FTDM_COMMAND_ENABLE_PROGRESS_DETECT = 20, - FTDM_COMMAND_DISABLE_PROGRESS_DETECT = 21, - - /*!< Start tracing input and output from channel to the given file */ - FTDM_COMMAND_TRACE_INPUT = 22, - FTDM_COMMAND_TRACE_OUTPUT = 23, - - /*!< Stop both Input and Output trace, closing the files */ - FTDM_COMMAND_TRACE_END_ALL = 24, - - /*!< Enable DTMF debugging */ - FTDM_COMMAND_ENABLE_DEBUG_DTMF = 25, - - /*!< Disable DTMF debugging (if not disabled explicitly, it is disabled automatically when calls hangup) */ - FTDM_COMMAND_DISABLE_DEBUG_DTMF = 26, - - /*!< Start dumping all input to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ - FTDM_COMMAND_ENABLE_INPUT_DUMP = 27, - - /*!< Stop dumping all input to a circular buffer. */ - FTDM_COMMAND_DISABLE_INPUT_DUMP = 28, - - /*!< Start dumping all output to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ - FTDM_COMMAND_ENABLE_OUTPUT_DUMP = 29, - - /*!< Stop dumping all output to a circular buffer. */ - FTDM_COMMAND_DISABLE_OUTPUT_DUMP = 30, - - /*!< Dump the current input circular buffer to the specified FILE* structure */ - FTDM_COMMAND_DUMP_INPUT = 31, - - /*!< Dump the current output circular buffer to the specified FILE* structure */ - FTDM_COMMAND_DUMP_OUTPUT = 32, - - FTDM_COMMAND_ENABLE_CALLERID_DETECT = 33, - FTDM_COMMAND_DISABLE_CALLERID_DETECT = 34, - FTDM_COMMAND_ENABLE_ECHOCANCEL = 35, - FTDM_COMMAND_DISABLE_ECHOCANCEL = 36, - FTDM_COMMAND_ENABLE_ECHOTRAIN = 37, - FTDM_COMMAND_DISABLE_ECHOTRAIN = 38, - FTDM_COMMAND_SET_CAS_BITS = 39, - FTDM_COMMAND_GET_CAS_BITS = 40, - FTDM_COMMAND_SET_RX_GAIN = 41, - FTDM_COMMAND_GET_RX_GAIN = 42, - FTDM_COMMAND_SET_TX_GAIN = 43, - FTDM_COMMAND_GET_TX_GAIN = 44, - FTDM_COMMAND_FLUSH_TX_BUFFERS = 45, - FTDM_COMMAND_FLUSH_RX_BUFFERS = 46, - FTDM_COMMAND_FLUSH_BUFFERS = 47, - - /*!< Flush IO statistics */ - FTDM_COMMAND_FLUSH_IOSTATS = 48, - - FTDM_COMMAND_SET_PRE_BUFFER_SIZE = 49, - FTDM_COMMAND_SET_LINK_STATUS = 50, - FTDM_COMMAND_GET_LINK_STATUS = 51, - FTDM_COMMAND_ENABLE_LOOP = 52, - FTDM_COMMAND_DISABLE_LOOP = 53, - FTDM_COMMAND_SET_RX_QUEUE_SIZE = 54, - FTDM_COMMAND_SET_TX_QUEUE_SIZE = 55, - FTDM_COMMAND_SET_POLARITY = 56, - FTDM_COMMAND_START_MF_PLAYBACK = 57, - FTDM_COMMAND_STOP_MF_PLAYBACK = 58, - - /*!< Get a copy of the current IO stats */ - FTDM_COMMAND_GET_IOSTATS = 59, - /*!< Enable/disable IO stats in the channel */ - FTDM_COMMAND_SWITCH_IOSTATS = 60, - - /*!< Enable/disable DTMF removal */ - FTDM_COMMAND_ENABLE_DTMF_REMOVAL = 61, - FTDM_COMMAND_DISABLE_DTMF_REMOVAL = 62, - - FTDM_COMMAND_COUNT, -} ftdm_command_t; - -typedef enum { - FTDM_POLARITY_FORWARD = 0, - FTDM_POLARITY_REVERSE = 1 -} ftdm_polarity_t; - -/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */ -typedef void *(*ftdm_malloc_func_t)(void *pool, ftdm_size_t len); -typedef void *(*ftdm_calloc_func_t)(void *pool, ftdm_size_t elements, ftdm_size_t len); -typedef void *(*ftdm_realloc_func_t)(void *pool, void *buff, ftdm_size_t len); -typedef void (*ftdm_free_func_t)(void *pool, void *ptr); -struct ftdm_memory_handler { - void *pool; - ftdm_malloc_func_t malloc; - ftdm_calloc_func_t calloc; - ftdm_realloc_func_t realloc; - ftdm_free_func_t free; -}; - -/*! \brief FreeTDM I/O layer interface argument macros - * You don't need these unless your implementing an I/O interface module (most users don't) */ -#define FIO_CHANNEL_REQUEST_ARGS (ftdm_span_t *span, uint32_t chan_id, ftdm_hunt_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) -#define FIO_CHANNEL_OUTGOING_CALL_ARGS (ftdm_channel_t *ftdmchan) -#define FIO_CHANNEL_INDICATE_ARGS (ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication) -#define FIO_CHANNEL_SET_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) -#define FIO_CHANNEL_GET_SIG_STATUS_ARGS (ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *status) -#define FIO_SPAN_SET_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t status) -#define FIO_SPAN_GET_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t *status) -#define FIO_SPAN_POLL_EVENT_ARGS (ftdm_span_t *span, uint32_t ms, short *poll_events) -#define FIO_SPAN_NEXT_EVENT_ARGS (ftdm_span_t *span, ftdm_event_t **event) -#define FIO_CHANNEL_NEXT_EVENT_ARGS (ftdm_channel_t *ftdmchan, ftdm_event_t **event) -#define FIO_SIGNAL_CB_ARGS (ftdm_sigmsg_t *sigmsg) -#define FIO_EVENT_CB_ARGS (ftdm_channel_t *ftdmchan, ftdm_event_t *event) -#define FIO_CONFIGURE_SPAN_ARGS (ftdm_span_t *span, const char *str, ftdm_chan_type_t type, char *name, char *number) -#define FIO_CONFIGURE_ARGS (const char *category, const char *var, const char *val, int lineno) -#define FIO_OPEN_ARGS (ftdm_channel_t *ftdmchan) -#define FIO_CLOSE_ARGS (ftdm_channel_t *ftdmchan) -#define FIO_CHANNEL_DESTROY_ARGS (ftdm_channel_t *ftdmchan) -#define FIO_SPAN_DESTROY_ARGS (ftdm_span_t *span) -#define FIO_COMMAND_ARGS (ftdm_channel_t *ftdmchan, ftdm_command_t command, void *obj) -#define FIO_WAIT_ARGS (ftdm_channel_t *ftdmchan, ftdm_wait_flag_t *flags, int32_t to) -#define FIO_GET_ALARMS_ARGS (ftdm_channel_t *ftdmchan) -#define FIO_READ_ARGS (ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen) -#define FIO_WRITE_ARGS (ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen) -#define FIO_IO_LOAD_ARGS (ftdm_io_interface_t **fio) -#define FIO_IO_UNLOAD_ARGS (void) -#define FIO_SIG_LOAD_ARGS (void) -#define FIO_SIG_CONFIGURE_ARGS (ftdm_span_t *span, fio_signal_cb_t sig_cb, va_list ap) -#define FIO_CONFIGURE_SPAN_SIGNALING_ARGS (ftdm_span_t *span, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *ftdm_parameters) -#define FIO_SIG_UNLOAD_ARGS (void) -#define FIO_API_ARGS (ftdm_stream_handle_t *stream, const char *data) -#define FIO_SPAN_START_ARGS (ftdm_span_t *span) -#define FIO_SPAN_STOP_ARGS (ftdm_span_t *span) - -/*! \brief FreeTDM I/O layer interface function typedefs - * You don't need these unless your implementing an I/O interface module (most users don't) */ -typedef ftdm_status_t (*fio_channel_request_t) FIO_CHANNEL_REQUEST_ARGS ; -typedef ftdm_status_t (*fio_channel_outgoing_call_t) FIO_CHANNEL_OUTGOING_CALL_ARGS ; -typedef ftdm_status_t (*fio_channel_indicate_t) FIO_CHANNEL_INDICATE_ARGS; -typedef ftdm_status_t (*fio_channel_set_sig_status_t) FIO_CHANNEL_SET_SIG_STATUS_ARGS; -typedef ftdm_status_t (*fio_channel_get_sig_status_t) FIO_CHANNEL_GET_SIG_STATUS_ARGS; -typedef ftdm_status_t (*fio_span_set_sig_status_t) FIO_SPAN_SET_SIG_STATUS_ARGS; -typedef ftdm_status_t (*fio_span_get_sig_status_t) FIO_SPAN_GET_SIG_STATUS_ARGS; -typedef ftdm_status_t (*fio_span_poll_event_t) FIO_SPAN_POLL_EVENT_ARGS ; -typedef ftdm_status_t (*fio_span_next_event_t) FIO_SPAN_NEXT_EVENT_ARGS ; -typedef ftdm_status_t (*fio_channel_next_event_t) FIO_CHANNEL_NEXT_EVENT_ARGS ; - -/*! \brief Callback for signal delivery (FTDM_SIGEVENT_START and friends) - * \note This callback is provided by the user during ftdm_configure_span_signaling - * - * \note You must NOT do any blocking during this callback since this function is - * most likely called in an internal signaling thread that can potentially be - * shared for all the channels in a span and blocking will delay processing - * (sometimes even audio processing) for other channels - * - * \note Although some simple FreeTDM APIs can work (ie: ftdm_span_get_id etc), the - * use of any FreeTDM call API (ie ftdm_channel_call_answer) is discouraged - */ -typedef ftdm_status_t (*fio_signal_cb_t) FIO_SIGNAL_CB_ARGS ; - -typedef ftdm_status_t (*fio_event_cb_t) FIO_EVENT_CB_ARGS ; -typedef ftdm_status_t (*fio_configure_span_t) FIO_CONFIGURE_SPAN_ARGS ; -typedef ftdm_status_t (*fio_configure_t) FIO_CONFIGURE_ARGS ; -typedef ftdm_status_t (*fio_open_t) FIO_OPEN_ARGS ; -typedef ftdm_status_t (*fio_close_t) FIO_CLOSE_ARGS ; -typedef ftdm_status_t (*fio_channel_destroy_t) FIO_CHANNEL_DESTROY_ARGS ; -typedef ftdm_status_t (*fio_span_destroy_t) FIO_SPAN_DESTROY_ARGS ; -typedef ftdm_status_t (*fio_get_alarms_t) FIO_GET_ALARMS_ARGS ; -typedef ftdm_status_t (*fio_command_t) FIO_COMMAND_ARGS ; -typedef ftdm_status_t (*fio_wait_t) FIO_WAIT_ARGS ; -typedef ftdm_status_t (*fio_read_t) FIO_READ_ARGS ; -typedef ftdm_status_t (*fio_write_t) FIO_WRITE_ARGS ; -typedef ftdm_status_t (*fio_io_load_t) FIO_IO_LOAD_ARGS ; -typedef ftdm_status_t (*fio_sig_load_t) FIO_SIG_LOAD_ARGS ; -typedef ftdm_status_t (*fio_sig_configure_t) FIO_SIG_CONFIGURE_ARGS ; -typedef ftdm_status_t (*fio_configure_span_signaling_t) FIO_CONFIGURE_SPAN_SIGNALING_ARGS ; -typedef ftdm_status_t (*fio_io_unload_t) FIO_IO_UNLOAD_ARGS ; -typedef ftdm_status_t (*fio_sig_unload_t) FIO_SIG_UNLOAD_ARGS ; -typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ; -typedef ftdm_status_t (*fio_span_start_t) FIO_SPAN_START_ARGS ; -typedef ftdm_status_t (*fio_span_stop_t) FIO_SPAN_STOP_ARGS ; - - -/*! \brief FreeTDM I/O layer interface function prototype wrapper macros - * You don't need these unless your implementing an I/O interface module (most users don't) */ -#define FIO_CHANNEL_REQUEST_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_REQUEST_ARGS -#define FIO_CHANNEL_OUTGOING_CALL_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_OUTGOING_CALL_ARGS -#define FIO_CHANNEL_INDICATE_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_INDICATE_ARGS -#define FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_SET_SIG_STATUS_ARGS -#define FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_GET_SIG_STATUS_ARGS -#define FIO_SPAN_SET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_SPAN_SET_SIG_STATUS_ARGS -#define FIO_SPAN_GET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_SPAN_GET_SIG_STATUS_ARGS -#define FIO_SPAN_POLL_EVENT_FUNCTION(name) ftdm_status_t name FIO_SPAN_POLL_EVENT_ARGS -#define FIO_SPAN_NEXT_EVENT_FUNCTION(name) ftdm_status_t name FIO_SPAN_NEXT_EVENT_ARGS -#define FIO_CHANNEL_NEXT_EVENT_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_NEXT_EVENT_ARGS -#define FIO_SIGNAL_CB_FUNCTION(name) ftdm_status_t name FIO_SIGNAL_CB_ARGS -#define FIO_EVENT_CB_FUNCTION(name) ftdm_status_t name FIO_EVENT_CB_ARGS -#define FIO_CONFIGURE_SPAN_FUNCTION(name) ftdm_status_t name FIO_CONFIGURE_SPAN_ARGS -#define FIO_CONFIGURE_FUNCTION(name) ftdm_status_t name FIO_CONFIGURE_ARGS -#define FIO_OPEN_FUNCTION(name) ftdm_status_t name FIO_OPEN_ARGS -#define FIO_CLOSE_FUNCTION(name) ftdm_status_t name FIO_CLOSE_ARGS -#define FIO_CHANNEL_DESTROY_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_DESTROY_ARGS -#define FIO_SPAN_DESTROY_FUNCTION(name) ftdm_status_t name FIO_SPAN_DESTROY_ARGS -#define FIO_GET_ALARMS_FUNCTION(name) ftdm_status_t name FIO_GET_ALARMS_ARGS -#define FIO_COMMAND_FUNCTION(name) ftdm_status_t name FIO_COMMAND_ARGS -#define FIO_WAIT_FUNCTION(name) ftdm_status_t name FIO_WAIT_ARGS -#define FIO_READ_FUNCTION(name) ftdm_status_t name FIO_READ_ARGS -#define FIO_WRITE_FUNCTION(name) ftdm_status_t name FIO_WRITE_ARGS -#define FIO_IO_LOAD_FUNCTION(name) ftdm_status_t name FIO_IO_LOAD_ARGS -#define FIO_SIG_LOAD_FUNCTION(name) ftdm_status_t name FIO_SIG_LOAD_ARGS -#define FIO_SIG_CONFIGURE_FUNCTION(name) ftdm_status_t name FIO_SIG_CONFIGURE_ARGS -#define FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(name) ftdm_status_t name FIO_CONFIGURE_SPAN_SIGNALING_ARGS -#define FIO_IO_UNLOAD_FUNCTION(name) ftdm_status_t name FIO_IO_UNLOAD_ARGS -#define FIO_SIG_UNLOAD_FUNCTION(name) ftdm_status_t name FIO_SIG_UNLOAD_ARGS -#define FIO_API_FUNCTION(name) ftdm_status_t name FIO_API_ARGS -#define FIO_SPAN_START_FUNCTION(name) ftdm_status_t name FIO_SPAN_START_ARGS -#define FIO_SPAN_STOP_FUNCTION(name) ftdm_status_t name FIO_SPAN_STOP_ARGS - -/*! \brief FreeTDM I/O layer function prototype wrapper macros - * You don't need these unless your implementing an I/O interface module (most users don't) */ -struct ftdm_io_interface { - const char *name; /*!< I/O module name */ - fio_configure_span_t configure_span; /*!< Configure span I/O */ - fio_configure_t configure; /*!< Configure the module */ - fio_open_t open; /*!< Open I/O channel */ - fio_close_t close; /*!< Close I/O channel */ - fio_channel_destroy_t channel_destroy; /*!< Destroy I/O channel */ - fio_span_destroy_t span_destroy; /*!< Destroy span I/O */ - fio_get_alarms_t get_alarms; /*!< Get hardware alarms */ - fio_command_t command; /*!< Execute an I/O command on the channel */ - fio_wait_t wait; /*!< Wait for events on the channel */ - fio_read_t read; /*!< Read data from the channel */ - fio_write_t write; /*!< Write data to the channel */ - fio_span_poll_event_t poll_event; /*!< Poll for events on the whole span */ - fio_span_next_event_t next_event; /*!< Retrieve an event from the span */ - fio_channel_next_event_t channel_next_event; /*!< Retrieve an event from channel */ - fio_api_t api; /*!< Execute a text command */ - fio_span_start_t span_start; /*!< Start span I/O */ - fio_span_stop_t span_stop; /*!< Stop span I/O */ -}; - -/*! \brief FreeTDM supported I/O codecs */ -typedef enum { - FTDM_CODEC_ULAW = 0, - FTDM_CODEC_ALAW = 8, - FTDM_CODEC_SLIN = 10, - FTDM_CODEC_NONE = (1 << 30) -} ftdm_codec_t; - -/*! \brief FreeTDM supported hardware alarms. */ -typedef enum { - FTDM_ALARM_NONE = 0, - FTDM_ALARM_RED = (1 << 0), - FTDM_ALARM_YELLOW = (1 << 1), - FTDM_ALARM_RAI = (1 << 2), - FTDM_ALARM_BLUE = (1 << 3), - FTDM_ALARM_AIS = (1 << 4), - FTDM_ALARM_GENERAL = (1 << 30) -} ftdm_alarm_flag_t; - -/*! \brief MF generation direction flags - * \note Used in bitwise OR with channel ID as argument to MF_PLAYBACK I/O command, so value must be higher that 255 - * \see FTDM_COMMAND_START_MF_PLAYBACK - * */ - -typedef enum { - FTDM_MF_DIRECTION_FORWARD = (1 << 8), - FTDM_MF_DIRECTION_BACKWARD = (1 << 9) -} ftdm_mf_direction_flag_t; - -/*! \brief IO Error statistics */ -typedef enum { - FTDM_IOSTATS_ERROR_CRC = (1 << 0), - FTDM_IOSTATS_ERROR_FRAME = (1 << 1), - FTDM_IOSTATS_ERROR_ABORT = (1 << 2), - FTDM_IOSTATS_ERROR_FIFO = (1 << 3), - FTDM_IOSTATS_ERROR_DMA = (1 << 4), - FTDM_IOSTATS_ERROR_QUEUE_THRES = (1 << 5), /* Queue reached high threshold */ - FTDM_IOSTATS_ERROR_QUEUE_FULL = (1 << 6), /* Queue is full */ -} ftdm_iostats_error_type_t; - -/*! \brief IO statistics */ -typedef struct { - struct { - uint64_t packets; - uint32_t errors; - uint16_t flags; - uint8_t queue_size; /*!< max queue size configured */ - uint8_t queue_len; /*!< Current number of elements in queue */ - } rx; - - struct { - uint64_t idle_packets; - uint64_t packets; - uint32_t errors; - uint16_t flags; - uint8_t queue_size; /*!< max queue size configured */ - uint8_t queue_len; /*!< Current number of elements in queue */ - } tx; -} ftdm_channel_iostats_t; - -/*! \brief Override the default queue handler */ -FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *handler); - -/*! \brief Return the availability rate for a channel - * \param ftdmchan Channel to get the availability from - * - * \retval > 0 if availability is supported - * \retval -1 if availability is not supported - */ -FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan); - -/*! \brief Answer call. This can also be accomplished by ftdm_channel_call_indicate with FTDM_CHANNEL_INDICATE_ANSWER, in both - * cases you will get a FTDM_SIGEVENT_INDICATION_COMPLETED when the indication is sent (or an error occurs). - * Just as with ftdm_channel_call_indicate you won't receive FTDM_SIGEVENT_INDICATION_COMPLETED when this function - * returns anything else than FTDM_SUCCESS - * \note Although this API may result in FTDM_SIGEVENT_INDICATION_COMPLETED event being delivered, - * there is no guarantee of whether the event will arrive after or before your execution thread returns - * from ftdm_channel_call_answer - */ -#define ftdm_channel_call_answer(ftdmchan) _ftdm_channel_call_answer(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), NULL) -#define ftdm_channel_call_answer_ex(ftdmchan, usrmsg) _ftdm_channel_call_answer(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (usrmsg)) - -/*! \brief Answer call recording the source code point where the it was called (see ftdm_channel_call_answer for an easy to use macro) */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg); - -/*! \brief Place an outgoing call in the given channel - * \deprecated This macro is deprecated since leaves the door open to glare issues, use ftdm_call_place instead - */ -#define ftdm_channel_call_place(ftdmchan) _ftdm_channel_call_place(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), NULL) -#define ftdm_channel_call_place_ex(ftdmchan, usrmsg) _ftdm_channel_call_place_ex(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (usrmsg)) - -/*! \brief Place an outgoing call recording the source code point where it was called (see ftdm_channel_call_place for an easy to use macro) - * \deprecated This function is deprecated since leaves the door open to glare issues, use ftdm_call_place instead - */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg); - -/*! \brief Place an outgoing call with the given caller data in a channel according to the hunting scheme provided */ -#define ftdm_call_place(callerdata, hunting) _ftdm_call_place(__FILE__, __FTDM_FUNC__, __LINE__, (callerdata), (hunting), NULL) -#define ftdm_call_place_ex(callerdata, hunting, usrmsg) _ftdm_call_place(__FILE__, __FTDM_FUNC__, __LINE__, (callerdata), (hunting), (usrmsg)) - -/*! \brief Place an outgoing call with the given caller data in a channel according to the hunting scheme provided and records - * the place where it was called. See ftdm_call_place for an easy to use macro - * \return FTDM_SUCCESS if the call attempt was successful - * FTDM_FAIL if there was an unspecified error - * FTDM_EBUSY if the channel was busy - * FTDM_BREAK if glare was detected and you must try again - * \note Even when FTDM_SUCCESS is returned, the call may still fail later on due to glare, in such case FTDM_SIGEVENT_STOP - * will be sent with the hangup cause field set to FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL - * - * \note When this function returns FTDM_SUCCESS, the member .fchan from caller_data will be set to the channel used to place the call - * and .call_id to the generated call id for that call - * - * \note When this function is successful you are guaranteed to receive FTDM_SIGEVENT_DIALING, this event could even be delivered - * before your execution thread returns from this function - */ -FT_DECLARE(ftdm_status_t) _ftdm_call_place(const char *file, const char *func, int line, ftdm_caller_data_t *caller_data, ftdm_hunting_scheme_t *hunting, ftdm_usrmsg_t *usrmsg); - -/*! \brief Indicate a new condition in an incoming call - * - * \note Every indication request will result in FTDM_SIGEVENT_INDICATION_COMPLETED event being delivered with - * the proper status that will inform you if the request was successful or not. The exception is if this - * function returns something different to FTDM_SUCCESS, in which case the request failed right away and no - * further FTDM_SIGEVENT_INDICATION_COMPLETED will be delivered - * Be aware there is no guarantee of whether the completion event will arrive after or before your execution - * thread returns from ftdm_channel_call_indicate. This means you could get FTDM_SIGEVENT_INDICATION_COMPLETED - * even before your execution thread returns from the ftdm_channel_call_indicate() API - * - * \note You cannot send more than one indication at the time. You must wait for the completed event before - * calling this function again (unless the return code was different than FTDM_SUCCESS) - */ -#define ftdm_channel_call_indicate(ftdmchan, indication) _ftdm_channel_call_indicate(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (indication), NULL) -#define ftdm_channel_call_indicate_ex(ftdmchan, indication, usrmsg) _ftdm_channel_call_indicate(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (indication), (usrmsg)) - -/*! \brief Indicate a new condition in an incoming call recording the source code point where it was called (see ftdm_channel_call_indicate for an easy to use macro) */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_usrmsg_t *usrmsg); - -/*! \brief Hangup the call without cause */ -#define ftdm_channel_call_hangup(ftdmchan) _ftdm_channel_call_hangup(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), NULL) -#define ftdm_channel_call_hangup_ex(ftdmchan, usrmsg) _ftdm_channel_call_hangup(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (usrmsg)) - -/*! \brief Hangup the call without cause recording the source code point where it was called (see ftdm_channel_call_hangup for an easy to use macro)*/ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg); - -/*! \brief Hangup the call with cause */ -#define ftdm_channel_call_hangup_with_cause(ftdmchan, cause) _ftdm_channel_call_hangup_with_cause(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (cause), NULL) -#define ftdm_channel_call_hangup_with_cause_ex(ftdmchan, cause, usrmsg) _ftdm_channel_call_hangup_with_cause(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (cause), (usrmsg)) - -/*! \brief Hangup the call with cause recording the source code point where it was called (see ftdm_channel_call_hangup_with_cause for an easy to use macro) */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t, ftdm_usrmsg_t *usrmsg); - -/*! \brief Transfer call. This can also be accomplished by ftdm_channel_call_indicate with FTDM_CHANNEL_INDICATE_TRANSFER, in both - * cases you will get a FTDM_SIGEVENT_INDICATION_COMPLETED when the indication is sent (or an error occurs). - * Just as with ftdm_channel_call_indicate you won't receive FTDM_SIGEVENT_INDICATION_COMPLETED when this function - * returns anything else than FTDM_SUCCESS - * \note Although this API may result in FTDM_SIGEVENT_INDICATION_COMPLETED event being delivered, - * there is no guarantee of whether the event will arrive after or before your execution thread returns - * from ftdm_channel_call_transfer - */ -#define ftdm_channel_call_transfer(ftdmchan, arg) _ftdm_channel_call_transfer(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (arg), NULL) -#define ftdm_channel_call_transfer_ex(ftdmchan, arg, usrmsg) _ftdm_channel_call_transfer(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (arg), (usrmsg)) - -/*! \brief Answer call recording the source code point where the it was called (see ftdm_channel_call_tranasfer for an easy to use macro) */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_transfer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, const char* arg, ftdm_usrmsg_t *usrmsg); - -/*! \brief Reset the channel */ -#define ftdm_channel_reset(ftdmchan) _ftdm_channel_reset(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), NULL) -#define ftdm_channel_reset_ex(ftdmchan, usrmsg) _ftdm_channel_reset(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), usrmsg) - -/*! \brief Reset the channel (see _ftdm_channel_reset for an easy to use macro) - * \note if there was a call on this channel, call will be cleared without any notifications to the user - */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg); - -/*! \brief Put a call on hold (if supported by the signaling stack) */ -#define ftdm_channel_call_hold(ftdmchan) _ftdm_channel_call_hold(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), NULL) -#define ftdm_channel_call_hold_ex(ftdmchan, usrmsg) _ftdm_channel_call_hold(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (usrmsg)) - -/*! \brief Put a call on hold recording the source code point where it was called (see ftdm_channel_call_hold for an easy to use macro) */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg); - -/*! \brief Unhold a call */ -#define ftdm_channel_call_unhold(ftdmchan) _ftdm_channel_call_unhold(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), NULL) -#define ftdm_channel_call_unhold_ex(ftdmchan, usrmsg) _ftdm_channel_call_unhold(__FILE__, __FTDM_FUNC__, __LINE__, (ftdmchan), (usrmsg)) - -/*! \brief Unhold a call recording the source code point where it was called (see ftdm_channel_call_unhold for an easy to use macro) */ -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg); - -/*! \brief Check if the call is answered already */ -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_answered(const ftdm_channel_t *ftdmchan); - -/*! \brief Check if the call is busy */ -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_busy(const ftdm_channel_t *ftdmchan); - -/*! \brief Check if the call is hangup */ -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_hangup(const ftdm_channel_t *ftdmchan); - -/*! \brief Check if the call is done (final state for a call, just after hangup) */ -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_done(const ftdm_channel_t *ftdmchan); - -/*! \brief Check if the call is in hold */ -FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_hold(const ftdm_channel_t *ftdmchan); - -/*! \brief Set channel signaling status (ie: put specific circuit down) only if supported by the signaling */ -FT_DECLARE(ftdm_status_t) ftdm_channel_set_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status); - -/*! \brief Get channel signaling status (ie: whether protocol layer is up or down) */ -FT_DECLARE(ftdm_status_t) ftdm_channel_get_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *status); - -/*! \brief Set span signaling status (ie: put the whole span protocol layer down) only if supported by the signaling */ -FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signaling_status_t status); - -/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */ -FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status); - - -/*! - * \brief Set user private data in the channel - * - * \param ftdmchan The channel where the private data will be stored - * \param pvt The private pointer to store - * - */ -FT_DECLARE(void) ftdm_channel_set_private(ftdm_channel_t *ftdmchan, void *pvt); - -/*! - * \brief Get user private data in the channel - * - * \param ftdmchan The channel to retrieve the private data - * \retval The private data (if any or NULL if no data has been stored) - * - */ -FT_DECLARE(void *) ftdm_channel_get_private(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Remove the given token from the channel - * - * \param ftdmchan The channel where the token is - * \param token The token string. If NULL, all tokens in the channel are cleared - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_clear_token(ftdm_channel_t *ftdmchan, const char *token); - -/*! - * \brief Replace the given token with the new token - * - * \param ftdmchan The channel where the token is - * \param old_token The token to replace - * \param new_token The token to put in place - */ -FT_DECLARE(void) ftdm_channel_replace_token(ftdm_channel_t *ftdmchan, const char *old_token, const char *new_token); - -/*! - * \brief Add a new token to the channel - * - * \param ftdmchan The channel where the token will be added - * \param token The token string to add - * \param end if 0, the token will be added at the beginning of the token list, to the end otherwise - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_add_token(ftdm_channel_t *ftdmchan, char *token, int end); - -/*! - * \brief Get the requested token - * - * \param ftdmchan The channel where the token is - * \param tokenid The id of the token - * - * \retval The token character string - * \retval NULL token not found - */ -FT_DECLARE(const char *) ftdm_channel_get_token(const ftdm_channel_t *ftdmchan, uint32_t tokenid); - -/*! - * \brief Get the token count - * - * \param ftdmchan The channel to get the token count from - * - * \retval The token count - */ -FT_DECLARE(uint32_t) ftdm_channel_get_token_count(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Get the I/O read/write interval - * - * \param ftdmchan The channel to get the interval from - * - * \retval The interval in milliseconds - */ -FT_DECLARE(uint32_t) ftdm_channel_get_io_interval(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Get the I/O read/write packet length per interval - * - * \param ftdmchan The channel to get the packet length from - * - * \retval The packet length interval in bytes - */ -FT_DECLARE(uint32_t) ftdm_channel_get_io_packet_len(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Get the I/O read/write codec - * - * \param ftdmchan The channel to get the codec from - * - * \retval The codec type - */ -FT_DECLARE(ftdm_codec_t) ftdm_channel_get_codec(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Get the last error string for the channel - * - * \deprecated This API will disappear in the future and not every - * FreeTDM API set the last error value - * - * \param ftdmchan The channel to get the error from - * - * \retval The error string (not thread-safe, the string is per channel, not per thread) - */ -FT_DECLARE(const char *) ftdm_channel_get_last_error(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Get the current alarm bitmask for the channel - * - * \param ftdmchan The channel to get the alarm bitmask from - * \param alarmbits The alarm bitmask pointer to store the current alarms (you are responsible for allocation/deallocation) - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_get_alarms(ftdm_channel_t *ftdmchan, ftdm_alarm_flag_t *alarmbits); - -/*! - * \brief Get the channel type - * - * \param ftdmchan The channel to get the type from - * - * \retval channel type (FXO, FXS, B-channel, D-channel, etc) - */ -FT_DECLARE(ftdm_chan_type_t) ftdm_channel_get_type(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Dequeue DTMF from the given channel - * \note To transmit DTMF use ftdm_channel_command with command FTDM_COMMAND_SEND_DTMF - * - * \param ftdmchan The channel to dequeue DTMF from - * \param dtmf DTMF buffer to store the dtmf (you are responsible for its allocation and deallocation) - * \param len The size of the provided DTMF buffer - * - * \retval The size of the dequeued DTMF (it might be zero if there is no DTMF in the queue) - */ -FT_DECLARE(ftdm_size_t) ftdm_channel_dequeue_dtmf(ftdm_channel_t *ftdmchan, char *dtmf, ftdm_size_t len); - -/*! - * \brief Flush the DTMF queue - * - * \param ftdmchan The channel to flush the dtmf queue of - */ -FT_DECLARE(void) ftdm_channel_flush_dtmf(ftdm_channel_t *ftdmchan); - -/*! - * \brief Wait for an event in the span - * - * \param span The span to wait events for - * \param ms Milliseconds timeout - * \param poll_events Array of events to poll for, for each channel on the span - * - * \retval FTDM_SUCCESS success (at least one event available) - * \retval FTDM_TIMEOUT Timed out waiting for events - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_span_poll_event(ftdm_span_t *span, uint32_t ms, short *poll_events); - -/*! - * \brief Find a span by its id - * - * \param id The span id - * \param span Pointer to store the span if found - * - * \retval FTDM_SUCCESS success (span is valid) - * \retval FTDM_FAIL failure (span is not valid) - */ -FT_DECLARE(ftdm_status_t) ftdm_span_find(uint32_t id, ftdm_span_t **span); - -/*! - * \brief Get the last error string for the given span - * - * \deprecated This API will disappear in the future and not every - * FreeTDM API set the last error value - * - * \param span The span to get the last error from - * - * \retval character string for the last error - */ -FT_DECLARE(const char *) ftdm_span_get_last_error(const ftdm_span_t *span); - -/*! - * \brief Create a new span (not needed if you are using freetdm.conf) - * - * \param iotype The I/O interface type this span will use. - * This depends on the available I/O modules - * ftmod_wanpipe = "wanpipe" (Sangoma) - * ftmod_zt = "zt" (DAHDI or Zaptel) - * ftmod_pika "pika" (this one is most likely broken) - * \param name Name for the span - * \param span Pointer to store the create span - * - * \retval FTDM_SUCCESS success (the span was created) - * \retval FTDM_FAIL failure (span was not created) - */ -FT_DECLARE(ftdm_status_t) ftdm_span_create(const char *iotype, const char *name, ftdm_span_t **span); - -/*! - * \brief Add a new channel to a span - * - * \param span Where to add the new channel - * \param sockfd The socket device associated to the channel (ie: sangoma device, dahdi device etc) - * \param type Channel type - * \param chan Pointer to store the newly allocated channel - * - * \retval FTDM_SUCCESS success (the channel was created) - * \retval FTDM_FAIL failure (span was not created) - */ -FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t sockfd, ftdm_chan_type_t type, ftdm_channel_t **chan); - -/*! \brief Add the channel to a hunt group */ -FT_DECLARE(ftdm_status_t) ftdm_channel_add_to_group(const char* name, ftdm_channel_t* ftdmchan); - -/*! \brief Remove the channel from a hunt group */ -FT_DECLARE(ftdm_status_t) ftdm_channel_remove_from_group(ftdm_group_t* group, ftdm_channel_t* ftdmchan); - -/*! - * \brief Retrieves an event from the span - * - * \note - * This function is non-reentrant and not thread-safe. - * The event returned may be modified if the function is called again - * from a different thread or even the same. It is recommended to - * handle events from the same span in a single thread. - * - * \param ftdmchan The channel to retrieve the event from - * \param event Pointer to store the pointer to the event - * - * \retval FTDM_SUCCESS success (at least one event available) - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm_event_t **event); - -/*! \brief Find a hunt group by id */ -FT_DECLARE(ftdm_status_t) ftdm_group_find(uint32_t id, ftdm_group_t **group); - -/*! \brief Find a hunt group by name */ -FT_DECLARE(ftdm_status_t) ftdm_group_find_by_name(const char *name, ftdm_group_t **group); - -/*! \brief Create a group with the given name */ -FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *name); - -/*! \brief Get the number of channels in use on a span */ -FT_DECLARE(ftdm_status_t) ftdm_span_channel_use_count(ftdm_span_t *span, uint32_t *count); - -/*! \brief Get the number of channels in use on a group */ -FT_DECLARE(ftdm_status_t) ftdm_group_channel_use_count(ftdm_group_t *group, uint32_t *count); - -/*! \brief Get the id of a group */ -FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group); - -/*! - * \brief Open a channel specifying the span id and chan id (required before placing a call on the channel) - * - * \warning Try using ftdm_call_place instead if you plan to place a call after opening the channel - * - * \note You must call ftdm_channel_close() or ftdm_channel_call_hangup() to release the channel afterwards - * Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel - * - * \param span_id The span id the channel belongs to - * \param chan_id Logical channel id of the channel you want to open - * \param ftdmchan Pointer to store the channel once is open - * - * \retval FTDM_SUCCESS success (the channel was found and is available) - * \retval FTDM_FAIL failure (channel was not found or not available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan); - -/*! - * \brief Open a channel specifying the span id and physical chan id (required before placing a call on the channel) - * - * \warning Try using ftdm_call_place instead if you plan to place a call after opening the channel - * - * \note You must call ftdm_channel_close() or ftdm_channel_call_hangup() to release the channel afterwards - * Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel - * - * \param span_id The span id the channel belongs to - * \param chan_id Physical channel id of the channel you want to open - * \param ftdmchan Pointer to store the channel once is open - * - * \retval FTDM_SUCCESS success (the channel was found and is available) - * \retval FTDM_FAIL failure (channel was not found or not available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan); - -/*! - * \brief Hunts and opens a channel specifying the span id only - * - * \warning Try using ftdm_call_place instead if you plan to place a call after opening the channel - * - * \note You must call ftdm_channel_close() or ftdm_channel_call_hangup() to release the channel afterwards - * Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel - * - * \param span_id The span id to hunt for a channel - * \param direction The hunting direction - * \param caller_data The calling party information - * \param ftdmchan The channel pointer to store the available channel - * - * \retval FTDM_SUCCESS success (a suitable channel was found available) - * \retval FTDM_FAIL failure (no suitable channel was found available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_hunt_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan); - -/*! - * \brief Hunts and opens a channel specifying group id - * - * \warning Try using ftdm_call_place instead if you plan to place a call after opening the channel - * - * \note You must call ftdm_channel_close() or ftdm_channel_call_hangup() to release the channel afterwards - * Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel - * - * \param group_id The group id to hunt for a channel - * \param direction The hunting direction - * \param caller_data The calling party information - * \param ftdmchan The channel pointer to store the available channel - * - * \retval FTDM_SUCCESS success (a suitable channel was found available) - * \retval FTDM_FAIL failure (no suitable channel was found available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_hunt_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan); - -/*! - * \brief Close a previously open channel - * - * \warning FreeTDM is more and more a signaling API rather than just a plane IO API, unless you are using - * FreeTDM as a pure IO API without its signaling modules, you should not use this function - * - * \note If you placed a call in this channel use ftdm_channel_call_hangup(), you MUST NOT call this function, - * the signaling stack will close the channel when the call is done. - * - * \param ftdmchan pointer to the channel to close - * - * \retval FTDM_SUCCESS success (a suitable channel was found available) - * \retval FTDM_FAIL failure (no suitable channel was found available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan); - -/*! - * \brief Execute a command in a channel (same semantics as the ioctl() unix system call) - * - * \param ftdmchan The channel to execute the command - * \param command The command to execute - * \param arg The argument for the command - * - * \retval FTDM_SUCCESS success (a suitable channel was found available) - * \retval FTDM_FAIL failure (no suitable channel was found available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_command_t command, void *arg); - -/*! - * \brief Wait for I/O events in a channel - * - * \param ftdmchan The channel to wait I/O for - * \param flags The wait I/O flags - * \param timeout The timeout in milliseconds - * - * \retval FTDM_SUCCESS success (a suitable channel was found available) - * \retval FTDM_FAIL failure (no suitable channel was found available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_wait(ftdm_channel_t *ftdmchan, ftdm_wait_flag_t *flags, int32_t timeout); - -/*! - * \brief Read data from a channel - * - * \param ftdmchan The channel to read data from - * \param data The pointer to the buffer to store the read data - * \param datalen The size in bytes of the provided buffer - * - * \retval FTDM_SUCCESS success (a suitable channel was found available) - * \retval FTDM_FAIL failure (no suitable channel was found available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen); - -/*! - * \brief Write data to a channel - * - * \note The difference between data and datasize is subtle but important. - * - * datalen is a pointer to the size of the actual data that you want to write. This pointer - * will be updated with the number of bytes actually written. - * - * datasize on the other hand is the size of the entire buffer provided in data, whether - * all of that buffer is in use or not is a different matter. The difference becomes - * important only if you are using FreeTDM doing transcoding, for example, providing - * a ulaw frame of 160 bytes but where the I/O device accepts input in signed linear, - * the data to write will be 320 bytes, therefore datasize is expected to be at least - * 320 where datalen would be just 160. - * - * \param ftdmchan The channel to write data to - * \param data The pointer to the buffer to write - * \param datasize The maximum number of bytes in data that can be used (in case transcoding is necessary) - * \param datalen The size of the actual data - * - * \retval FTDM_SUCCESS success (a suitable channel was found available) - * \retval FTDM_FAIL failure (no suitable channel was found available) - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t datasize, ftdm_size_t *datalen); - -/*! \brief Get a custom variable from the sigmsg - * \note The variable pointer returned is only valid while the before the event is processed and it'll be destroyed once the event is processed. */ -FT_DECLARE(const char *) ftdm_sigmsg_get_var(ftdm_sigmsg_t *sigmsg, const char *var_name); - -/*! \brief Get an iterator to iterate over the sigmsg variables - * \param sigmsg The message structure containing the variables - * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. - * \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. - * This iterator is completely non-thread safe, if you are adding variables or removing variables while iterating - * results are unpredictable - */ -FT_DECLARE(ftdm_iterator_t *) ftdm_sigmsg_get_var_iterator(const ftdm_sigmsg_t *sigmsg, ftdm_iterator_t *iter); - -/*! \brief Get raw data from sigmsg - * \param sigmsg The message structure containing the variables - * \param data data will point to available data pointer if available - * \param datalen datalen will be set to length of data available - * \retval FTDM_SUCCESS data is available - * \retval FTDM_FAIL no data available - * \note data is only valid within the duration of the callback, to receive a data pointer that does not get - * \note destroyed when callback returns, see ftdm_sigmsg_get_raw_data_detached - */ -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_get_raw_data(ftdm_sigmsg_t *sigmsg, void **data, ftdm_size_t *datalen); - -/*! \brief Get raw data from event - * \param sigmsg The message structure containing the variables - * \param data data will point to available data pointer if available - * \param datalen datalen will be set to length of data available - * \retval FTDM_SUCCESS data is available - * \retval FTDM_FAIL no data available - * \note Once this function returns, User owns data, and is responsible to free data using ftdm_safe_free(); - */ -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_get_raw_data_detached(ftdm_sigmsg_t *sigmsg, void **data, ftdm_size_t *datalen); - -/*! \brief Add a custom variable to the user message - * \note This variables may be used by signaling modules to override signaling parameters - * \todo Document which signaling variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_add_var(ftdm_usrmsg_t *usrmsg, const char *var_name, const char *value); - -/*! \brief Attach raw data to usrmsg - * \param usrmsg The message structure containing the variables - * \param data pointer to data - * \param datalen datalen length of data - * \retval FTDM_SUCCESS success, data was successfully saved - * \retval FTDM_FAIL failed, event already had data attached to it. - * \note data must have been allocated using ftdm_calloc, FreeTDM will free data once the usrmsg is processed. - */ -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_set_raw_data(ftdm_usrmsg_t *usrmsg, void *data, ftdm_size_t datalen); - -/*! \brief Get iterator current value (depends on the iterator type) - * \note Channel iterators return a pointer to ftdm_channel_t - * Span iterators return a pointer to ftdm_span_t - * Variable iterators return a pointer to the variable name (not the variable value) - */ -FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter); - -/*! \brief Get variable name and value for the current iterator position */ -FT_DECLARE(ftdm_status_t) ftdm_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val); - -/*! \brief Advance iterator */ -FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter); - -/*! \brief Free iterator - * \note You must free an iterator after using it unless you plan to reuse it - */ -FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter); - -/*! \brief Get the span pointer associated to the channel */ -FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan); - -/*! \brief Get the span pointer associated to the channel */ -FT_DECLARE(uint32_t) ftdm_channel_get_span_id(const ftdm_channel_t *ftdmchan); - -/*! \brief Get the physical span id associated to the channel */ -FT_DECLARE(uint32_t) ftdm_channel_get_ph_span_id(const ftdm_channel_t *ftdmchan); - -/*! \brief Get the span name associated to the channel */ -FT_DECLARE(const char *) ftdm_channel_get_span_name(const ftdm_channel_t *ftdmchan); - -/*! \brief Get the id associated to the channel */ -FT_DECLARE(uint32_t) ftdm_channel_get_id(const ftdm_channel_t *ftdmchan); - -/*! \brief Get the name associated to the channel */ -FT_DECLARE(const char *) ftdm_channel_get_name(const ftdm_channel_t *ftdmchan); - -/*! \brief Get the number associated to the channel */ -FT_DECLARE(const char *) ftdm_channel_get_number(const ftdm_channel_t *ftdmchan); - -/*! \brief Get the number physical id associated to the channel */ -FT_DECLARE(uint32_t) ftdm_channel_get_ph_id(const ftdm_channel_t *ftdmchan); - -/*! - * \brief Configure span with a signaling type - * - * \deprecated use ftdm_configure_span_signaling instead - * - * \note This function does the same as ftdm_configure_span_signaling - * - * \param span The span to configure - * \param type The signaling type ("boost", "isdn" and others, this depends on the available signaling modules) - * \param sig_cb The callback that the signaling stack will use to notify about events - * \param ... variable argument list with "var", value sequence, the variable and values are signaling type dependant - * the last argument must be FTDM_TAG_END - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_configure_span(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ...); -#define FTDM_TAG_END NULL - - -/*! - * \brief Configure span with a signaling type - * - * \param span The span to configure - * \param type The signaling type ("boost", "isdn" and others, this depends on the available signaling modules) - * \param sig_cb The callback that the signaling stack will use to notify about events - * \param parameters The array if signaling-specific parameters (the last member of the array MUST have its var member set to NULL, ie: .var = NULL) - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *parameters); - -/*! - * \brief Register callback to listen for incoming events - * \note This function should only be used when there is no signalling module - * \param span The span to register to - * \param sig_cb The callback that the signaling stack will use to notify about events - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb); - -/*! - * \brief Start the span signaling (must call ftdm_configure_span_signaling first) - * - * \note Even before this function returns you may receive signaling events! - * Never block in the signaling callback since it might be called in a thread - * that handles more than 1 call and therefore you would be blocking all the - * calls handled by that thread! - * - * \param span The span to start - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span); - -/*! - * \brief Stop the span signaling (must call ftdm_span_start first) - * \note certain signalings (boost signaling) does not support granular span start/stop - * so it is recommended to always configure all spans and then starting them all and finally - * stop them all (or call ftdm_global_destroy which takes care of stopping and destroying the spans at once). - * - * \param span The span to stop - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span); - -/*! - * \brief Register a custom I/O interface with the FreeTDM core - * - * \param io_interface the Interface to register - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_global_add_io_interface(ftdm_io_interface_t *io_interface); - -/** - * Get I/O interface by name - * - * \param iotype Name of interface - * \param autoload Try to load missing plugins - * \retval I/O interface handle on success - * \retval NULL on failure - */ -FT_DECLARE(ftdm_io_interface_t *) ftdm_global_get_io_interface(const char *iotype, ftdm_bool_t autoload); - -/*! \brief Find a span by name */ -FT_DECLARE(ftdm_status_t) ftdm_span_find_by_name(const char *name, ftdm_span_t **span); - -/*! \brief Get the span id */ -FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span); - -/*! \brief Get the span name */ -FT_DECLARE(const char *) ftdm_span_get_name(const ftdm_span_t *span); - -/*! \brief Get iterator for the span channels - * \param span The span containing the channels - * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. - */ -FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter); - -/*! \brief Get iterator for spans - * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. - */ -FT_DECLARE(ftdm_iterator_t *) ftdm_get_span_iterator(ftdm_iterator_t *iter); - -/*! - * \brief Execute a text command. The text command output will be returned and must be free'd - * - * \param cmd The command to execute - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(char *) ftdm_api_execute(const char *cmd); - -/*! - * \brief Create a configuration node - * - * \param name The name of the configuration node - * \param node The node pointer to store the new node - * \param parent The parent node if any, or NULL if no parent - * - * \return FTDM_SUCCESS success - * \return FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node_t **node, ftdm_conf_node_t *parent); - -/*! - * \brief Adds a new parameter to the specified configuration node - * - * \param node The configuration node to add the param-val pair to - * \param param The parameter name - * \param val The parameter value - * - * \return FTDM_SUCCESS success - * \return FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_conf_node_add_param(ftdm_conf_node_t *node, const char *param, const char *val); - -/*! - * \brief Destroy the memory allocated for a configuration node (and all of its descendance) - * - * \param node The node to destroy - * - * \return FTDM_SUCCESS success - * \return FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node); - -/*! - * \brief Create and configure channels in the given span - * - * \param span The span container - * \param str The channel range null terminated string. "1-10", "24" etc - * \param chan_config The basic channel configuration for each channel within the range - * \param configured Pointer where the number of channels configured will be stored - * - * \return FTDM_SUCCESS success - * \return FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const char *str, ftdm_channel_config_t *chan_config, unsigned *configured); - -/*! - * \brief Set the trunk type for a span - * This must be called before configuring any channels within the span - * - * \param span The span - * \param type The trunk type - * - */ -FT_DECLARE(void) ftdm_span_set_trunk_type(ftdm_span_t *span, ftdm_trunk_type_t type); - -/*! - * \brief Get the trunk type for a span - * - * \param span The span - * - * \return The span trunk type - */ -FT_DECLARE(ftdm_trunk_type_t) ftdm_span_get_trunk_type(const ftdm_span_t *span); - -/*! \brief For display debugging purposes you can display this string which describes the trunk type of a span */ -FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span); - -/*! - * Set the trunk mode for a span - * \note This must be called before configuring any channels within the span! - * \param[in] span The span - * \param[in] type The trunk mode - */ -FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode); - -/*! - * Get the trunk mode for a span - * \param[in] span The span - * \return Span trunk mode - */ -FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span); - -/*! - * Get the trunk mode of a span in textual form - * \param[in] span The span - * \return Span mode name as a string - */ -FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span); - -/*! - * \brief Return the channel identified by the provided logical id - * - * \param span The span where the channel belongs - * \param chanid The logical channel id within the span - * - * \return The channel pointer if found, NULL otherwise - */ -FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint32_t chanid); - -/*! - * \brief Return the channel identified by the provided physical id - * - * \param span The span where the channel belongs - * \param chanid The physical channel id within the span - * - * \return The channel pointer if found, NULL otherwise - */ -FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid); - -/*! \brief Return the channel count number for the given span */ -FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span); - -/*! \brief Set the caller data for a channel. Be sure to call this before ftdm_channel_call_place() */ -FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data); - -/*! \brief Get the caller data for a channel, typically you need this when receiving FTDM_SIGEVENT_START */ -FT_DECLARE(ftdm_caller_data_t *) ftdm_channel_get_caller_data(ftdm_channel_t *channel); - -/*! \brief Get current state of a channel */ -FT_DECLARE(int) ftdm_channel_get_state(const ftdm_channel_t *ftdmchan); - -/*! \brief Get last state of a channel */ -FT_DECLARE(int) ftdm_channel_get_last_state(const ftdm_channel_t *ftdmchan); - -/*! \brief For display debugging purposes you can display this string which describes the current channel internal state */ -FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *channel); - -/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */ -FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *channel); - -/*! \brief For display debugging purposes you can display this string which describes the history of the channel - * \param channel The channel to get the history from - * \return History string for the channel. You must free the string with ftdm_free - */ -FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *channel); - -/*! \brief Enable/disable blocking mode in the channels for this span */ -FT_DECLARE(ftdm_status_t) ftdm_span_set_blocking_mode(const ftdm_span_t *span, ftdm_bool_t enabled); - -/*! \brief Initialize the library */ -FT_DECLARE(ftdm_status_t) ftdm_global_init(void); - -/*! \brief Create spans and channels reading the freetdm.conf file */ -FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void); - -/*! \brief Shutdown the library */ -FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void); - -/*! \brief Set memory handler for the library */ -FT_DECLARE(ftdm_status_t) ftdm_global_set_memory_handler(ftdm_memory_handler_t *handler); - -/*! \brief Set the crash policy for the library */ -FT_DECLARE(void) ftdm_global_set_crash_policy(ftdm_crash_policy_t policy); - -/*! \brief Set the logger handler for the library */ -FT_DECLARE(void) ftdm_global_set_logger(ftdm_logger_t logger); - -/*! \brief Set the default logger level */ -FT_DECLARE(void) ftdm_global_set_default_logger(int level); - -/*! \brief Set the directory to look for modules */ -FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path); - -/*! \brief Set the directory to look for configs */ -FT_DECLARE(void) ftdm_global_set_config_directory(const char *path); - -/*! \brief Check if the FTDM library is initialized and running */ -FT_DECLARE(ftdm_bool_t) ftdm_running(void); - -/** - * Generate a stack trace and invoke a callback function for each entry - * \param[in] callback Callback function, that is invoked for each stack symbol - * \param[in] priv (User-)Private data passed to the callback - * \retval - * FTDM_SUCCESS On success - * FTDM_NOTIMPL Backtraces are not available - * FTDM_EINVAL Invalid arguments (callback was NULL) - */ -FT_DECLARE(ftdm_status_t) ftdm_backtrace_walk(void (* callback)(const int tid, const void *addr, const char *symbol, void *priv), void *priv); - -/** - * Convenience function to print a backtrace for a span. - * \note The backtrace is generated with FTDM_LOG_DEBUG log level. - * \param[in] span Span object - * \retval - * FTDM_SUCCESS On success - * FTDM_NOTIMPL Backtraces are not available - * FTDM_EINVAL Invalid arguments (e.g. span was NULL) - */ -FT_DECLARE(ftdm_status_t) ftdm_backtrace_span(ftdm_span_t *span); - -/** - * Convenience function to print a backtrace for a channel. - * \note The backtrace is generated with FTDM_LOG_DEBUG log level. - * \param[in] chan Channel object - * \retval - * FTDM_SUCCESS On success - * FTDM_NOTIMPL Backtraces are not available - * FTDM_EINVAL Invalid arguments (e.g. chan was NULL) - */ -FT_DECLARE(ftdm_status_t) ftdm_backtrace_chan(ftdm_channel_t *chan); - - -FT_DECLARE_DATA extern ftdm_logger_t ftdm_log; - -/*! \brief Basic transcoding function prototype */ -#define FIO_CODEC_ARGS (void *data, ftdm_size_t max, ftdm_size_t *datalen) -#define FIO_CODEC_FUNCTION(name) FT_DECLARE_NONSTD(ftdm_status_t) name FIO_CODEC_ARGS -typedef ftdm_status_t (*fio_codec_t) FIO_CODEC_ARGS ; - -/*! \brief Basic transcoding functions */ -FIO_CODEC_FUNCTION(fio_slin2ulaw); -FIO_CODEC_FUNCTION(fio_ulaw2slin); -FIO_CODEC_FUNCTION(fio_slin2alaw); -FIO_CODEC_FUNCTION(fio_alaw2slin); -FIO_CODEC_FUNCTION(fio_ulaw2alaw); -FIO_CODEC_FUNCTION(fio_alaw2ulaw); - -#define FTDM_PRE __FILE__, __func__, __LINE__ -#define FTDM_LOG_LEVEL_DEBUG 7 -#define FTDM_LOG_LEVEL_INFO 6 -#define FTDM_LOG_LEVEL_NOTICE 5 -#define FTDM_LOG_LEVEL_WARNING 4 -#define FTDM_LOG_LEVEL_ERROR 3 -#define FTDM_LOG_LEVEL_CRIT 2 -#define FTDM_LOG_LEVEL_ALERT 1 -#define FTDM_LOG_LEVEL_EMERG 0 - -/*! \brief Log levels */ -#define FTDM_LOG_DEBUG FTDM_PRE, FTDM_LOG_LEVEL_DEBUG -#define FTDM_LOG_INFO FTDM_PRE, FTDM_LOG_LEVEL_INFO -#define FTDM_LOG_NOTICE FTDM_PRE, FTDM_LOG_LEVEL_NOTICE -#define FTDM_LOG_WARNING FTDM_PRE, FTDM_LOG_LEVEL_WARNING -#define FTDM_LOG_ERROR FTDM_PRE, FTDM_LOG_LEVEL_ERROR -#define FTDM_LOG_CRIT FTDM_PRE, FTDM_LOG_LEVEL_CRIT -#define FTDM_LOG_ALERT FTDM_PRE, FTDM_LOG_LEVEL_ALERT -#define FTDM_LOG_EMERG FTDM_PRE, FTDM_LOG_LEVEL_EMERG - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/ftdm_call_utils.h b/libs/freetdm/src/include/ftdm_call_utils.h deleted file mode 100644 index 975e73e729..0000000000 --- a/libs/freetdm/src/include/ftdm_call_utils.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * Ricardo Barroetaveña - * - */ - -#ifndef __FTDM_CALL_UTILS_H__ -#define __FTDM_CALL_UTILS_H__ - -/*! - * \brief Set the Numbering Plan Identification from a string - * - * \param npi_string string value - * \param target the target to set value to - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *npi_string, uint8_t *target); - - -/*! - * \brief Set the Type of number from a string - * - * \param ton_string string value - * \param target the target to set value to - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_set_ton(const char *ton_string, uint8_t *target); - -/*! - * \brief Set the Bearer Capability from a string - * - * \param bc_string string value - * \param target the target to set value to - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_set_bearer_capability(const char *bc_string, uint8_t *target); - -/*! - * \brief Set the Bearer Capability - Layer 1 from a string - * - * \param bc_string string value - * \param target the target to set value to - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_set_bearer_layer1(const char *bc_string, uint8_t *target); - -/*! - * \brief Set the Screening Ind from a string - * - * \param screen_string string value - * \param target the target to set value to - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_set_screening_ind(const char *string, uint8_t *target); - - -/*! - * \brief Set the Presentation Ind from an enum - * - * \param screen_string string value - * \param target the target to set value to - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t *target); - - -/*! - * \brief Checks whether a string contains only numbers - * - * \param number string value - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number); - -/*! - * \brief Set the Calling Party Category from an enum - * - * \param cpc_string string value - * \param target the target to set value to - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target); - -/*! - * \brief URL encode a buffer - * - * \param url buffer to convert - * \param buf target to save converted string to - * \param len size of buffer - * - * \retval pointer to converted string - */ -FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len); - -/*! - * \param s buffer to convert - * \param len size of buffer - * - * \retval pointer to converted string - */ -FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len); - -#endif /* __FTDM_CALL_UTILS_H__ */ - diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h deleted file mode 100644 index 410944e7d3..0000000000 --- a/libs/freetdm/src/include/ftdm_declare.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __FTDM_DECLARE_H__ -#define __FTDM_DECLARE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) -#define _XOPEN_SOURCE 600 -#endif - -#ifndef HAVE_STRINGS_H -#define HAVE_STRINGS_H 1 -#endif -#ifndef HAVE_SYS_SOCKET_H -#define HAVE_SYS_SOCKET_H 1 -#endif - -#ifndef __WINDOWS__ -#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) -#define __WINDOWS__ -#endif -#endif - -#ifdef _MSC_VER -#define __FTDM_FUNC__ __FUNCTION__ -#if defined(FT_DECLARE_STATIC) -#define FT_DECLARE(type) type __stdcall -#define FT_DECLARE_NONSTD(type) type __cdecl -#define FT_DECLARE_DATA -#elif defined(FREETDM_EXPORTS) -#define FT_DECLARE(type) __declspec(dllexport) type __stdcall -#define FT_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl -#define FT_DECLARE_DATA __declspec(dllexport) -#else -#define FT_DECLARE(type) __declspec(dllimport) type __stdcall -#define FT_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl -#define FT_DECLARE_DATA __declspec(dllimport) -#endif -#define FT_DECLARE_INLINE(type) extern __inline__ type /* why extern? see http://support.microsoft.com/kb/123768 */ -#define EX_DECLARE_DATA __declspec(dllexport) -#else -#define __FTDM_FUNC__ (const char *)__func__ -#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(HAVE_VISIBILITY) -#define FT_DECLARE(type) __attribute__((visibility("default"))) type -#define FT_DECLARE_NONSTD(type) __attribute__((visibility("default"))) type -#define FT_DECLARE_DATA __attribute__((visibility("default"))) -#else -#define FT_DECLARE(type) type -#define FT_DECLARE_NONSTD(type) type -#define FT_DECLARE_DATA -#endif -#define FT_DECLARE_INLINE(type) __inline__ type -#define EX_DECLARE_DATA -#endif - -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif -#if (_MSC_VER >= 1400) /* VC8+ */ -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE -#endif -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE -#endif -#endif -#ifndef strcasecmp -#define strcasecmp(s1, s2) _stricmp(s1, s2) -#endif -#ifndef strncasecmp -#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) -#endif -#if _MSC_VER < 1900 -#define snprintf _snprintf -#endif -#ifndef S_IRUSR -#define S_IRUSR _S_IREAD -#endif -#ifndef S_IWUSR -#define S_IWUSR _S_IWRITE -#endif -#undef HAVE_STRINGS_H -#undef HAVE_SYS_SOCKET_H -/* disable warning for zero length array in a struct */ -/* this will cause errors on c99 and ansi compliant compilers and will need to be fixed in the wanpipe header files */ -#pragma warning(disable:4706) -#pragma comment(lib, "Winmm") -#endif - -/* - * Compiler-specific format checking attributes - * use these on custom functions that use printf/scanf-style - * format strings (e.g. ftdm_log()) - */ -#if defined(__GNUC__) -/** - * Enable compiler-specific printf()-style format and argument checks on a function - * @param fmtp Position of printf()-style format string parameter - * @param argp Position of variable argument list ("...") parameter - * @code - * void log(const int level, const char *fmt, ...) __ftdm_check_printf(2, 3); - * @endcode - */ -#define __ftdm_check_printf(fmtp, argp) __attribute__((format (printf, fmtp, argp))) -/** - * Enable compiler-specific scanf()-style format and argument checks on a function - * @param fmtp Position of scanf()-style format string parameter - * @param argp Position of variable argument list ("...") parameter - * @code - * void parse(struct foo *ctx, const char *fmt, ...) __ftdm_check_scanf(2, 3); - * @endcode - */ -#define __ftdm_check_scanf(fmtp, argp) __attribute__((format (scanf, fmtp, argp))) -#else -#define __ftdm_check_printf(fmtp, argp) -#define __ftdm_check_scanf(fmtp, argp) -#endif - - -#define FTDM_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) FT_DECLARE(_TYPE) _FUNC1 (const char *name); FT_DECLARE(const char *) _FUNC2 (_TYPE type); -#define FTDM_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \ - FT_DECLARE(_TYPE) _FUNC1 (const char *name) \ - { \ - int i; \ - _TYPE t = _MAX ; \ - \ - for (i = 0; i < _MAX ; i++) { \ - if (!strcasecmp(name, _STRINGS[i])) { \ - t = (_TYPE) i; \ - break; \ - } \ - } \ - \ - return t; \ - } \ - FT_DECLARE(const char *) _FUNC2 (_TYPE type) \ - { \ - if (type > _MAX) { \ - type = _MAX; \ - } \ - return _STRINGS[(int)type]; \ - } \ - -#ifdef __WINDOWS__ -#include -#include -#define FTDM_INVALID_SOCKET INVALID_HANDLE_VALUE -typedef HANDLE ftdm_socket_t; -typedef unsigned __int64 uint64_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int8 uint8_t; -typedef __int64 int64_t; -typedef __int32 int32_t; -typedef __int16 int16_t; -typedef __int8 int8_t; -#define FTDM_O_BINARY O_BINARY -#define FTDM_SIZE_FMT "Id" -#define FTDM_INT64_FMT "lld" -#define FTDM_UINT64_FMT "llu" -#define FTDM_XINT64_FMT "llx" -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif /* _MSC_VER */ -#else /* __WINDOWS__ */ -#define FTDM_O_BINARY 0 -#define FTDM_SIZE_FMT "zd" -#if (defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ == 8)) || defined(__LP64__) || defined(__LLP64__) -#define FTDM_INT64_FMT "ld" -#define FTDM_UINT64_FMT "lu" -#define FTDM_XINT64_FMT "lx" -#else -#define FTDM_INT64_FMT "lld" -#define FTDM_UINT64_FMT "llu" -#define FTDM_XINT64_FMT "llx" -#endif -#define FTDM_INVALID_SOCKET -1 -typedef int ftdm_socket_t; -#include -#include -#include -#endif - -/*! \brief FreeTDM APIs possible return codes */ -typedef enum { - FTDM_SUCCESS, /*!< Success */ - FTDM_FAIL, /*!< Failure, generic error return code when no more specific return code can be used */ - - FTDM_MEMERR, /*!< Allocation failure */ - FTDM_ENOMEM = FTDM_MEMERR, - - FTDM_TIMEOUT, /*!< Operation timed out (ie: polling on a device)*/ - FTDM_ETIMEDOUT = FTDM_TIMEOUT, - - FTDM_NOTIMPL, /*!< Operation not implemented */ - FTDM_ENOSYS = FTDM_NOTIMPL, /*!< The function is not implemented */ - - FTDM_BREAK, /*!< Request the caller to perform a break (context-dependant, ie: stop getting DNIS/ANI) */ - - /*!< Any new return codes should try to mimc unix style error codes, no need to reinvent */ - FTDM_EINVAL, /*!< Invalid argument */ - FTDM_ECANCELED, /*!< Operation cancelled */ - FTDM_EBUSY, /*!< Device busy */ -} ftdm_status_t; - -/*! \brief FreeTDM bool type. */ -typedef enum { - FTDM_FALSE, - FTDM_TRUE -} ftdm_bool_t; - -/*! \brief I/O waiting flags */ -typedef enum { - FTDM_NO_FLAGS = 0, - FTDM_READ = (1 << 0), - FTDM_WRITE = (1 << 1), - FTDM_EVENTS = (1 << 2) -} ftdm_wait_flag_t; - -/*! - * \brief FreeTDM channel. - * This is the basic data structure used to place calls and I/O operations - */ -typedef struct ftdm_channel ftdm_channel_t; - -/*! - * \brief FreeTDM span. - * Channel and signaling configuration container. - * This is a logical span structure, a span may ( or may note ) contain channels - * of other physical spans, depending on configuration (freetdm.conf) or if you - * are not using configuration depends on how you call ftdm_span_add_channel - */ -typedef struct ftdm_span ftdm_span_t; - -typedef struct ftdm_event ftdm_event_t; -typedef struct ftdm_conf_node ftdm_conf_node_t; -typedef struct ftdm_group ftdm_group_t; -typedef size_t ftdm_size_t; -typedef struct ftdm_sigmsg ftdm_sigmsg_t; -typedef struct ftdm_usrmsg ftdm_usrmsg_t; -typedef struct ftdm_io_interface ftdm_io_interface_t; -typedef struct ftdm_stream_handle ftdm_stream_handle_t; -typedef struct ftdm_queue ftdm_queue_t; -typedef struct ftdm_memory_handler ftdm_memory_handler_t; - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/ftdm_dso.h b/libs/freetdm/src/include/ftdm_dso.h deleted file mode 100755 index b2d3c21999..0000000000 --- a/libs/freetdm/src/include/ftdm_dso.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cross Platform dso/dll load abstraction - * Copyright(C) 2008 Michael Jerris - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so. - * - * This work is provided under this license on an "as is" basis, without warranty of any kind, - * either expressed or implied, including, without limitation, warranties that the covered code - * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire - * risk as to the quality and performance of the covered code is with you. Should any covered - * code prove defective in any respect, you (not the initial developer or any other contributor) - * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty - * constitutes an essential part of this license. No use of any covered code is authorized hereunder - * except under this disclaimer. - * - */ - -#include "freetdm.h" - -#ifndef _FTDM_DSO_H -#define _FTDM_DSO_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*ftdm_func_ptr_t) (void); -typedef void * ftdm_dso_lib_t; - -FT_DECLARE(ftdm_status_t) ftdm_dso_destroy(ftdm_dso_lib_t *lib); -FT_DECLARE(ftdm_dso_lib_t) ftdm_dso_open(const char *path, char **err); -FT_DECLARE(void *) ftdm_dso_func_sym(ftdm_dso_lib_t lib, const char *sym, char **err); -FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len); - - -#ifdef __cplusplus -} -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/include/ftdm_os.h b/libs/freetdm/src/include/ftdm_os.h deleted file mode 100644 index 913debcd52..0000000000 --- a/libs/freetdm/src/include/ftdm_os.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __FTDM_OS_H__ -#define __FTDM_OS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__linux__) && !defined(__USE_BSD) -#define __USE_BSD -#endif - -#include "ftdm_declare.h" -#include "ftdm_threadmutex.h" -#include - -#ifndef __WINDOWS__ -#include -#endif - -/*! \brief time data type */ -typedef uint64_t ftdm_time_t; -/*! format string for ftdm_time_t */ -#define FTDM_TIME_FMT FTDM_UINT64_FMT - -/*! \brief sleep x amount of milliseconds */ -#ifdef __WINDOWS__ -#define ftdm_sleep(x) Sleep(x) -#else -#define ftdm_sleep(x) usleep(x * 1000) -#endif - -/*! \brief strncpy replacement */ -#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1) - -/*! \brief strncpy into a fixed-length buffer */ -#define ftdm_set_string(x,y) strncpy(x, y, sizeof(x)-1) - -/*! \brief check for null or zero length string buffer */ -#define ftdm_strlen_zero(s) (!s || *s == '\0') - -/*! \brief check for zero length string buffer */ -#define ftdm_strlen_zero_buf(s) (*s == '\0') - -/*! \brief array len helper */ -#define ftdm_array_len(array) sizeof(array)/sizeof(array[0]) - -/*! \brief Get smaller value */ -#define ftdm_min(x,y) ((x) < (y) ? (x) : (y)) - -/*! \brief Get larger value */ -#define ftdm_max(x,y) ((x) > (y) ? (x) : (y)) - -/*! \brief Get value that is in range [vmin,vmax] */ -#define ftdm_clamp(val,vmin,vmax) ftdm_max(vmin,ftdm_min(val,vmax)) - -/*!< \brief Safer version of ftdm_clamp(), that swaps vmin/vmax parameters if vmin > vmax */ -#define ftdm_clamp_safe(val,vmin,vmax) \ - ftdm_clamp(val, ftdm_min(vmin,vmax), ftdm_max(vmin,vmax)) - -/*! - * \brief Get offset of member in structure - * \param[in] type Type of struct - * \param[in] member Name of struct member - * \code - * struct a { - * int foo; - * int bar; - * }; - * - * int offset_a_bar = ftdm_offset_of(struct a, bar); // 4 byte offset - * \endcode - */ -#define ftdm_offset_of(type,member) (uintptr_t)&(((type *)0)->member) - -/*! - * \brief Get pointer to enclosing structrure from pointer to embedded member - * \param[in] ptr Pointer to embedded member - * \param[in] type Type of parent/container structure - * \param[in] member Name of embedded member in parent/container struct - * \code - * struct engine { - * int nr_cyl; - * }; - * - * struct car { - * char model[10]; - * struct engine eng; // struct engine embedded in car(!) - * }; - * - * int somefunc(struct engine *e) { - * struct car *c = ftdm_container_of(e, struct car, eng); - * - * ... do something with car ... - * } - * \endcode - */ -#define ftdm_container_of(ptr,type,member) (type *)((uintptr_t)(ptr) - ftdm_offset_of(type, member)) - -/*! - * \brief Silence "unused parameter" compiler warnings - * \note Tested with VS 2010, GCC 4.8, clang 3.1 and suncc - * \code - * int example(char *a) { - * ftdm_unused_arg(a); - * return 0; - * } - * \endcode - */ -#define ftdm_unused_arg(x) (void)(x) - - -/*! \brief The memory handler. - Do not use directly this variable, use the memory macros and ftdm_global_set_memory_handler to override */ -FT_DECLARE_DATA extern ftdm_memory_handler_t g_ftdm_mem_handler; - -/*! - \brief Allocate uninitialized memory - \param chunksize the chunk size -*/ -#define ftdm_malloc(chunksize) g_ftdm_mem_handler.malloc(g_ftdm_mem_handler.pool, chunksize) - -/*! - \brief Reallocates memory - \param buff the buffer - \param chunksize the chunk size -*/ -#define ftdm_realloc(buff, chunksize) g_ftdm_mem_handler.realloc(g_ftdm_mem_handler.pool, buff, chunksize) - -/*! - \brief Allocate initialized memory - \param chunksize the chunk size -*/ -#define ftdm_calloc(elements, chunksize) g_ftdm_mem_handler.calloc(g_ftdm_mem_handler.pool, elements, chunksize) - -/*! - \brief Free chunk of memory - \param chunksize the chunk size -*/ -#define ftdm_free(chunk) g_ftdm_mem_handler.free(g_ftdm_mem_handler.pool, chunk) - -/*! - \brief Free a pointer and set it to NULL unless it already is NULL - \param it the pointer -*/ -#define ftdm_safe_free(it) if (it) { ftdm_free(it); it = NULL; } - -/*! \brief Duplicate string */ -FT_DECLARE(char *) ftdm_strdup(const char *str); - -/*! \brief Duplicate string with limit */ -FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen); - -/*! \brief Get the current time in milliseconds */ -FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void); - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/ftdm_threadmutex.h b/libs/freetdm/src/include/ftdm_threadmutex.h deleted file mode 100644 index 45eb87d441..0000000000 --- a/libs/freetdm/src/include/ftdm_threadmutex.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Cross Platform Thread/Mutex abstraction - * Copyright(C) 2007 Michael Jerris - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so. - * - * This work is provided under this license on an "as is" basis, without warranty of any kind, - * either expressed or implied, including, without limitation, warranties that the covered code - * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire - * risk as to the quality and performance of the covered code is with you. Should any covered - * code prove defective in any respect, you (not the initial developer or any other contributor) - * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty - * constitutes an essential part of this license. No use of any covered code is authorized hereunder - * except under this disclaimer. - * - * Contributors: - * - * Moises Silva - * - */ - - -#ifndef _FTDM_THREADMUTEX_H -#define _FTDM_THREADMUTEX_H - -#include "freetdm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ftdm_mutex ftdm_mutex_t; -typedef struct ftdm_thread ftdm_thread_t; -typedef struct ftdm_interrupt ftdm_interrupt_t; -typedef void *(*ftdm_thread_function_t) (ftdm_thread_t *, void *); - -FT_DECLARE(ftdm_status_t) ftdm_thread_create_detached(ftdm_thread_function_t func, void *data); -FT_DECLARE(ftdm_status_t) ftdm_thread_create_detached_ex(ftdm_thread_function_t func, void *data, ftdm_size_t stack_size); -FT_DECLARE(void) ftdm_thread_override_default_stacksize(ftdm_size_t size); - -FT_DECLARE(ftdm_status_t) ftdm_mutex_create(ftdm_mutex_t **mutex); -FT_DECLARE(ftdm_status_t) ftdm_mutex_destroy(ftdm_mutex_t **mutex); - -#define ftdm_mutex_lock(_x) _ftdm_mutex_lock(__FILE__, __LINE__, __FTDM_FUNC__, _x) -FT_DECLARE(ftdm_status_t) _ftdm_mutex_lock(const char *file, int line, const char *func, ftdm_mutex_t *mutex); - -#define ftdm_mutex_trylock(_x) _ftdm_mutex_trylock(__FILE__, __LINE__, __FTDM_FUNC__, _x) -FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(const char *file, int line, const char *func, ftdm_mutex_t *mutex); - -#define ftdm_mutex_unlock(_x) _ftdm_mutex_unlock(__FILE__, __LINE__, __FTDM_FUNC__, _x) -FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const char *func, ftdm_mutex_t *mutex); - -FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **cond, ftdm_socket_t device, ftdm_wait_flag_t device_flags); -FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **cond); -FT_DECLARE(ftdm_status_t) ftdm_interrupt_signal(ftdm_interrupt_t *cond); -FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *cond, int ms); -FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interrupts[], ftdm_size_t size, int ms); -FT_DECLARE(ftdm_wait_flag_t) ftdm_interrupt_device_ready(ftdm_interrupt_t *interrupt); - -#ifdef __cplusplus -} -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/include/private/fsk.h b/libs/freetdm/src/include/private/fsk.h deleted file mode 100644 index 66da140df9..0000000000 --- a/libs/freetdm/src/include/private/fsk.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * bell202.h - * - * Copyright (c) 2005 Robert Krten. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This module contains the manifest constants and declarations for - * the Bell-202 1200 baud FSK modem. - * - * 2005 03 20 R. Krten created -*/ - -#ifndef __FSK_H__ -#define __FSK_H__ -#include "uart.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - int freq_space; /* Frequency of the 0 bit */ - int freq_mark; /* Frequency of the 1 bit */ - int baud_rate; /* baud rate for the modem */ -} fsk_modem_definition_t; - -/* Must be kept in sync with fsk_modem_definitions array in fsk.c */ -/* V.23 definitions: http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-V.23 */ -typedef enum { - FSK_V23_FORWARD_MODE1 = 0, /* Maximum 600 bps for long haul */ - FSK_V23_FORWARD_MODE2, /* Standard 1200 bps V.23 */ - FSK_V23_BACKWARD, /* 75 bps return path for V.23 */ - FSK_BELL202 /* Bell 202 half-duplex 1200 bps */ -} fsk_modem_types_t; - -typedef enum { - FSK_STATE_CHANSEIZE = 0, - FSK_STATE_CARRIERSIG, - FSK_STATE_DATA -} fsk_state_t; - -typedef struct dsp_fsk_attr_s -{ - int sample_rate; /* sample rate in HZ */ - bithandler_func_t bithandler; /* bit handler */ - void *bithandler_arg; /* arbitrary ID passed to bithandler as first argument */ - bytehandler_func_t bytehandler; /* byte handler */ - void *bytehandler_arg; /* arbitrary ID passed to bytehandler as first argument */ -} dsp_fsk_attr_t; - -typedef struct -{ - fsk_state_t state; - dsp_fsk_attr_t attr; /* attributes structure */ - double *correlates[4]; /* one for each of sin/cos for mark/space */ - int corrsize; /* correlate size (also number of samples in ring buffer) */ - double *buffer; /* sample ring buffer */ - int ringstart; /* ring buffer start offset */ - double cellpos; /* bit cell position */ - double celladj; /* bit cell adjustment for each sample */ - int previous_bit; /* previous bit (for detecting a transition to sync-up cell position) */ - int current_bit; /* current bit */ - int last_bit; - int downsampling_count; /* number of samples to skip */ - int current_downsample; /* current skip count */ - int conscutive_state_bits; /* number of bits in a row that matches the pattern for the current state */ -} dsp_fsk_handle_t; - -/* - * Function prototypes - * - * General calling order is: - * a) create the attributes structure (dsp_fsk_attr_init) - * b) initialize fields in the attributes structure (dsp_fsk_attr_set_*) - * c) create a Bell-202 handle (dsp_fsk_create) - * d) feed samples through the handler (dsp_fsk_sample) -*/ - -void dsp_fsk_attr_init(dsp_fsk_attr_t *attributes); - -bithandler_func_t dsp_fsk_attr_get_bithandler(dsp_fsk_attr_t *attributes, void **bithandler_arg); -void dsp_fsk_attr_set_bithandler(dsp_fsk_attr_t *attributes, bithandler_func_t bithandler, void *bithandler_arg); -bytehandler_func_t dsp_fsk_attr_get_bytehandler(dsp_fsk_attr_t *attributes, void **bytehandler_arg); -void dsp_fsk_attr_set_bytehandler(dsp_fsk_attr_t *attributes, bytehandler_func_t bytehandler, void *bytehandler_arg); -int dsp_fsk_attr_get_samplerate(dsp_fsk_attr_t *attributes); -int dsp_fsk_attr_set_samplerate(dsp_fsk_attr_t *attributes, int samplerate); - -dsp_fsk_handle_t * dsp_fsk_create(dsp_fsk_attr_t *attributes); -void dsp_fsk_destroy(dsp_fsk_handle_t **handle); - -void dsp_fsk_sample(dsp_fsk_handle_t *handle, double normalized_sample); - -extern fsk_modem_definition_t fsk_modem_definitions[]; - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif - diff --git a/libs/freetdm/src/include/private/ftdm_buffer.h b/libs/freetdm/src/include/private/ftdm_buffer.h deleted file mode 100644 index fd5628c905..0000000000 --- a/libs/freetdm/src/include/private/ftdm_buffer.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FTDM_BUFFER_H -#define FTDM_BUFFER_H - -#include "freetdm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup ftdm_buffer Buffer Routines - * @ingroup buffer - * The purpose of this module is to make a plain buffering interface that can be used for read/write buffers - * throughout the application. - * @{ - */ -struct ftdm_buffer; -typedef struct ftdm_buffer ftdm_buffer_t; - -/*! \brief Allocate a new dynamic ftdm_buffer - * \param buffer returned pointer to the new buffer - * \param blocksize length to realloc by as data is added - * \param start_len ammount of memory to reserve initially - * \param max_len length the buffer is allowed to grow to - * \return status - */ -FT_DECLARE(ftdm_status_t) ftdm_buffer_create(ftdm_buffer_t **buffer, ftdm_size_t blocksize, ftdm_size_t start_len, ftdm_size_t max_len); - -/*! \brief Get the length of a ftdm_buffer_t - * \param buffer any buffer of type ftdm_buffer_t - * \return int size of the buffer. - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_len(ftdm_buffer_t *buffer); - -/*! \brief Get the freespace of a ftdm_buffer_t - * \param buffer any buffer of type ftdm_buffer_t - * \return int freespace in the buffer. - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_freespace(ftdm_buffer_t *buffer); - -/*! \brief Get the in use amount of a ftdm_buffer_t - * \param buffer any buffer of type ftdm_buffer_t - * \return int ammount of buffer curently in use - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_inuse(ftdm_buffer_t *buffer); - -/*! \brief Read data from a ftdm_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer. - * \param buffer any buffer of type ftdm_buffer_t - * \param data pointer to the read data to be returned - * \param datalen amount of data to be returned - * \return int ammount of data actually read - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_read(ftdm_buffer_t *buffer, void *data, ftdm_size_t datalen); - -/*! \brief Read data endlessly from a ftdm_buffer_t - * \param buffer any buffer of type ftdm_buffer_t - * \param data pointer to the read data to be returned - * \param datalen amount of data to be returned - * \return int ammount of data actually read - * \note Once you have read all the data from the buffer it will loop around. - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_read_loop(ftdm_buffer_t *buffer, void *data, ftdm_size_t datalen); - -/*! \brief Assign a number of loops to read - * \param buffer any buffer of type ftdm_buffer_t - * \param loops the number of loops (-1 for infinite) - */ -FT_DECLARE(void) ftdm_buffer_set_loops(ftdm_buffer_t *buffer, int32_t loops); - -/*! \brief Write data into a ftdm_buffer_t up to the length of datalen - * \param buffer any buffer of type ftdm_buffer_t - * \param data pointer to the data to be written - * \param datalen amount of data to be written - * \return int amount of buffer used after the write, or 0 if no space available - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_write(ftdm_buffer_t *buffer, const void *data, ftdm_size_t datalen); - -/*! \brief Remove data from the buffer - * \param buffer any buffer of type ftdm_buffer_t - * \param datalen amount of data to be removed - * \return int size of buffer, or 0 if unable to toss that much data - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_toss(ftdm_buffer_t *buffer, ftdm_size_t datalen); - -/*! \brief Remove all data from the buffer - * \param buffer any buffer of type ftdm_buffer_t - */ -FT_DECLARE(void) ftdm_buffer_zero(ftdm_buffer_t *buffer); - -/*! \brief Destroy the buffer - * \param buffer buffer to destroy - * \note only neccessary on dynamic buffers (noop on pooled ones) - */ -FT_DECLARE(void) ftdm_buffer_destroy(ftdm_buffer_t **buffer); - -/*! \brief Seek to offset from the beginning of the buffer - * \param buffer buffer to seek - * \param datalen offset in bytes - * \return new position - */ -FT_DECLARE(ftdm_size_t) ftdm_buffer_seek(ftdm_buffer_t *buffer, ftdm_size_t datalen); - -/** @} */ - -FT_DECLARE(ftdm_size_t) ftdm_buffer_zwrite(ftdm_buffer_t *buffer, const void *data, ftdm_size_t datalen); - -#ifdef __cplusplus -} -#endif - -#endif -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/ftdm_config.h b/libs/freetdm/src/include/private/ftdm_config.h deleted file mode 100644 index f55261fcc9..0000000000 --- a/libs/freetdm/src/include/private/ftdm_config.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @defgroup config Config File Parser - * @ingroup config - * This module implements a basic interface and file format parser - * - *
- *
- * EXAMPLE 
- * 
- * [category1]
- * var1 => val1
- * var2 => val2
- * \# lines that begin with \# are comments
- * \#var3 => val3
- * 
- * @{ - */ - -#ifndef FTDM_CONFIG_H -#define FTDM_CONFIG_H - -#include "freetdm.h" -#define FTDM_URL_SEPARATOR "://" - - -#ifdef WIN32 -#define FTDM_PATH_SEPARATOR "\\" -#ifndef FTDM_CONFIG_DIR -#define FTDM_CONFIG_DIR "c:\\freetdm" -#endif -#define ftdm_is_file_path(file) (*(file +1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR)) -#else -#define FTDM_PATH_SEPARATOR "/" -#ifndef FTDM_CONFIG_DIR -#define FTDM_CONFIG_DIR "/etc/freetdm" -#endif -#define ftdm_is_file_path(file) ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR)) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ftdm_config ftdm_config_t; - -/*! \brief A simple file handle representing an open configuration file **/ -struct ftdm_config { - /*! FILE stream buffer to the opened file */ - FILE *file; - /*! path to the file */ - char path[512]; - /*! current category */ - char category[256]; - /*! current section */ - char section[256]; - /*! buffer of current line being read */ - char buf[1024]; - /*! current line number in file */ - int lineno; - /*! current category number in file */ - int catno; - /*! current section number in file */ - int sectno; - - int lockto; -}; - -/*! - \brief Open a configuration file - \param cfg (ftdm_config_t *) config handle to use - \param file_path path to the file - \return 1 (true) on success 0 (false) on failure -*/ -int ftdm_config_open_file(ftdm_config_t * cfg, const char *file_path); - -/*! - \brief Close a previously opened configuration file - \param cfg (ftdm_config_t *) config handle to use -*/ -void ftdm_config_close_file(ftdm_config_t * cfg); - -/*! - \brief Retrieve next name/value pair from configuration file - \param cfg (ftdm_config_t *) config handle to use - \param var pointer to aim at the new variable name - \param val pointer to aim at the new value -*/ -int ftdm_config_next_pair(ftdm_config_t * cfg, char **var, char **val); - -/*! - \brief Retrieve the CAS bits from a configuration string value - \param strvalue pointer to the configuration string value (expected to be in format whatever:xxxx) - \param outbits pointer to aim at the CAS bits -*/ -FT_DECLARE (int) ftdm_config_get_cas_bits(char *strvalue, unsigned char *outbits); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h deleted file mode 100644 index 935cd50078..0000000000 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ /dev/null @@ -1,803 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "freetdm.h" - -#ifndef __PRIVATE_FTDM_CORE__ -#define __PRIVATE_FTDM_CORE__ - -#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) -#define _XOPEN_SOURCE 600 -#endif - -#ifndef HAVE_STRINGS_H -#define HAVE_STRINGS_H 1 -#endif -#ifndef HAVE_SYS_SOCKET_H -#define HAVE_SYS_SOCKET_H 1 -#endif - -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif -#if (_MSC_VER >= 1400) /* VC8+ */ -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE -#endif -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE -#endif -#endif -#ifndef strcasecmp -#define strcasecmp(s1, s2) _stricmp(s1, s2) -#endif -#ifndef strncasecmp -#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) -#endif -#ifndef snprintf -#define snprintf _snprintf -#endif -#ifndef S_IRUSR -#define S_IRUSR _S_IREAD -#endif -#ifndef S_IWUSR -#define S_IWUSR _S_IWRITE -#endif -#undef HAVE_STRINGS_H -#undef HAVE_SYS_SOCKET_H -/* disable warning for zero length array in a struct */ -/* this will cause errors on c99 and ansi compliant compilers and will need to be fixed in the wanpipe header files */ -#pragma warning(disable:4706) -#pragma comment(lib, "Winmm") -#endif - -#define FTDM_THREAD_STACKSIZE 240 * 1024 -#define FTDM_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL }; - -#define ftdm_true(expr) \ - (expr && ( !strcasecmp(expr, "yes") || \ - !strcasecmp(expr, "on") || \ - !strcasecmp(expr, "true") || \ - !strcasecmp(expr, "enabled") || \ - !strcasecmp(expr, "active") || \ - atoi(expr))) ? FTDM_TRUE : FTDM_FALSE - -#ifdef WIN32_LEAN_AND_MEAN -#include -#include -#endif - -#include -#ifndef __WINDOWS__ -#include -#endif - -#include -#include -#include -#ifdef HAVE_STRINGS_H -#include -#endif -#include - -#include "ftdm_types.h" -#include "hashtable.h" -#include "ftdm_config.h" -#include "g711.h" -#include "libteletone.h" -#include "ftdm_buffer.h" -#include "ftdm_threadmutex.h" -#include "ftdm_sched.h" -#include "ftdm_call_utils.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000 -#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 - -#define GOTO_STATUS(label,st) status = st; goto label ; - -#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1) -#define ftdm_set_string(x,y) strncpy(x, y, sizeof(x)-1) -#define ftdm_strlen_zero(s) (!s || *s == '\0') -#define ftdm_strlen_zero_buf(s) (*s == '\0') - - -#define ftdm_channel_test_feature(obj, flag) ((obj)->features & flag) -#define ftdm_channel_set_feature(obj, flag) (obj)->features = (ftdm_channel_feature_t)((obj)->features | flag) -#define ftdm_channel_clear_feature(obj, flag) (obj)->features = (ftdm_channel_feature_t)((obj)->features & ( ~(flag) )) -#define ftdm_channel_set_member_locked(obj, _m, _v) ftdm_mutex_lock(obj->mutex); obj->_m = _v; ftdm_mutex_unlock(obj->mutex) - -/*! - \brief Test for the existance of a flag on an arbitary object - \command obj the object to test - \command flag the or'd list of flags to test - \return true value if the object has the flags defined -*/ -#define ftdm_test_flag(obj, flag) ((obj)->flags & flag) -/*!< Physical (IO) module specific flags */ -#define ftdm_test_pflag(obj, flag) ((obj)->pflags & flag) -/*!< signaling module specific flags */ -#define ftdm_test_sflag(obj, flag) ((obj)->sflags & flag) - -#define ftdm_set_alarm_flag(obj, flag) (obj)->alarm_flags |= (flag) -#define ftdm_clear_alarm_flag(obj, flag) (obj)->alarm_flags &= ~(flag) -#define ftdm_test_alarm_flag(obj, flag) ((obj)->alarm_flags & flag) - -#define ftdm_set_io_flag(obj, flag) (obj)->io_flags |= (flag) -#define ftdm_clear_io_flag(obj, flag) (obj)->io_flags &= ~(flag) -#define ftdm_test_io_flag(obj, flag) ((obj)->io_flags & flag) - -/*! - \brief Set a flag on an arbitrary object - \command obj the object to set the flags on - \command flag the or'd list of flags to set -*/ -#define ftdm_set_flag(obj, flag) (obj)->flags |= (flag) -#define ftdm_set_flag_locked(obj, flag) assert(obj->mutex != NULL); \ - ftdm_mutex_lock(obj->mutex); \ - (obj)->flags |= (flag); \ - ftdm_mutex_unlock(obj->mutex); - -#define ftdm_set_pflag(obj, flag) (obj)->pflags |= (flag) -#define ftdm_set_pflag_locked(obj, flag) assert(obj->mutex != NULL); \ - ftdm_mutex_lock(obj->mutex); \ - (obj)->pflags |= (flag); \ - ftdm_mutex_unlock(obj->mutex); - -#define ftdm_set_sflag(obj, flag) (obj)->sflags |= (flag) -#define ftdm_set_sflag_locked(obj, flag) assert(obj->mutex != NULL); \ - ftdm_mutex_lock(obj->mutex); \ - (obj)->sflags |= (flag); \ - ftdm_mutex_unlock(obj->mutex); - -/*! - \brief Clear a flag on an arbitrary object while locked - \command obj the object to test - \command flag the or'd list of flags to clear -*/ -#define ftdm_clear_flag(obj, flag) (obj)->flags &= ~(flag) - -#define ftdm_clear_flag_locked(obj, flag) assert(obj->mutex != NULL); ftdm_mutex_lock(obj->mutex); (obj)->flags &= ~(flag); ftdm_mutex_unlock(obj->mutex); - -#define ftdm_clear_pflag(obj, flag) (obj)->pflags &= ~(flag) - -#define ftdm_clear_pflag_locked(obj, flag) assert(obj->mutex != NULL); ftdm_mutex_lock(obj->mutex); (obj)->pflags &= ~(flag); ftdm_mutex_unlock(obj->mutex); - -#define ftdm_clear_sflag(obj, flag) (obj)->sflags &= ~(flag) - -#define ftdm_clear_sflag_locked(obj, flag) assert(obj->mutex != NULL); ftdm_mutex_lock(obj->mutex); (obj)->sflags &= ~(flag); ftdm_mutex_unlock(obj->mutex); - -#ifdef _MSC_VER -/* The while(0) below throws a conditional expression is constant warning */ -#pragma warning(disable:4127) -#endif - -/* this macro assumes obj is locked! */ -#define ftdm_wait_for_flag_cleared(obj, flag, time) \ - do { \ - int __safety = time; \ - while(__safety-- && ftdm_test_flag(obj, flag)) { \ - ftdm_mutex_unlock(obj->mutex); \ - ftdm_sleep(10); \ - ftdm_mutex_lock(obj->mutex); \ - } \ - if(!__safety) { \ - ftdm_log(FTDM_LOG_CRIT, "flag %"FTDM_UINT64_FMT" was never cleared\n", (uint64_t)flag); \ - } \ - } while(0); - -#define ftdm_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119) - -#ifdef __linux__ -#define ftdm_print_stack(level) \ - do { \ - void *__stacktrace[100] = { 0 }; \ - char **__symbols = NULL; \ - int __size = 0; \ - int __i = 0; \ - __size = backtrace(__stacktrace, ftdm_array_len(__stacktrace)); \ - __symbols = backtrace_symbols(__stacktrace, __size); \ - if (__symbols) { \ - for (__i = 0; __i < __size; __i++) { \ - ftdm_log(__level, "%s\n", __symbols[i]); \ - } \ - free(__symbols); \ - } \ - } while (0); -#else -#define ftdm_print_stack(level) ftdm_log(level, "FTDM_PRINT_STACK is not implemented in this operating system!\n"); -#endif - - -#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP) -/*! - \brief Copy flags from one arbitrary object to another - \command dest the object to copy the flags to - \command src the object to copy the flags from - \command flags the flags to copy -*/ -#define ftdm_copy_flags(dest, src, flags) (dest)->flags &= ~(flags); (dest)->flags |= ((src)->flags & (flags)) - -struct ftdm_stream_handle { - ftdm_stream_handle_write_function_t write_function; - ftdm_stream_handle_raw_write_function_t raw_write_function; - void *data; - void *end; - ftdm_size_t data_size; - ftdm_size_t data_len; - ftdm_size_t alloc_len; - ftdm_size_t alloc_chunk; -}; - -FT_DECLARE_NONSTD(ftdm_status_t) ftdm_console_stream_raw_write(ftdm_stream_handle_t *handle, uint8_t *data, ftdm_size_t datalen); -FT_DECLARE_NONSTD(ftdm_status_t) ftdm_console_stream_write(ftdm_stream_handle_t *handle, const char *fmt, ...); - -#define FTDM_CMD_CHUNK_LEN 1024 -#define FTDM_STANDARD_STREAM(s) memset(&s, 0, sizeof(s)); s.data = ftdm_malloc(FTDM_CMD_CHUNK_LEN); \ - assert(s.data); \ - memset(s.data, 0, FTDM_CMD_CHUNK_LEN); \ - s.end = s.data; \ - s.data_size = FTDM_CMD_CHUNK_LEN; \ - s.write_function = ftdm_console_stream_write; \ - s.raw_write_function = ftdm_console_stream_raw_write; \ - s.alloc_len = FTDM_CMD_CHUNK_LEN; \ - s.alloc_chunk = FTDM_CMD_CHUNK_LEN - -/*! brief create a new queue */ -#define ftdm_queue_create(queue, capacity) g_ftdm_queue_handler.create(queue, capacity) - -/*! Enqueue an object */ -#define ftdm_queue_enqueue(queue, obj) g_ftdm_queue_handler.enqueue(queue, obj) - -/*! dequeue an object from the queue */ -#define ftdm_queue_dequeue(queue) g_ftdm_queue_handler.dequeue(queue) - -/*! wait ms milliseconds for a queue to have available objects, -1 to wait forever */ -#define ftdm_queue_wait(queue, ms) g_ftdm_queue_handler.wait(queue, ms) - -/*! get the internal interrupt object (to wait for elements to be added from the outside bypassing ftdm_queue_wait) */ -#define ftdm_queue_get_interrupt(queue, ms) g_ftdm_queue_handler.get_interrupt(queue, ms) - -/*! destroy the queue */ -#define ftdm_queue_destroy(queue) g_ftdm_queue_handler.destroy(queue) - -FT_DECLARE_DATA extern ftdm_queue_handler_t g_ftdm_queue_handler; - -#define FTDM_TOKEN_STRLEN 128 -#define FTDM_MAX_TOKENS 10 - -static __inline__ char *ftdm_clean_string(char *s) -{ - char *p; - - for (p = s; p && *p; p++) { - uint8_t x = (uint8_t) *p; - if (x < 32 || x > 127) { - *p = ' '; - } - } - - return s; -} - -struct ftdm_bitstream { - uint8_t *data; - uint32_t datalen; - uint32_t byte_index; - uint8_t bit_index; - int8_t endian; - uint8_t top; - uint8_t bot; - uint8_t ss; - uint8_t ssv; -}; - -struct ftdm_fsk_data_state { - dsp_fsk_handle_t *fsk1200_handle; - uint8_t init; - uint8_t *buf; - size_t bufsize; - ftdm_size_t blen; - ftdm_size_t bpos; - ftdm_size_t dlen; - ftdm_size_t ppos; - int checksum; -}; - -struct ftdm_fsk_modulator { - teletone_dds_state_t dds; - ftdm_bitstream_t bs; - uint32_t carrier_bits_start; - uint32_t carrier_bits_stop; - uint32_t chan_sieze_bits; - uint32_t bit_factor; - uint32_t bit_accum; - uint32_t sample_counter; - int32_t samples_per_bit; - int32_t est_bytes; - fsk_modem_types_t modem_type; - ftdm_fsk_data_state_t *fsk_data; - ftdm_fsk_write_sample_t write_sample_callback; - void *user_data; - int16_t sample_buffer[64]; -}; - - -typedef enum { - FTDM_TYPE_NONE, - FTDM_TYPE_SPAN = 0xFF, - FTDM_TYPE_CHANNEL -} ftdm_data_type_t; - -/* number of bytes for the IO dump circular buffer (5 seconds worth of audio by default) */ -#define FTDM_IO_DUMP_DEFAULT_BUFF_SIZE 8 * 5000 -typedef struct { - char *buffer; - ftdm_size_t size; - int windex; - int wrapped; -} ftdm_io_dump_t; - -/* number of interval cycles before timeout and close the debug dtmf file (5 seconds if interval is 20) */ -#define DTMF_DEBUG_TIMEOUT 250 -typedef struct { - uint8_t enabled; - uint8_t requested; - FILE *file; - int32_t closetimeout; - ftdm_mutex_t *mutex; -} ftdm_dtmf_debug_t; - -typedef struct { - uint32_t duration_ms; - ftdm_time_t start_time; - /* If set to 1, we will send DTMF event the the tone starts, instead of waiting for end */ - uint8_t trigger_on_start; -} ftdm_dtmf_detect_t; - -/* 2^8 table size, one for each byte (sample) value */ -#define FTDM_GAINS_TABLE_SIZE 256 -struct ftdm_channel { - ftdm_data_type_t data_type; - uint32_t span_id; - uint32_t chan_id; - uint32_t physical_span_id; - uint32_t physical_chan_id; - uint32_t rate; - uint32_t extra_id; - ftdm_chan_type_t type; - ftdm_socket_t sockfd; - uint64_t flags; - uint32_t pflags; - uint32_t sflags; - uint8_t io_flags; - ftdm_alarm_flag_t alarm_flags; - ftdm_channel_feature_t features; - ftdm_codec_t effective_codec; - ftdm_codec_t native_codec; - uint32_t effective_interval; - uint32_t native_interval; - uint32_t packet_len; - ftdm_channel_state_t state; - ftdm_state_status_t state_status; - ftdm_channel_state_t last_state; - ftdm_channel_state_t init_state; - ftdm_channel_indication_t indication; - ftdm_state_history_entry_t history[10]; - uint8_t hindex; - ftdm_mutex_t *mutex; - teletone_dtmf_detect_state_t dtmf_detect; - uint32_t buffer_delay; - ftdm_event_t event_header; - char last_error[256]; - fio_event_cb_t event_callback; - uint32_t skip_read_frames; - ftdm_buffer_t *dtmf_buffer; - ftdm_buffer_t *gen_dtmf_buffer; - ftdm_buffer_t *pre_buffer; - ftdm_buffer_t *digit_buffer; - ftdm_buffer_t *fsk_buffer; - ftdm_mutex_t *pre_buffer_mutex; - uint32_t dtmf_on; - uint32_t dtmf_off; - char *dtmf_hangup_buf; - teletone_generation_session_t tone_session; - ftdm_time_t last_event_time; - ftdm_time_t ring_time; - char tokens[FTDM_MAX_TOKENS+1][FTDM_TOKEN_STRLEN]; - uint8_t needed_tones[FTDM_TONEMAP_INVALID]; - uint8_t detected_tones[FTDM_TONEMAP_INVALID]; - ftdm_tonemap_t last_detected_tone; - uint32_t token_count; - char chan_name[128]; - char chan_number[32]; - ftdm_filehandle_t fds[2]; - ftdm_fsk_data_state_t fsk; - uint8_t fsk_buf[80]; - uint32_t ring_count; - ftdm_polarity_t polarity; - /* Private I/O data. Do not touch unless you are an I/O module */ - void *io_data; - /* Private signaling data. Do not touch unless you are a signaling module */ - void *call_data; - struct ftdm_caller_data caller_data; - struct ftdm_span *span; - struct ftdm_io_interface *fio; - unsigned char rx_cas_bits; - uint32_t pre_buffer_size; - uint8_t rxgain_table[FTDM_GAINS_TABLE_SIZE]; - uint8_t txgain_table[FTDM_GAINS_TABLE_SIZE]; - float rxgain; - float txgain; - int availability_rate; - void *user_private; - ftdm_timer_id_t hangup_timer; - ftdm_channel_iostats_t iostats; - ftdm_dtmf_debug_t dtmfdbg; - ftdm_dtmf_detect_t dtmfdetect; - ftdm_io_dump_t rxdump; - ftdm_io_dump_t txdump; - ftdm_interrupt_t *state_completed_interrupt; /*!< Notify when a state change is completed */ - int32_t txdrops; - int32_t rxdrops; - ftdm_usrmsg_t *usrmsg; - ftdm_time_t last_state_change_time; - ftdm_time_t last_release_time; -}; - -struct ftdm_span { - ftdm_data_type_t data_type; - char *name; - uint32_t span_id; - uint32_t chan_count; - ftdm_span_flag_t flags; - struct ftdm_io_interface *fio; - fio_event_cb_t event_callback; - ftdm_mutex_t *mutex; - ftdm_trunk_type_t trunk_type; - ftdm_trunk_mode_t trunk_mode; - ftdm_analog_start_type_t start_type; - ftdm_signal_type_t signal_type; - uint32_t last_used_index; - /* Private signaling data. Do not touch unless you are a signaling module */ - void *signal_data; - fio_signal_cb_t signal_cb; - ftdm_event_t event_header; - char last_error[256]; - char tone_map[FTDM_TONEMAP_INVALID+1][FTDM_TONEMAP_LEN]; - teletone_tone_map_t tone_detect_map[FTDM_TONEMAP_INVALID+1]; - teletone_multi_tone_t tone_finder[FTDM_TONEMAP_INVALID+1]; - ftdm_channel_t *channels[FTDM_MAX_CHANNELS_SPAN+1]; - fio_channel_outgoing_call_t outgoing_call; - fio_channel_indicate_t indicate; - fio_channel_set_sig_status_t set_channel_sig_status; - fio_channel_get_sig_status_t get_channel_sig_status; - fio_span_set_sig_status_t set_span_sig_status; - fio_span_get_sig_status_t get_span_sig_status; - fio_channel_request_t channel_request; - ftdm_span_start_t start; - ftdm_span_stop_t stop; - ftdm_span_destroy_t destroy; - ftdm_channel_sig_read_t sig_read; - ftdm_channel_sig_write_t sig_write; - ftdm_channel_sig_dtmf_t sig_queue_dtmf; - ftdm_channel_sig_dtmf_t sig_send_dtmf; - uint32_t sig_release_guard_time_ms; - ftdm_channel_state_processor_t state_processor; /*!< This guy is called whenever state processing is required */ - void *io_data; /*!< Private I/O data per span. Do not touch unless you are an I/O module */ - char *type; - char *dtmf_hangup; - size_t dtmf_hangup_len; - ftdm_state_map_t *state_map; - ftdm_caller_data_t default_caller_data; - ftdm_queue_t *pendingchans; /*!< Channels pending of state processing */ - ftdm_queue_t *pendingsignals; /*!< Signals pending from being delivered to the user */ - struct ftdm_span *next; -}; - -struct ftdm_group { - char *name; - uint32_t group_id; - uint32_t chan_count; - ftdm_channel_t *channels[FTDM_MAX_CHANNELS_GROUP]; - uint32_t last_used_index; - ftdm_mutex_t *mutex; - struct ftdm_group *next; -}; - -FT_DECLARE_DATA extern ftdm_crash_policy_t g_ftdm_crash_policy; - -FT_DECLARE(ftdm_size_t) ftdm_fsk_modulator_generate_bit(ftdm_fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, ftdm_size_t buflen); -FT_DECLARE(int32_t) ftdm_fsk_modulator_generate_carrier_bits(ftdm_fsk_modulator_t *fsk_trans, uint32_t bits); -FT_DECLARE(void) ftdm_fsk_modulator_generate_chan_sieze(ftdm_fsk_modulator_t *fsk_trans); -FT_DECLARE(void) ftdm_fsk_modulator_send_data(ftdm_fsk_modulator_t *fsk_trans); -#define ftdm_fsk_modulator_send_all(_it) ftdm_fsk_modulator_generate_chan_sieze(_it); \ - ftdm_fsk_modulator_generate_carrier_bits(_it, _it->carrier_bits_start); \ - ftdm_fsk_modulator_send_data(_it); \ - ftdm_fsk_modulator_generate_carrier_bits(_it, _it->carrier_bits_stop) - -FT_DECLARE(ftdm_status_t) ftdm_fsk_modulator_init(ftdm_fsk_modulator_t *fsk_trans, - fsk_modem_types_t modem_type, - uint32_t sample_rate, - ftdm_fsk_data_state_t *fsk_data, - float db_level, - uint32_t carrier_bits_start, - uint32_t carrier_bits_stop, - uint32_t chan_sieze_bits, - ftdm_fsk_write_sample_t write_sample_callback, - void *user_data); -FT_DECLARE(int8_t) ftdm_bitstream_get_bit(ftdm_bitstream_t *bsp); -FT_DECLARE(void) ftdm_bitstream_init(ftdm_bitstream_t *bsp, uint8_t *data, uint32_t datalen, ftdm_endian_t endian, uint8_t ss); -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_parse(ftdm_fsk_data_state_t *state, ftdm_size_t *type, char **data, ftdm_size_t *len); -FT_DECLARE(ftdm_status_t) ftdm_fsk_demod_feed(ftdm_fsk_data_state_t *state, int16_t *data, size_t samples); -FT_DECLARE(ftdm_status_t) ftdm_fsk_demod_destroy(ftdm_fsk_data_state_t *state); -FT_DECLARE(int) ftdm_fsk_demod_init(ftdm_fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize); -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_init(ftdm_fsk_data_state_t *state, uint8_t *data, uint32_t datalen); -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_mdmf(ftdm_fsk_data_state_t *state, ftdm_mdmf_type_t type, const uint8_t *data, uint32_t datalen); -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_checksum(ftdm_fsk_data_state_t *state); -FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_sdmf(ftdm_fsk_data_state_t *state, const char *date, char *number); -FT_DECLARE(ftdm_status_t) ftdm_channel_send_fsk_data(ftdm_channel_t *ftdmchan, ftdm_fsk_data_state_t *fsk_data, float db_level); - -FT_DECLARE(ftdm_status_t) ftdm_span_load_tones(ftdm_span_t *span, const char *mapname); - -FT_DECLARE(ftdm_status_t) ftdm_channel_use(ftdm_channel_t *ftdmchan); - -FT_DECLARE(void) ftdm_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t divisor); - -FT_DECLARE(uint32_t) ftdm_separate_string(char *buf, char delim, char **array, int arraylen); -FT_DECLARE(void) print_bits(uint8_t *b, int bl, char *buf, int blen, int e, uint8_t ss); -FT_DECLARE(void) print_hex_bytes(uint8_t *data, ftdm_size_t dlen, char *buf, ftdm_size_t blen); - -FT_DECLARE_NONSTD(int) ftdm_hash_equalkeys(void *k1, void *k2); -FT_DECLARE_NONSTD(uint32_t) ftdm_hash_hashfromstring(void *ky); - -FT_DECLARE(int) ftdm_load_modules(void); - -FT_DECLARE(ftdm_status_t) ftdm_unload_modules(void); - -FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg); - -FT_DECLARE(void) ftdm_channel_clear_needed_tones(ftdm_channel_t *ftdmchan); -FT_DECLARE(void) ftdm_channel_rotate_tokens(ftdm_channel_t *ftdmchan); - -FT_DECLARE(int) ftdm_load_module(const char *name); -FT_DECLARE(int) ftdm_load_module_assume(const char *name); -FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap); - -FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void); -FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan); -FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_status_t status); - - -FT_DECLARE(ftdm_iterator_t *) ftdm_get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter); - -FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen); - -FT_DECLARE(ftdm_status_t) ftdm_raw_read (ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen); -FT_DECLARE(ftdm_status_t) ftdm_raw_write (ftdm_channel_t *ftdmchan, void *data, ftdm_size_t *datalen); - -/*! - * \brief Retrieves an event from the span - * - * \note - * This function is non-reentrant and not thread-safe. - * The event returned may be modified if the function is called again - * from a different thread or even the same. It is recommended to - * handle events from the same span in a single thread. - * WARNING: this function used to be public ( in freetdm.h ) - * but since is really of no use to users better keep it here - * - * \param span The span to retrieve the event from - * \param event Pointer to store the pointer to the event - * - * \retval FTDM_SUCCESS success (at least one event available) - * \retval FTDM_TIMEOUT Timed out waiting for events - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t **event); - -/*! - * \brief Enqueue a DTMF string into the channel - * - * \param ftdmchan The channel to enqueue the dtmf string to - * \param dtmf null-terminated DTMF string - * - * \retval FTDM_SUCCESS success - * \retval FTDM_FAIL failure - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, const char *dtmf); - -/* dequeue pending signals and notify the user via the span signal callback */ -FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span); - -/*! \brief clear the tone detector state */ -FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); - -/*! \brief adjust echocanceller for beginning of call */ -FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan); - -/*! \brief adjust echocanceller for end of call */ -FT_DECLARE(void) ftdm_set_echocancel_call_end(ftdm_channel_t *chan); - -/*! \brief save data from user */ -FT_DECLARE(ftdm_status_t) ftdm_channel_save_usrmsg(ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg); - -/*! \brief free usrmsg and variables/raw data attached to it */ -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_free(ftdm_usrmsg_t **usrmsg); - -/*! \brief Get a custom variable from the user message - * \note The variable pointer returned is only valid while the before the event is processed and it'll be destroyed once the event is processed. */ -FT_DECLARE(const char *) ftdm_usrmsg_get_var(ftdm_usrmsg_t *usrmsg, const char *var_name); - -/*! \brief Get raw data from user message - * \param usrmsg The message structure containing the variables - * \param data data will point to available data pointer if available - * \param datalen datalen will be set to length of data available - * \retval FTDM_SUCCESS data is available - * \retval FTDM_FAIL no data available - * \note data is only valid within the duration of the callback, to receive a data pointer that does not get - * \note destroyed when callback returns, see ftdm_sigmsg_get_raw_data_detached - */ -FT_DECLARE(ftdm_status_t) ftdm_usrmsg_get_raw_data(ftdm_usrmsg_t *usrmsg, void **data, ftdm_size_t *datalen); - -/*! \brief free sigmsg and variables/raw data attached to it */ -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_free(ftdm_sigmsg_t **sigmsg); - -/*! \brief Add a custom variable to the event - * \note This variables may be used by signaling modules to override signaling parameters - * \todo Document which signaling variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_add_var(ftdm_sigmsg_t *sigmsg, const char *var_name, const char *value); - -/*! \brief Remove a custom variable from the event - * \note The variable pointer returned is only valid while the before the event is processed and it'll be destroyed once the event is processed. */ -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_remove_var(ftdm_sigmsg_t *sigmsg, const char *var_name); - -/*! \brief Attach raw data to sigmsg - * \param sigmsg The message structure containing the variables - * \param data pointer to data - * \param datalen datalen length of data - * \retval FTDM_SUCCESS success, data was successfully saved - * \retval FTDM_FAIL failed, event already had data attached to it. - * \note data must have been allocated using ftdm_calloc, FreeTDM will free data once the usrmsg is processed. - */ -FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *data, ftdm_size_t datalen); - -/*! \brief Retrieve a span and channel data structure from a string in the format 'span_id:chan_id'*/ -FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel); - -/*! - \brief Assert condition -*/ -#define ftdm_assert(assertion, msg) \ - if (!(assertion)) { \ - ftdm_log(FTDM_LOG_CRIT, "%s", msg); \ - if (g_ftdm_crash_policy & FTDM_CRASH_ON_ASSERT) { \ - ftdm_abort(); \ - } \ - } - -/*! - \brief Assert condition and return -*/ -#define ftdm_assert_return(assertion, retval, msg) \ - if (!(assertion)) { \ - ftdm_log(FTDM_LOG_CRIT, "%s", msg); \ - if (g_ftdm_crash_policy & FTDM_CRASH_ON_ASSERT) { \ - ftdm_abort(); \ - } else { \ - return retval; \ - } \ - } - -/*! - \brief Socket the given socket - \command it the socket -*/ -#define ftdm_socket_close(it) if (it > -1) { close(it); it = -1;} - -#define ftdm_channel_lock(chan) ftdm_mutex_lock((chan)->mutex) -#define ftdm_channel_unlock(chan) ftdm_mutex_unlock((chan)->mutex) - -#define ftdm_log_throttle(level, ...) \ - time_current_throttle_log = ftdm_current_time_in_ms(); \ - if (time_current_throttle_log - time_last_throttle_log > FTDM_THROTTLE_LOG_INTERVAL) {\ - ftdm_log(level, __VA_ARGS__); \ - time_last_throttle_log = time_current_throttle_log; \ - } - -#define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) - -#define ftdm_log_chan_ex_msg(fchan, file, func, line, level, msg) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id) - -#define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) - -#define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id) - -#define ftdm_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) -#define ftdm_log_chan_msg_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) - -#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex) -#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex) - -#define ftdm_test_and_set_media(fchan) \ - do { \ - if (!ftdm_test_flag((fchan), FTDM_CHANNEL_MEDIA)) { \ - ftdm_set_flag((fchan), FTDM_CHANNEL_MEDIA); \ - ftdm_set_echocancel_call_begin((fchan)); \ - if ((fchan)->dtmfdbg.requested) { \ - ftdm_channel_command((fchan), FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL); \ - } \ - } \ - } while (0); - -FT_DECLARE_DATA extern const char *FTDM_LEVEL_NAMES[9]; - -static __inline__ void ftdm_abort(void) -{ -#ifdef __cplusplus - ::abort(); -#else - abort(); -#endif -} - -static __inline__ int16_t ftdm_saturated_add(int16_t sample1, int16_t sample2) -{ - int addres; - - addres = sample1 + sample2; - if (addres > 32767) - addres = 32767; - else if (addres < -32767) - addres = -32767; - return (int16_t)addres; -} - -/* Bitmap helper functions */ -typedef long ftdm_bitmap_t; -#define FTDM_BITMAP_NBITS (sizeof(ftdm_bitmap_t) * 8) -#define ftdm_map_set_bit(map, bit) (map[(bit/FTDM_BITMAP_NBITS)] |= ((ftdm_bitmap_t)1 << (bit % FTDM_BITMAP_NBITS))) -#define ftdm_map_clear_bit(map, bit) (map[(bit/FTDM_BITMAP_NBITS)] &= ~((ftdm_bitmap_t)1 << (bit % FTDM_BITMAP_NBITS))) -#define ftdm_map_test_bit(map, bit) (map[(bit/FTDM_BITMAP_NBITS)] & ((ftdm_bitmap_t)1 << (bit % FTDM_BITMAP_NBITS))) - -#ifdef __cplusplus -} -#endif - -#endif /* endif __PRIVATE_FTDM_CORE__ */ diff --git a/libs/freetdm/src/include/private/ftdm_cpu_monitor.h b/libs/freetdm/src/include/private/ftdm_cpu_monitor.h deleted file mode 100644 index 249a5233c7..0000000000 --- a/libs/freetdm/src/include/private/ftdm_cpu_monitor.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Contributors: - * David Yat Sin - * - */ - -/*! \brief opaque cpu stats structure */ -struct ftdm_cpu_monitor_stats; - -/*! - * \brief create a new cpu monitor - * \return profile timer structure previously created with new_profile_timer, NULL on error - */ -FT_DECLARE(struct ftdm_cpu_monitor_stats*) ftdm_new_cpu_monitor(void); - -/*! - * \brief Deletes cpu_monitor - */ -FT_DECLARE(void) ftdm_delete_cpu_monitor(struct ftdm_cpu_monitor_stats *p); - -/*! - * \brief provides the percentage of idle system time - * \param p cpu_stats structure previously created with ftdm_new_cpu_monitor - * \param pointer to store the percentage of idle time - * \return -1 on error 0 for success - */ -FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor_stats *p, double *idle_percentage); - - - - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/ftdm_sched.h b/libs/freetdm/src/include/private/ftdm_sched.h deleted file mode 100644 index 020da9fb3b..0000000000 --- a/libs/freetdm/src/include/private/ftdm_sched.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __FTDM_SCHED_H__ -#define __FTDM_SCHED_H__ - -#include "freetdm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FTDM_MICROSECONDS_PER_SECOND 1000000 - -typedef struct ftdm_sched ftdm_sched_t; -typedef void (*ftdm_sched_callback_t)(void *data); -typedef uint64_t ftdm_timer_id_t; - -/*! \brief Create a new scheduling context */ -FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name); - -/*! \brief Run the schedule to find timers that are expired and run its callbacks */ -FT_DECLARE(ftdm_status_t) ftdm_sched_run(ftdm_sched_t *sched); - -/*! \brief Run the schedule in its own thread. Callbacks will be called in a core thread. You *must* not block there! */ -FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched); - -/*! - * \brief Schedule a new timer - * \param sched The scheduling context (required) - * \param name Timer name, typically unique but is not required to be unique, any null terminated string is fine (required) - * \param callback The callback to call upon timer expiration (required) - * \param data Optional data to pass to the callback - * \param timer Timer id pointer to store the id of the newly created timer. It can be null - * if you do not need to know the id, but you need this if you want to be able - * to cancel the timer with ftdm_sched_cancel_timer - */ -FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, - int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timer); - -/*! - * \brief Cancel the timer - * Note that there is a race between cancelling and triggering a timer. - * By the time you call this function the timer may be about to be triggered. - * This is specially true with timers in free run schedule. - * \param sched The scheduling context (required) - * \param timer The timer to cancel (required) - */ -FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timer); - -/*! \brief Destroy the context and all of the scheduled timers in it */ -FT_DECLARE(ftdm_status_t) ftdm_sched_destroy(ftdm_sched_t **sched); - -/*! - * \brief Calculate the time to the next timer and return it - * \param sched The sched context - * \param timeto The pointer to store the next timer time in milliseconds - */ -FT_DECLARE(ftdm_status_t) ftdm_sched_get_time_to_next_timer(const ftdm_sched_t *sched, int32_t *timeto); - -/*! \brief Global initialization, called just once, this is called by FreeTDM core, other users MUST not call it */ -FT_DECLARE(ftdm_status_t) ftdm_sched_global_init(void); - -/*! \brief Global destroy, called just once, this is called by FreeTDM core, other users MUST not call it */ -FT_DECLARE(ftdm_status_t) ftdm_sched_global_destroy(void); - -/*! \brief Checks if the main scheduling thread is running */ -FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void); - -/*! \brief Stop the main scheduling thread (if running) */ -FT_DECLARE(ftdm_bool_t) ftdm_free_sched_stop(void); - -#ifdef __cplusplus -} -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/ftdm_state.h b/libs/freetdm/src/include/private/ftdm_state.h deleted file mode 100644 index 733a561dcc..0000000000 --- a/libs/freetdm/src/include/private/ftdm_state.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * Moises Silva - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __FTDM_STATE_H__ -#define __FTDM_STATE_H__ - -/*! \file - * \brief State handling definitions - * \note Most, if not all of the state handling functions assume you have a lock acquired. Touching the channel - * state is a sensitive matter that requires checks and careful thought and is typically a process that - * is not encapsulated within a single function, therefore the lock must be explicitly acquired by the - * caller (most of the time, signaling modules), process states, set a new state and process it, and - * finally unlock the channel. See docs/locking.txt fore more info - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - FTDM_CHANNEL_STATE_ANY = -1, - FTDM_CHANNEL_STATE_END = -1, - FTDM_CHANNEL_STATE_DOWN, - FTDM_CHANNEL_STATE_HOLD, - FTDM_CHANNEL_STATE_SUSPENDED, - FTDM_CHANNEL_STATE_DIALTONE, - FTDM_CHANNEL_STATE_COLLECT, - FTDM_CHANNEL_STATE_RING, - FTDM_CHANNEL_STATE_RINGING, - FTDM_CHANNEL_STATE_BUSY, - FTDM_CHANNEL_STATE_ATTN, - FTDM_CHANNEL_STATE_GENRING, - FTDM_CHANNEL_STATE_DIALING, - FTDM_CHANNEL_STATE_GET_CALLERID, - FTDM_CHANNEL_STATE_CALLWAITING, - FTDM_CHANNEL_STATE_RESTART, - FTDM_CHANNEL_STATE_PROCEED, - FTDM_CHANNEL_STATE_PROGRESS, - FTDM_CHANNEL_STATE_PROGRESS_MEDIA, - FTDM_CHANNEL_STATE_UP, - FTDM_CHANNEL_STATE_TRANSFER, - FTDM_CHANNEL_STATE_IDLE, - FTDM_CHANNEL_STATE_TERMINATING, - FTDM_CHANNEL_STATE_CANCEL, - FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_HANGUP_COMPLETE, - FTDM_CHANNEL_STATE_IN_LOOP, - FTDM_CHANNEL_STATE_RESET, - FTDM_CHANNEL_STATE_INVALID -} ftdm_channel_state_t; -/* Purposely not adding ANY (-1) and END (-1) since FTDM_STR2ENUM_P works only on enums starting at zero */ -#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \ - "RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \ - "RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "TRANSFER", "IDLE", "TERMINATING", "CANCEL", \ - "HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID" -FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t) - -typedef struct { - const char *file; - const char *func; - int line; - ftdm_channel_state_t state; /*!< Current state (processed or not) */ - ftdm_channel_state_t last_state; /*!< Previous state */ - ftdm_time_t time; /*!< Time the state was set */ - ftdm_time_t end_time; /*!< Time the state processing was completed */ -} ftdm_state_history_entry_t; - -typedef ftdm_status_t (*ftdm_channel_state_processor_t)(ftdm_channel_t *fchan); - -/*! - * \brief Process channel states by invoking the channel state processing routine - * it will keep calling the processing routine while the state status - * is FTDM_STATE_STATUS_NEW, it will not do anything otherwise - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan); - -FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *function, int line, ftdm_channel_t *fchan); -#define ftdm_channel_complete_state(obj) _ftdm_channel_complete_state(__FILE__, __FTDM_FUNC__, __LINE__, obj) -FT_DECLARE(int) ftdm_check_state_all(ftdm_span_t *span, ftdm_channel_state_t state); - -/*! - * \brief Status of the current channel state - * \note A given state goes thru several status (yes, states for the state!) - * The order is always FTDM_STATE_STATUS_NEW -> FTDM_STATE_STATUS_PROCESSED -> FTDM_STATUS_COMPLETED - * However, is possible to go from NEW -> COMPLETED directly when the signaling module explicitly changes - * the state of the channel in the middle of processing the current state by calling the ftdm_set_state() API - * - * FTDM_STATE_STATUS_NEW - - * Someone just set the state of the channel, either the signaling module or the user (implicitly through a call API). - * This is accomplished by calling ftdm_channel_set_state() which changes the 'state' and 'last_state' memebers of - * the ftdm_channel_t structure. - * - * FTDM_STATE_STATUS_PROCESSED - - * The signaling module did something based on the new state. - * - * This is accomplished via ftdm_channel_advance_states() - * - * When ftdm_channel_advance_states(), at the very least, if the channel has its state in FTDM_STATE_STATUS_NEW, it - * will move to FTDM_STATE_STATUS_PROCESSED, depending on what the signaling module does during the processing - * the state may move to FTDM_STATE_STATUS_COMPLETED right after or wait for a signaling specific event to complete it. - * It is also possible that more state transitions occur during the execution of ftdm_channel_advance_states() if one - * state processing/completion leads to another state change, the function will not return until the chain of events - * lead to a state that is not in FTDM_STATE_STATUS_NEW - * - * FTDM_STATE_STATUS_COMPLETED - - * The signaling module completed the processing of the state and there is nothing further to be done for this state. - * - * This is accomplished either explicitly by the signaling module by calling ftdm_channel_complete_state() or by - * the signaling module implicitly by trying to set the state of the channel to a new state via ftdm_set_state() - * - * When working with blocking channels (FTDM_CHANNEL_NONBLOCK flag not set), the user thread is signaled and unblocked - * so it can continue. - * - * When a state moves to this status is also possible for a signal FTDM_SIGEVENT_INDICATION_COMPLETED to be delivered - * by the core if the state change was associated to an indication requested by the user, - */ -typedef enum { - FTDM_STATE_STATUS_NEW, - FTDM_STATE_STATUS_PROCESSED, - FTDM_STATE_STATUS_COMPLETED, - FTDM_STATE_STATUS_INVALID -} ftdm_state_status_t; -#define CHANNEL_STATE_STATUS_STRINGS "NEW", "PROCESSED", "COMPLETED", "INVALID" -FTDM_STR2ENUM_P(ftdm_str2ftdm_state_status, ftdm_state_status2str, ftdm_state_status_t) - -typedef enum { - ZSM_NONE, - ZSM_UNACCEPTABLE, - ZSM_ACCEPTABLE -} ftdm_state_map_type_t; - -typedef enum { - ZSD_INBOUND, - ZSD_OUTBOUND, -} ftdm_state_direction_t; - -#define FTDM_MAP_NODE_SIZE 512 -#define FTDM_MAP_MAX FTDM_CHANNEL_STATE_INVALID+2 - -struct ftdm_state_map_node { - ftdm_state_direction_t direction; - ftdm_state_map_type_t type; - ftdm_channel_state_t check_states[FTDM_MAP_MAX]; - ftdm_channel_state_t states[FTDM_MAP_MAX]; -}; -typedef struct ftdm_state_map_node ftdm_state_map_node_t; - -struct ftdm_state_map { - ftdm_state_map_node_t nodes[FTDM_MAP_NODE_SIZE]; -}; -typedef struct ftdm_state_map ftdm_state_map_t; - -/*!\brief Cancel the state processing for a channel (the channel must be locked when calling this function) - * \note Only the core should use this function - */ -FT_DECLARE(ftdm_status_t) ftdm_channel_cancel_state(const char *file, const char *func, int line, - ftdm_channel_t *ftdmchan); - -/*!\brief Set the state for a channel (the channel must be locked when calling this function) - * \note Signaling modules should use ftdm_set_state macro instead - * \note If this function is called with the wait parameter set to a non-zero value, the recursivity - * of the channel lock must be == 1 because the channel will be unlocked/locked when waiting */ -FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line, - ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int wait, ftdm_usrmsg_t *usrmsg); - -/*!\brief Set the state of a channel immediately and implicitly complete the previous state if needed - * \note FTDM_SIGEVENT_INDICATION_COMPLETED will be sent if the state change - * is associated to some indication (ie FTDM_CHANNEL_INDICATE_PROCEED) - * \note The channel must be locked when calling this function - * */ -FT_DECLARE(ftdm_status_t) _ftdm_set_state(const char *file, const char *func, int line, - ftdm_channel_t *fchan, ftdm_channel_state_t state); -#define ftdm_set_state(obj, s) _ftdm_set_state(__FILE__, __FTDM_FUNC__, __LINE__, obj, s); \ - -/*!\brief This macro is deprecated, signaling modules should always lock the channel themselves anyways since they must - * process first the user pending state changes then set a new state before releasing the lock - * this macro is here for backwards compatibility, DO NOT USE IT in new code since it is *always* wrong to set - * a state in a signaling module without checking and processing the current state first (and for that you must lock the channel) - */ -#define ftdm_set_state_locked(obj, s) \ - do { \ - ftdm_channel_lock(obj); \ - ftdm_channel_set_state(__FILE__, __FTDM_FUNC__, __LINE__, obj, s, 0, NULL); \ - ftdm_channel_unlock(obj); \ - } while(0); - -#define ftdm_set_state_r(obj, s, r) r = ftdm_channel_set_state(__FILE__, __FTDM_FUNC__, __LINE__, obj, s, 0); - -#define ftdm_set_state_all(span, state) \ - do { \ - uint32_t _j; \ - ftdm_mutex_lock((span)->mutex); \ - for(_j = 1; _j <= (span)->chan_count; _j++) { \ - if (!FTDM_IS_DCHAN(span->channels[_j])) { \ - ftdm_set_state_locked((span->channels[_j]), state); \ - } \ - } \ - ftdm_mutex_unlock((span)->mutex); \ - } while (0); - -#ifdef __cplusplus -} -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h deleted file mode 100755 index a498489af1..0000000000 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2007-2014, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Contributors: - * - * Moises Silva - * - */ - -#ifndef FTDM_TYPES_H -#define FTDM_TYPES_H - -#include "freetdm.h" - -#include "fsk.h" - -#ifdef WIN32 -typedef intptr_t ftdm_ssize_t; -typedef int ftdm_filehandle_t; -#else -#include -#include -#include -typedef ssize_t ftdm_ssize_t; -typedef int ftdm_filehandle_t; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define FTDM_COMMAND_OBJ_SIZE *((ftdm_size_t *)obj) -#define FTDM_COMMAND_OBJ_INT *((int *)obj) -#define FTDM_COMMAND_OBJ_CHAR_P (char *)obj -#define FTDM_COMMAND_OBJ_FLOAT *(float *)obj -#define FTDM_FSK_MOD_FACTOR 0x10000 -#define FTDM_DEFAULT_DTMF_ON 250 -#define FTDM_DEFAULT_DTMF_OFF 50 - -typedef enum { - FTDM_ENDIAN_BIG = 1, - FTDM_ENDIAN_LITTLE = -1 -} ftdm_endian_t; - -typedef enum { - FTDM_CID_TYPE_SDMF = 0x04, - FTDM_CID_TYPE_MDMF = 0x80 -} ftdm_cid_type_t; - -typedef enum { - MDMF_DATETIME = 1, - MDMF_PHONE_NUM = 2, - MDMF_DDN = 3, - MDMF_NO_NUM = 4, - MDMF_PHONE_NAME = 7, - MDMF_NO_NAME = 8, - MDMF_ALT_ROUTE = 9, - MDMF_INVALID = 10 -} ftdm_mdmf_type_t; -#define MDMF_STRINGS "X", "DATETIME", "PHONE_NUM", "DDN", "NO_NUM", "X", "X", "PHONE_NAME", "NO_NAME", "ALT_ROUTE", "INVALID" -FTDM_STR2ENUM_P(ftdm_str2ftdm_mdmf_type, ftdm_mdmf_type2str, ftdm_mdmf_type_t) - -#define FTDM_TONEMAP_LEN 128 -typedef enum { - FTDM_TONEMAP_NONE, - FTDM_TONEMAP_DIAL, - FTDM_TONEMAP_RING, - FTDM_TONEMAP_BUSY, - FTDM_TONEMAP_FAIL1, - FTDM_TONEMAP_FAIL2, - FTDM_TONEMAP_FAIL3, - FTDM_TONEMAP_ATTN, - FTDM_TONEMAP_CALLWAITING_CAS, - FTDM_TONEMAP_CALLWAITING_SAS, - FTDM_TONEMAP_CALLWAITING_ACK, - FTDM_TONEMAP_INVALID -} ftdm_tonemap_t; -#define TONEMAP_STRINGS "NONE", "DIAL", "RING", "BUSY", "FAIL1", "FAIL2", "FAIL3", "ATTN", "CALLWAITING-CAS", "CALLWAITING-SAS", "CALLWAITING-ACK", "INVALID" -FTDM_STR2ENUM_P(ftdm_str2ftdm_tonemap, ftdm_tonemap2str, ftdm_tonemap_t) - -typedef enum { - FTDM_ANALOG_START_KEWL, - FTDM_ANALOG_START_LOOP, - FTDM_ANALOG_START_GROUND, - FTDM_ANALOG_START_WINK, - FTDM_ANALOG_START_NA -} ftdm_analog_start_type_t; -#define START_TYPE_STRINGS "KEWL", "LOOP", "GROUND", "WINK", "NA" -FTDM_STR2ENUM_P(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t) - -typedef enum { - FTDM_OOB_NOOP, - FTDM_OOB_ONHOOK, - FTDM_OOB_OFFHOOK, - FTDM_OOB_WINK, - FTDM_OOB_FLASH, - FTDM_OOB_RING_START, - FTDM_OOB_RING_STOP, - FTDM_OOB_ALARM_TRAP, - FTDM_OOB_ALARM_CLEAR, - FTDM_OOB_CAS_BITS_CHANGE, - FTDM_OOB_POLARITY_REVERSE, - FTDM_OOB_INVALID -} ftdm_oob_event_t; -#define OOB_STRINGS "NOOP", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "CAS_BITS_CHANGE", "POLARITY_REVERSE", "INVALID" -FTDM_STR2ENUM_P(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t) - -/*! \brief Event types */ -typedef enum { - FTDM_EVENT_NONE, - /* DTMF digit was just detected */ - FTDM_EVENT_DTMF, - /* Out of band event */ - FTDM_EVENT_OOB, - FTDM_EVENT_COUNT -} ftdm_event_type_t; - -/*! \brief Generic event data type */ -struct ftdm_event { - ftdm_event_type_t e_type; - uint32_t enum_id; - ftdm_channel_t *channel; - void *data; -}; - -typedef enum { - FTDM_SIGTYPE_NONE, - FTDM_SIGTYPE_ISDN, - FTDM_SIGTYPE_RBS, - FTDM_SIGTYPE_ANALOG, - FTDM_SIGTYPE_SANGOMABOOST, - FTDM_SIGTYPE_M3UA, - FTDM_SIGTYPE_M2UA, - FTDM_SIGTYPE_R2, - FTDM_SIGTYPE_SS7, - FTDM_SIGTYPE_GSM -} ftdm_signal_type_t; - -typedef enum { - FTDM_SPAN_CONFIGURED = (1 << 0), - FTDM_SPAN_STARTED = (1 << 1), - FTDM_SPAN_STATE_CHANGE = (1 << 2), - FTDM_SPAN_SUSPENDED = (1 << 3), - FTDM_SPAN_IN_THREAD = (1 << 4), - FTDM_SPAN_STOP_THREAD = (1 << 5), - /*! Signaling modules set this flag to use fchan->pendingchans queue instead - * of the FTDM_SPAN_STATE_CHANGE flag to detect when there is channels with - * a state change pending in the span. If you set this member you can't rely - * on FTDM_SPAN_STATE_CHANGE anymore and must use the queue only instead. This - * is the new way of detecting state changes, new modules should always set this - * flag, the old modules still relying on FTDM_SPAN_STATE_CHANGE should be updated */ - FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6), - FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7), - FTDM_SPAN_USE_AV_RATE = (1 << 8), - FTDM_SPAN_PWR_SAVING = (1 << 9), - /* If you use this flag, you MUST call ftdm_span_trigger_signals to deliver the user signals - * after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal - * for later delivery */ - FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10), - /* If this flag is set, channel will be moved to proceed state when calls goes to routing */ - FTDM_SPAN_USE_PROCEED_STATE = (1 << 11), - /* If this flag is set, the signalling module supports jumping directly to state up, without - going through PROGRESS/PROGRESS_MEDIA */ - FTDM_SPAN_USE_SKIP_STATES = (1 << 12), - /* If this flag is set, then this span cannot be stopped individually, it can only be stopped - on freetdm unload */ - FTDM_SPAN_NON_STOPPABLE = (1 << 13), - /* If this flag is set, then this span supports TRANSFER state */ - FTDM_SPAN_USE_TRANSFER = (1 << 14), - /* This is the last flag, no more flags bigger than this */ - FTDM_SPAN_MAX_FLAG = (1 << 15), -} ftdm_span_flag_t; - -/*! \brief Channel supported features */ -typedef enum { - FTDM_CHANNEL_FEATURE_DTMF_DETECT = (1 << 0), /*!< Channel can detect DTMF (read-only) */ - FTDM_CHANNEL_FEATURE_DTMF_GENERATE = (1 << 1), /*!< Channel can generate DTMF (read-only) */ - FTDM_CHANNEL_FEATURE_CODECS = (1 << 2), /*!< Channel can do transcoding (read-only) */ - FTDM_CHANNEL_FEATURE_INTERVAL = (1 << 3), /*!< Channel support i/o interval configuration (read-only) */ - FTDM_CHANNEL_FEATURE_CALLERID = (1 << 4), /*!< Channel can detect caller id (read-only) */ - FTDM_CHANNEL_FEATURE_PROGRESS = (1 << 5), /*!< Channel can detect inband progress (read-only) */ - FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */ - FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */ - FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */ - FTDM_CHANNEL_FEATURE_IO_STATS = (1<<9), /*!< Channel supports IO statistics (HDLC channels only) */ - FTDM_CHANNEL_FEATURE_MF_GENERATE = (1<<10), /*!< Channel can generate R2 MF tones (read-only) */ -} ftdm_channel_feature_t; - -/*! \brief Channel IO pending flags */ -typedef enum { - FTDM_CHANNEL_IO_EVENT = (1 << 0), - FTDM_CHANNEL_IO_READ = (1 << 1), - FTDM_CHANNEL_IO_WRITE = (1 << 2), -} ftdm_channel_io_flags_t; - -/*!< Channel flags. This used to be an enum but we reached the 32bit limit for enums, is safer this way */ -#define FTDM_CHANNEL_CONFIGURED (1ULL << 0) -#define FTDM_CHANNEL_READY (1ULL << 1) -#define FTDM_CHANNEL_OPEN (1ULL << 2) -#define FTDM_CHANNEL_DTMF_DETECT (1ULL << 3) -#define FTDM_CHANNEL_SUPRESS_DTMF (1ULL << 4) -#define FTDM_CHANNEL_TRANSCODE (1ULL << 5) -#define FTDM_CHANNEL_BUFFER (1ULL << 6) -#define FTDM_CHANNEL_INTHREAD (1ULL << 8) -#define FTDM_CHANNEL_WINK (1ULL << 9) -#define FTDM_CHANNEL_FLASH (1ULL << 10) -#define FTDM_CHANNEL_STATE_CHANGE (1ULL << 11) -#define FTDM_CHANNEL_HOLD (1ULL << 12) -#define FTDM_CHANNEL_INUSE (1ULL << 13) -#define FTDM_CHANNEL_OFFHOOK (1ULL << 14) -#define FTDM_CHANNEL_RINGING (1ULL << 15) -#define FTDM_CHANNEL_PROGRESS_DETECT (1ULL << 16) -#define FTDM_CHANNEL_CALLERID_DETECT (1ULL << 17) -#define FTDM_CHANNEL_OUTBOUND (1ULL << 18) -#define FTDM_CHANNEL_SUSPENDED (1ULL << 19) -#define FTDM_CHANNEL_3WAY (1ULL << 20) -#define FTDM_CHANNEL_PROGRESS (1ULL << 21) -/*!< There is media on the channel already */ -#define FTDM_CHANNEL_MEDIA (1ULL << 22) -/*!< The channel was answered */ -#define FTDM_CHANNEL_ANSWERED (1ULL << 23) -#define FTDM_CHANNEL_MUTE (1ULL << 24) -#define FTDM_CHANNEL_USE_RX_GAIN (1ULL << 25) -#define FTDM_CHANNEL_USE_TX_GAIN (1ULL << 26) -#define FTDM_CHANNEL_IN_ALARM (1ULL << 27) -#define FTDM_CHANNEL_SIG_UP (1ULL << 28) -#define FTDM_CHANNEL_USER_HANGUP (1ULL << 29) -#define FTDM_CHANNEL_RX_DISABLED (1ULL << 30) -#define FTDM_CHANNEL_TX_DISABLED (1ULL << 31) -/*!< The user knows about a call in this channel */ -#define FTDM_CHANNEL_CALL_STARTED (1ULL << 32) -/*!< The user wants non-blocking operations in the channel */ -#define FTDM_CHANNEL_NONBLOCK (1ULL << 33) -/*!< There is a pending acknowledge for an indication */ -#define FTDM_CHANNEL_IND_ACK_PENDING (1ULL << 34) -/*!< There is someone blocking in the channel waiting for state completion */ -#define FTDM_CHANNEL_BLOCKING (1ULL << 35) -/*!< Media is digital */ -#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36) -/*!< Native signaling bridge is enabled */ -#define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37) -/*!< Native signaling DTMF detection */ -#define FTDM_CHANNEL_SIG_DTMF_DETECTION (1ULL << 38) - -/*!< This no more flags after this flag */ -#define FTDM_CHANNEL_MAX_FLAG (1ULL << 39) -/*! - * - * Copyright (C) 2001 Steve Underwood - * - * Despite my general liking of the GPL, I place this code in the - * public domain for the benefit of all mankind - even the slimy - * ones who might try to proprietize my work and use it to my - * detriment. - * - * $Id: g711.h,v 1.1 2006/06/07 15:46:39 steveu Exp $ - */ - -/*! \file */ - -/*! \page g711_page A-law and mu-law handling - Lookup tables for A-law and u-law look attractive, until you consider the impact - on the CPU cache. If it causes a substantial area of your processor cache to get - hit too often, cache sloshing will severely slow things down. The main reason - these routines are slow in C, is the lack of direct access to the CPU's "find - the first 1" instruction. A little in-line assembler fixes that, and the - conversion routines can be faster than lookup tables, in most real world usage. - A "find the first 1" instruction is available on most modern CPUs, and is a - much underused feature. - - If an assembly language method of bit searching is not available, these routines - revert to a method that can be a little slow, so the cache thrashing might not - seem so bad :( - - Feel free to submit patches to add fast "find the first 1" support for your own - favourite processor. - - Look up tables are used for transcoding between A-law and u-law, since it is - difficult to achieve the precise transcoding procedure laid down in the G.711 - specification by other means. -*/ - -#if !defined(_G711_H_) -#define _G711_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif - typedef unsigned __int8 uint8_t; - typedef __int16 int16_t; - typedef __int32 int32_t; - typedef unsigned __int16 uint16_t; -#else -#include -#endif - -#if defined(__i386__) - /*! \brief Find the bit position of the highest set bit in a word - \param bits The word to be searched - \return The bit number of the highest set bit, or -1 if the word is zero. */ - static __inline__ int top_bit(unsigned int bits) - { - int res; - - __asm__ __volatile__(" movl $-1,%%edx;\n" - " bsrl %%eax,%%edx;\n" - : "=d" (res) - : "a" (bits)); - return res; - } - /*- End of function --------------------------------------------------------*/ - - /*! \brief Find the bit position of the lowest set bit in a word - \param bits The word to be searched - \return The bit number of the lowest set bit, or -1 if the word is zero. */ - static __inline__ int bottom_bit(unsigned int bits) - { - int res; - - __asm__ __volatile__(" movl $-1,%%edx;\n" - " bsfl %%eax,%%edx;\n" - : "=d" (res) - : "a" (bits)); - return res; - } - /*- End of function --------------------------------------------------------*/ -#elif defined(__x86_64__) - static __inline__ int top_bit(unsigned int bits) - { - int res; - - __asm__ __volatile__(" movq $-1,%%rdx;\n" - " bsrq %%rax,%%rdx;\n" - : "=d" (res) - : "a" (bits)); - return res; - } - /*- End of function --------------------------------------------------------*/ - - static __inline__ int bottom_bit(unsigned int bits) - { - int res; - - __asm__ __volatile__(" movq $-1,%%rdx;\n" - " bsfq %%rax,%%rdx;\n" - : "=d" (res) - : "a" (bits)); - return res; - } - /*- End of function --------------------------------------------------------*/ -#else - static __inline__ int top_bit(unsigned int bits) - { - int i; - - if (bits == 0) - return -1; - i = 0; - if (bits & 0xFFFF0000) - { - bits &= 0xFFFF0000; - i += 16; - } - if (bits & 0xFF00FF00) - { - bits &= 0xFF00FF00; - i += 8; - } - if (bits & 0xF0F0F0F0) - { - bits &= 0xF0F0F0F0; - i += 4; - } - if (bits & 0xCCCCCCCC) - { - bits &= 0xCCCCCCCC; - i += 2; - } - if (bits & 0xAAAAAAAA) - { - bits &= 0xAAAAAAAA; - i += 1; - } - return i; - } - /*- End of function --------------------------------------------------------*/ - - static __inline__ int bottom_bit(unsigned int bits) - { - int i; - - if (bits == 0) - return -1; - i = 32; - if (bits & 0x0000FFFF) - { - bits &= 0x0000FFFF; - i -= 16; - } - if (bits & 0x00FF00FF) - { - bits &= 0x00FF00FF; - i -= 8; - } - if (bits & 0x0F0F0F0F) - { - bits &= 0x0F0F0F0F; - i -= 4; - } - if (bits & 0x33333333) - { - bits &= 0x33333333; - i -= 2; - } - if (bits & 0x55555555) - { - bits &= 0x55555555; - i -= 1; - } - return i; - } - /*- End of function --------------------------------------------------------*/ -#endif - - /* N.B. It is tempting to use look-up tables for A-law and u-law conversion. - * However, you should consider the cache footprint. - * - * A 64K byte table for linear to x-law and a 512 byte table for x-law to - * linear sound like peanuts these days, and shouldn't an array lookup be - * real fast? No! When the cache sloshes as badly as this one will, a tight - * calculation may be better. The messiest part is normally finding the - * segment, but a little inline assembly can fix that on an i386, x86_64 and - * many other modern processors. - */ - - /* - * Mu-law is basically as follows: - * - * Biased Linear Input Code Compressed Code - * ------------------------ --------------- - * 00000001wxyza 000wxyz - * 0000001wxyzab 001wxyz - * 000001wxyzabc 010wxyz - * 00001wxyzabcd 011wxyz - * 0001wxyzabcde 100wxyz - * 001wxyzabcdef 101wxyz - * 01wxyzabcdefg 110wxyz - * 1wxyzabcdefgh 111wxyz - * - * Each biased linear code has a leading 1 which identifies the segment - * number. The value of the segment number is equal to 7 minus the number - * of leading 0's. The quantization interval is directly available as the - * four bits wxyz. * The trailing bits (a - h) are ignored. - * - * Ordinarily the complement of the resulting code word is used for - * transmission, and so the code word is complemented before it is returned. - * - * For further information see John C. Bellamy's Digital Telephony, 1982, - * John Wiley & Sons, pps 98-111 and 472-476. - */ - - /*#define ULAW_ZEROTRAP*/ /* turn on the trap as per the MIL-STD */ -#define ULAW_BIAS 0x84 /* Bias for linear code. */ - - /*! \brief Encode a linear sample to u-law - \param linear The sample to encode. - \return The u-law value. - */ - static __inline__ uint8_t linear_to_ulaw(int linear) - { - uint8_t u_val; - int mask; - int seg; - - /* Get the sign and the magnitude of the value. */ - if (linear < 0) - { - linear = ULAW_BIAS - linear; - mask = 0x7F; - } - else - { - linear = ULAW_BIAS + linear; - mask = 0xFF; - } - - seg = top_bit(linear | 0xFF) - 7; - - /* - * Combine the sign, segment, quantization bits, - * and complement the code word. - */ - if (seg >= 8) - u_val = (uint8_t) (0x7F ^ mask); - else - u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask); -#ifdef ULAW_ZEROTRAP - /* Optional ITU trap */ - if (u_val == 0) - u_val = 0x02; -#endif - return u_val; - } - /*- End of function --------------------------------------------------------*/ - - /*! \brief Decode an u-law sample to a linear value. - \param ulaw The u-law sample to decode. - \return The linear value. - */ - static __inline__ int16_t ulaw_to_linear(uint8_t ulaw) - { - int t; - - /* Complement to obtain normal u-law value. */ - ulaw = ~ulaw; - /* - * Extract and bias the quantization bits. Then - * shift up by the segment number and subtract out the bias. - */ - t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4); - return (int16_t) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS)); - } - /*- End of function --------------------------------------------------------*/ - - /* - * A-law is basically as follows: - * - * Linear Input Code Compressed Code - * ----------------- --------------- - * 0000000wxyza 000wxyz - * 0000001wxyza 001wxyz - * 000001wxyzab 010wxyz - * 00001wxyzabc 011wxyz - * 0001wxyzabcd 100wxyz - * 001wxyzabcde 101wxyz - * 01wxyzabcdef 110wxyz - * 1wxyzabcdefg 111wxyz - * - * For further information see John C. Bellamy's Digital Telephony, 1982, - * John Wiley & Sons, pps 98-111 and 472-476. - */ - -#define ALAW_AMI_MASK 0x55 - - /*! \brief Encode a linear sample to A-law - \param linear The sample to encode. - \return The A-law value. - */ - static __inline__ uint8_t linear_to_alaw(int linear) - { - int mask; - int seg; - - if (linear >= 0) - { - /* Sign (bit 7) bit = 1 */ - mask = ALAW_AMI_MASK | 0x80; - } - else - { - /* Sign (bit 7) bit = 0 */ - mask = ALAW_AMI_MASK; - linear = -linear - 8; - } - - /* Convert the scaled magnitude to segment number. */ - seg = top_bit(linear | 0xFF) - 7; - if (seg >= 8) - { - if (linear >= 0) - { - /* Out of range. Return maximum value. */ - return (uint8_t) (0x7F ^ mask); - } - /* We must be just a tiny step below zero */ - return (uint8_t) (0x00 ^ mask); - } - /* Combine the sign, segment, and quantization bits. */ - return (uint8_t) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask); - } - /*- End of function --------------------------------------------------------*/ - - /*! \brief Decode an A-law sample to a linear value. - \param alaw The A-law sample to decode. - \return The linear value. - */ - static __inline__ int16_t alaw_to_linear(uint8_t alaw) - { - int i; - int seg; - - alaw ^= ALAW_AMI_MASK; - i = ((alaw & 0x0F) << 4); - seg = (((int) alaw & 0x70) >> 4); - if (seg) - i = (i + 0x108) << (seg - 1); - else - i += 8; - return (int16_t) ((alaw & 0x80) ? i : -i); - } - /*- End of function --------------------------------------------------------*/ - - /*! \brief Transcode from A-law to u-law, using the procedure defined in G.711. - \param alaw The A-law sample to transcode. - \return The best matching u-law value. - */ - uint8_t alaw_to_ulaw(uint8_t alaw); - - /*! \brief Transcode from u-law to A-law, using the procedure defined in G.711. - \param alaw The u-law sample to transcode. - \return The best matching A-law value. - */ - uint8_t ulaw_to_alaw(uint8_t ulaw); - -#ifdef __cplusplus -} -#endif - -#endif -/*- End of file ------------------------------------------------------------*/ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/hashtable.h b/libs/freetdm/src/include/private/hashtable.h deleted file mode 100644 index 5d029b5b85..0000000000 --- a/libs/freetdm/src/include/private/hashtable.h +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 2002 Christopher Clark */ - -#ifndef __HASHTABLE_CWC22_H__ -#define __HASHTABLE_CWC22_H__ -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif -#endif -#include "freetdm.h" - -#ifdef __cplusplus -extern "C" { -#endif -struct hashtable; -struct hashtable_iterator; - -/* Example of use: - * - * struct hashtable *h; - * struct some_key *k; - * struct some_value *v; - * - * static unsigned int hash_from_key_fn( void *k ); - * static int keys_equal_fn ( void *key1, void *key2 ); - * - * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn); - * k = (struct some_key *) malloc(sizeof(struct some_key)); - * v = (struct some_value *) malloc(sizeof(struct some_value)); - * - * (initialise k and v to suitable values) - * - * if (! hashtable_insert(h,k,v) ) - * { exit(-1); } - * - * if (NULL == (found = hashtable_search(h,k) )) - * { printf("not found!"); } - * - * if (NULL == (found = hashtable_remove(h,k) )) - * { printf("Not found\n"); } - * - */ - -/* Macros may be used to define type-safe(r) hashtable access functions, with - * methods specialized to take known key and value types as parameters. - * - * Example: - * - * Insert this at the start of your file: - * - * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value); - * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value); - * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value); - * - * This defines the functions 'insert_some', 'search_some' and 'remove_some'. - * These operate just like hashtable_insert etc., with the same parameters, - * but their function signatures have 'struct some_key *' rather than - * 'void *', and hence can generate compile time errors if your program is - * supplying incorrect data as a key (and similarly for value). - * - * Note that the hash and key equality functions passed to create_hashtable - * still take 'void *' parameters instead of 'some key *'. This shouldn't be - * a difficult issue as they're only defined and passed once, and the other - * functions will ensure that only valid keys are supplied to them. - * - * The cost for this checking is increased code size and runtime overhead - * - if performance is important, it may be worth switching back to the - * unsafe methods once your program has been debugged with the safe methods. - * This just requires switching to some simple alternative defines - eg: - * #define insert_some hashtable_insert - * - */ - -/***************************************************************************** - * create_hashtable - - * @name create_hashtable - * @param minsize minimum initial size of hashtable - * @param hashfunction function for hashing keys - * @param key_eq_fn function for determining key equality - * @return newly created hashtable or NULL on failure - */ - -FT_DECLARE(struct hashtable *) -create_hashtable(unsigned int minsize, - unsigned int (*hashfunction) (void*), - int (*key_eq_fn) (void*,void*)); - -/***************************************************************************** - * hashtable_insert - - * @name hashtable_insert - * @param h the hashtable to insert into - * @param k the key - hashtable claims ownership and will free on removal - * @param v the value - does not claim ownership - * @return non-zero for successful insertion - * - * This function will cause the table to expand if the insertion would take - * the ratio of entries to table size over the maximum load factor. - * - * This function does not check for repeated insertions with a duplicate key. - * The value returned when using a duplicate key is undefined -- when - * the hashtable changes size, the order of retrieval of duplicate key - * entries is reversed. - * If in doubt, remove before insert. - */ - - -typedef enum { - HASHTABLE_FLAG_NONE = 0, - HASHTABLE_FLAG_FREE_KEY = (1 << 0), - HASHTABLE_FLAG_FREE_VALUE = (1 << 1) -} hashtable_flag_t; - -FT_DECLARE(int) -hashtable_insert(struct hashtable *h, void *k, void *v, hashtable_flag_t flags); - -#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \ - int fnname (struct hashtable *h, keytype *k, valuetype *v) \ - { \ - return hashtable_insert(h,k,v); \ - } - -/***************************************************************************** - * hashtable_search - - * @name hashtable_search - * @param h the hashtable to search - * @param k the key to search for - does not claim ownership - * @return the value associated with the key, or NULL if none found - */ - -FT_DECLARE(void *) -hashtable_search(struct hashtable *h, void *k); - -#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \ - valuetype * fnname (struct hashtable *h, keytype *k) \ - { \ - return (valuetype *) (hashtable_search(h,k)); \ - } - -/***************************************************************************** - * hashtable_remove - - * @name hashtable_remove - * @param h the hashtable to remove the item from - * @param k the key to search for - does not claim ownership - * @return the value associated with the key, or NULL if none found - */ - -FT_DECLARE(void *) /* returns value */ -hashtable_remove(struct hashtable *h, void *k); - -#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \ - valuetype * fnname (struct hashtable *h, keytype *k) \ - { \ - return (valuetype *) (hashtable_remove(h,k)); \ - } - - -/***************************************************************************** - * hashtable_count - - * @name hashtable_count - * @param h the hashtable - * @return the number of items stored in the hashtable - */ -FT_DECLARE(unsigned int) -hashtable_count(struct hashtable *h); - - -/***************************************************************************** - * hashtable_destroy - - * @name hashtable_destroy - * @param h the hashtable - * @param free_values whether to call 'free' on the remaining values - */ - -FT_DECLARE(void) -hashtable_destroy(struct hashtable *h); - -FT_DECLARE(struct hashtable_iterator*) hashtable_first(struct hashtable *h); -FT_DECLARE(struct hashtable_iterator*) hashtable_next(struct hashtable_iterator *i); -FT_DECLARE(void) hashtable_this(struct hashtable_iterator *i, const void **key, int *klen, void **val); - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif /* __HASHTABLE_CWC22_H__ */ - -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/hashtable_itr.h b/libs/freetdm/src/include/private/hashtable_itr.h deleted file mode 100644 index bf0a6e19d0..0000000000 --- a/libs/freetdm/src/include/private/hashtable_itr.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright (C) 2002, 2004 Christopher Clark */ - -#ifndef __HASHTABLE_ITR_CWC22__ -#define __HASHTABLE_ITR_CWC22__ -#include "hashtable.h" -#include "hashtable_private.h" /* needed to enable inlining */ - -#ifdef __cplusplus -extern "C" { -#endif -/*****************************************************************************/ -/* This struct is only concrete here to allow the inlining of two of the - * accessor functions. */ -struct hashtable_itr -{ - struct hashtable *h; - struct entry *e; - struct entry *parent; - unsigned int index; -}; - - -/*****************************************************************************/ -/* hashtable_iterator - */ - -struct hashtable_itr * -hashtable_iterator(struct hashtable *h); - -/*****************************************************************************/ -/* hashtable_iterator_key - * - return the value of the (key,value) pair at the current position */ -extern __inline__ void * -hashtable_iterator_key(struct hashtable_itr *i); - -extern __inline__ void * -hashtable_iterator_key(struct hashtable_itr *i) -{ - return i->e->k; -} - -/*****************************************************************************/ -/* value - return the value of the (key,value) pair at the current position */ - -extern __inline__ void * -hashtable_iterator_value(struct hashtable_itr *i); - -extern __inline__ void * -hashtable_iterator_value(struct hashtable_itr *i) -{ - return i->e->v; -} - -/*****************************************************************************/ -/* advance - advance the iterator to the next element - * returns zero if advanced to end of table */ - -int -hashtable_iterator_advance(struct hashtable_itr *itr); - -/*****************************************************************************/ -/* remove - remove current element and advance the iterator to the next element - * NB: if you need the value to free it, read it before - * removing. ie: beware memory leaks! - * returns zero if advanced to end of table */ - -int -hashtable_iterator_remove(struct hashtable_itr *itr); - -/*****************************************************************************/ -/* search - overwrite the supplied iterator, to point to the entry - * matching the supplied key. - h points to the hashtable to be searched. - * returns zero if not found. */ -int -hashtable_iterator_search(struct hashtable_itr *itr, - struct hashtable *h, void *k); - -#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \ - int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \ - { \ - return (hashtable_iterator_search(i,h,k)); \ - } - -#ifdef __cplusplus -} -#endif - -#endif /* __HASHTABLE_ITR_CWC22__*/ - -/* - * Copyright (c) 2002, 2004, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/include/private/hashtable_private.h b/libs/freetdm/src/include/private/hashtable_private.h deleted file mode 100644 index 35f22091ef..0000000000 --- a/libs/freetdm/src/include/private/hashtable_private.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (C) 2002, 2004 Christopher Clark */ - -#ifndef __HASHTABLE_PRIVATE_CWC22_H__ -#define __HASHTABLE_PRIVATE_CWC22_H__ - -#include "hashtable.h" - -#ifdef __cplusplus -extern "C" { -#endif -/*****************************************************************************/ - -struct entry -{ - void *k, *v; - unsigned int h; - hashtable_flag_t flags; - struct entry *next; -}; - -struct hashtable_iterator { - unsigned int pos; - struct entry *e; - struct hashtable *h; -}; - -struct hashtable { - unsigned int tablelength; - struct entry **table; - unsigned int entrycount; - unsigned int loadlimit; - unsigned int primeindex; - unsigned int (*hashfn) (void *k); - int (*eqfn) (void *k1, void *k2); - struct hashtable_iterator iterator; -}; - -/*****************************************************************************/ -unsigned int -hash(struct hashtable *h, void *k); - -/*****************************************************************************/ -/* indexFor */ -static __inline__ unsigned int -indexFor(unsigned int tablelength, unsigned int hashvalue) { - return (hashvalue % tablelength); -} - -/* Only works if tablelength == 2^N */ -/*static inline unsigned int - indexFor(unsigned int tablelength, unsigned int hashvalue) - { - return (hashvalue & (tablelength - 1u)); - } -*/ - -/*****************************************************************************/ -#define freekey(X) free(X) -/*define freekey(X) ; */ - -#ifdef __cplusplus -} -#endif - -/*****************************************************************************/ - -#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/ - -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/libteletone.h b/libs/freetdm/src/include/private/libteletone.h deleted file mode 100644 index 060a226032..0000000000 --- a/libs/freetdm/src/include/private/libteletone.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * libteletone - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is libteletone - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * libteletone.h -- Tone Generator/Detector - * - * - * - * Exception: - * The author hereby grants the use of this source code under the - * following license if and only if the source code is distributed - * as part of the OpenZAP or FreeTDM library. Any use or distribution of this - * source code outside the scope of the OpenZAP or FreeTDM library will nullify the - * following license and reinact the MPL 1.1 as stated above. - * - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef LIBTELETONE_H -#define LIBTELETONE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define TELETONE_MAX_DTMF_DIGITS 128 -#define TELETONE_MAX_TONES 18 -#define TELETONE_TONE_RANGE 127 - -typedef double teletone_process_t; - -/*! \file libteletone.h - \brief Top level include file - - This file should be included by applications using the library -*/ - -/*! \brief An abstraction to store a tone mapping */ -typedef struct { - /*! An array of tone frequencies */ - teletone_process_t freqs[TELETONE_MAX_TONES]; -} teletone_tone_map_t; - -#if !defined(M_PI) -/* C99 systems may not define M_PI */ -#define M_PI 3.14159265358979323846264338327 -#endif - -#ifdef _MSC_VER -typedef __int16 int16_t; -#endif - -#if (_MSC_VER >= 1400) // VC8+ -#define teletone_assert(expr) assert(expr);__analysis_assume( expr ) -#else -#define teletone_assert(expr) assert(expr) -#endif - -#ifdef _MSC_VER -#if defined(TT_DECLARE_STATIC) -#define TELETONE_API(type) type __stdcall -#define TELETONE_API_NONSTD(type) type __cdecl -#define TELETONE_API_DATA -#elif defined(TELETONE_EXPORTS) -#define TELETONE_API(type) __declspec(dllexport) type __stdcall -#define TELETONE_API_NONSTD(type) __declspec(dllexport) type __cdecl -#define TELETONE_API_DATA __declspec(dllexport) -#else -#define TELETONE_API(type) __declspec(dllimport) type __stdcall -#define TELETONE_API_NONSTD(type) __declspec(dllimport) type __cdecl -#define TELETONE_API_DATA __declspec(dllimport) -#endif -#else -#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(HAVE_VISIBILITY) -#define TELETONE_API(type) __attribute__((visibility("default"))) type -#define TELETONE_API_NONSTD(type) __attribute__((visibility("default"))) type -#define TELETONE_API_DATA __attribute__((visibility("default"))) -#else -#define TELETONE_API(type) type -#define TELETONE_API_NONSTD(type) type -#define TELETONE_API_DATA -#endif -#endif - -#include "libteletone_generate.h" -#include "libteletone_detect.h" - -#ifdef HAVE_STRING_H -#include -#endif - -#ifdef __cplusplus -} -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/libteletone_detect.h b/libs/freetdm/src/include/private/libteletone_detect.h deleted file mode 100644 index 646b03e1be..0000000000 --- a/libs/freetdm/src/include/private/libteletone_detect.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - * libteletone - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF. - * - * - * The Initial Developer of the Original Code is - * Stephen Underwood - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * The the original interface designed by Steve Underwood was preserved to retain - *the optimizations when considering DTMF tones though the names were changed in the interest - * of namespace. - * - * Much less efficient expansion interface was added to allow for the detection of - * a single arbitrary tone combination which may also exceed 2 simultaneous tones. - * (controlled by compile time constant TELETONE_MAX_TONES) - * - * Copyright (C) 2006 Anthony Minessale II - * - * - * libteletone_detect.c Tone Detection Code - * - * - ********************************************************************************* - * - * Derived from tone_detect.h - General telephony tone detection, and specific - * detection of DTMF. - * - * Copyright (C) 2001 Steve Underwood - * - * Despite my general liking of the GPL, I place this code in the - * public domain for the benefit of all mankind - even the slimy - * ones who might try to proprietize my work and use it to my - * detriment. - * - * - * Exception: - * The author hereby grants the use of this source code under the - * following license if and only if the source code is distributed - * as part of the OpenZAP or FreeTDM library. Any use or distribution of this - * source code outside the scope of the OpenZAP or FreeTDM library will nullify the - * following license and reinact the MPL 1.1 as stated above. - * - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LIBTELETONE_DETECT_H -#define LIBTELETONE_DETECT_H - -#ifdef __cplusplus -extern "C" { -#endif -#include "libteletone.h" - - /*! \file libteletone_detect.h - \brief Tone Detection Routines - - This module is responsible for tone detection specifics - */ - -#ifndef FALSE -#define FALSE 0 -#ifndef TRUE -#define TRUE (!FALSE) -#endif -#endif - - /* Basic DTMF specs: - * - * Minimum tone on = 40ms - * Minimum tone off = 50ms - * Maximum digit rate = 10 per second - * Normal twist <= 8dB accepted - * Reverse twist <= 4dB accepted - * S/N >= 15dB will detect OK - * Attenuation <= 26dB will detect OK - * Frequency tolerance +- 1.5% will detect, +-3.5% will reject - */ - -#define DTMF_THRESHOLD 8.0e7 -#define DTMF_NORMAL_TWIST 6.3 /* 8dB */ -#define DTMF_REVERSE_TWIST 2.5 /* 4dB */ -#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */ -#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */ -#define DTMF_2ND_HARMONIC_ROW 2.5 /* 4dB */ -#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */ -#define GRID_FACTOR 4 -#define BLOCK_LEN 102 -#define M_TWO_PI 2.0*M_PI - - typedef enum { - TT_HIT_NONE = 0, - TT_HIT_BEGIN = 1, - TT_HIT_MIDDLE = 2, - TT_HIT_END = 3 - } teletone_hit_type_t; - - - /*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */ - typedef struct { - float v2; - float v3; - double fac; - } teletone_goertzel_state_t; - - /*! \brief A container for a DTMF detection state.*/ - typedef struct { - int hit1; - int hit2; - int hit3; - int hit4; - int dur; - int zc; - - - teletone_goertzel_state_t row_out[GRID_FACTOR]; - teletone_goertzel_state_t col_out[GRID_FACTOR]; - teletone_goertzel_state_t row_out2nd[GRID_FACTOR]; - teletone_goertzel_state_t col_out2nd[GRID_FACTOR]; - float energy; - float lenergy; - - int current_sample; - char digit; - int current_digits; - int detected_digits; - int lost_digits; - int digit_hits[16]; - } teletone_dtmf_detect_state_t; - - /*! \brief An abstraction to store the coefficient of a tone frequency */ - typedef struct { - float fac; - } teletone_detection_descriptor_t; - - /*! \brief A container for a single multi-tone detection - TELETONE_MAX_TONES dictates the maximum simultaneous tones that can be present - in a multi-tone representation. - */ - typedef struct { - int sample_rate; - - teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES]; - teletone_goertzel_state_t gs[TELETONE_MAX_TONES]; - teletone_goertzel_state_t gs2[TELETONE_MAX_TONES]; - int tone_count; - - float energy; - int current_sample; - - int min_samples; - int total_samples; - - int positives; - int negatives; - int hits; - - int positive_factor; - int negative_factor; - int hit_factor; - - } teletone_multi_tone_t; - - - /*! - \brief Initilize a multi-frequency tone detector - \param mt the multi-frequency tone descriptor - \param map a representation of the multi-frequency tone - */ -TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map); - - /*! - \brief Check a sample buffer for the presence of the mulit-frequency tone described by mt - \param mt the multi-frequency tone descriptor - \param sample_buffer an array aof 16 bit signed linear samples - \param samples the number of samples present in sample_buffer - \return true when the tone was detected or false when it is not - */ -TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt, - int16_t sample_buffer[], - int samples); - - /*! - \brief Initilize a DTMF detection state object - \param dtmf_detect_state the DTMF detection state to initilize - \param sample_rate the desired sample rate - */ -TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate); - - /*! - \brief Check a sample buffer for the presence of DTMF digits - \param dtmf_detect_state the detection state object to check - \param sample_buffer an array aof 16 bit signed linear samples - \param samples the number of samples present in sample_buffer - \return true when DTMF was detected or false when it is not - */ -TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state, - int16_t sample_buffer[], - int samples); - /*! - \brief retrieve any collected digits into a string buffer - \param dtmf_detect_state the detection state object to check - \param buf the string buffer to write to - \param max the maximum length of buf - \return the number of characters written to buf - */ -TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur); - - /*! - \brief Step through the Goertzel Algorithm for each sample in a buffer - \param goertzel_state the goertzel state to step the samples through - \param sample_buffer an array aof 16 bit signed linear samples - \param samples the number of samples present in sample_buffer - */ -TELETONE_API(void) teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state, - int16_t sample_buffer[], - int samples); - - - -#ifdef __cplusplus -} -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/libteletone_generate.h b/libs/freetdm/src/include/private/libteletone_generate.h deleted file mode 100644 index d5f0bf2e48..0000000000 --- a/libs/freetdm/src/include/private/libteletone_generate.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * libteletone - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is libteletone - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * libteletone.h -- Tone Generator - * - * - * - * Exception: - * The author hereby grants the use of this source code under the - * following license if and only if the source code is distributed - * as part of the OpenZAP or FreeTDM library. Any use or distribution of this - * source code outside the scope of the OpenZAP or FreeTDM library will nullify the - * following license and reinact the MPL 1.1 as stated above. - * - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef LIBTELETONE_GENERATE_H -#define LIBTELETONE_GENERATE_H -#ifdef __cplusplus -extern "C" { -#ifdef _doh -} -#endif -#endif - -#include -#include - -#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) -#ifndef __inline__ -#define __inline__ inline -#endif -#endif - -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif - -typedef unsigned __int64 uint64_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int8 uint8_t; -typedef __int64 int64_t; -typedef __int32 int32_t; -typedef __int16 int16_t; -typedef __int8 int8_t; -#else -#include -#endif -#include -#include -#include -#include -#if !defined(powf) && !defined(_WIN64) -extern float powf (float, float); -#endif -#include -#include -#ifndef _MSC_VER -#include -#endif -#include -#include -#include "libteletone.h" - -#define TELETONE_VOL_DB_MAX 0 -#define TELETONE_VOL_DB_MIN -63 -#define MAX_PHASE_TONES 4 - -struct teletone_dds_state { - uint32_t phase_rate[MAX_PHASE_TONES]; - uint32_t scale_factor; - uint32_t phase_accumulator; - teletone_process_t tx_level; -}; -typedef struct teletone_dds_state teletone_dds_state_t; - -#define SINE_TABLE_MAX 128 -#define SINE_TABLE_LEN (SINE_TABLE_MAX - 1) -#define MAX_PHASE_ACCUMULATOR 0x10000 * 0x10000 -/* 3.14 == the max power on ulaw (alaw is 3.17) */ -/* 3.02 represents twice the power */ -#define DBM0_MAX_POWER (3.14f + 3.02f) - -TELETONE_API_DATA extern int16_t TELETONE_SINES[SINE_TABLE_MAX]; - -static __inline__ int32_t teletone_dds_phase_rate(teletone_process_t tone, uint32_t rate) -{ - return (int32_t) ((tone * MAX_PHASE_ACCUMULATOR) / rate); -} - -static __inline__ int16_t teletone_dds_state_modulate_sample(teletone_dds_state_t *dds, uint32_t pindex) -{ - int32_t bitmask = dds->phase_accumulator, sine_index = (bitmask >>= 23) & SINE_TABLE_LEN; - int16_t sample; - - if (pindex >= MAX_PHASE_TONES) { - pindex = 0; - } - - if (bitmask & SINE_TABLE_MAX) { - sine_index = SINE_TABLE_LEN - sine_index; - } - - sample = TELETONE_SINES[sine_index]; - - if (bitmask & (SINE_TABLE_MAX * 2)) { - sample *= -1; - } - - dds->phase_accumulator += dds->phase_rate[pindex]; - return (int16_t) (sample * dds->scale_factor >> 15); -} - -static __inline__ void teletone_dds_state_set_tx_level(teletone_dds_state_t *dds, float tx_level) -{ - dds->scale_factor = (int) (powf(10.0f, (tx_level - DBM0_MAX_POWER) / 20.0f) * (32767.0f * 1.414214f)); - dds->tx_level = tx_level; -} - -static __inline__ void teletone_dds_state_reset_accum(teletone_dds_state_t *dds) -{ - dds->phase_accumulator = 0; -} - -static __inline__ int teletone_dds_state_set_tone(teletone_dds_state_t *dds, teletone_process_t tone, uint32_t rate, uint32_t pindex) -{ - if (pindex < MAX_PHASE_TONES) { - dds->phase_rate[pindex] = teletone_dds_phase_rate(tone, rate); - return 0; - } - - return -1; -} - - - -/*! \file libteletone_generate.h - \brief Tone Generation Routines - - This module is responsible for tone generation specifics -*/ - -typedef int16_t teletone_audio_t; -struct teletone_generation_session; -typedef int (*tone_handler)(struct teletone_generation_session *ts, teletone_tone_map_t *map); - -/*! \brief An abstraction to store a tone generation session */ -struct teletone_generation_session { - /*! An array of tone mappings to character mappings */ - teletone_tone_map_t TONES[TELETONE_TONE_RANGE]; - /*! The number of channels the output audio should be in */ - int channels; - /*! The Rate in hz of the output audio */ - int rate; - /*! The duration (in samples) of the output audio */ - int duration; - /*! The duration of silence to append after the initial audio is generated */ - int wait; - /*! The duration (in samples) of the output audio (takes prescedence over actual duration value) */ - int tmp_duration; - /*! The duration of silence to append after the initial audio is generated (takes prescedence over actual wait value)*/ - int tmp_wait; - /*! Number of loops to repeat a single instruction*/ - int loops; - /*! Number of loops to repeat the entire set of instructions*/ - int LOOPS; - /*! Number to mutiply total samples by to determine when to begin ascent or decent e.g. 0=beginning 4=(last 25%) */ - float decay_factor; - /*! Direction to perform volume increase/decrease 1/-1*/ - int decay_direction; - /*! Number of samples between increase/decrease of volume */ - int decay_step; - /*! Volume factor of the tone */ - float volume; - /*! Debug on/off */ - int debug; - /*! FILE stream to write debug data to */ - FILE *debug_stream; - /*! Extra user data to attach to the session*/ - void *user_data; - /*! Buffer for storing sample data (dynamic) */ - teletone_audio_t *buffer; - /*! Size of the buffer */ - int datalen; - /*! In-Use size of the buffer */ - int samples; - /*! Callback function called during generation */ - int dynamic; - tone_handler handler; -}; - -typedef struct teletone_generation_session teletone_generation_session_t; - - -/*! - \brief Assign a set of tones to a tone_session indexed by a paticular index/character - \param ts the tone generation session - \param index the index to map the tone to - \param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0 - \return 0 -*/ -TELETONE_API(int) teletone_set_tone(teletone_generation_session_t *ts, int index, ...); - -/*! - \brief Assign a set of tones to a single tone map - \param map the map to assign the tones to - \param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0 - \return 0 -*/ -TELETONE_API(int) teletone_set_map(teletone_tone_map_t *map, ...); - -/*! - \brief Initilize a tone generation session - \param ts the tone generation session to initilize - \param buflen the size of the buffer(in samples) to dynamically allocate - \param handler a callback function to execute when a tone generation instruction is complete - \param user_data optional user data to send - \return 0 -*/ -TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data); - -/*! - \brief Free the buffer allocated by a tone generation session - \param ts the tone generation session to destroy - \return 0 -*/ -TELETONE_API(int) teletone_destroy_session(teletone_generation_session_t *ts); - -/*! - \brief Execute a single tone generation instruction - \param ts the tone generation session to consult for parameters - \param map the tone mapping to use for the frequencies - \return 0 -*/ -TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map); - -/*! - \brief Execute a tone generation script and call callbacks after each instruction - \param ts the tone generation session to execute on - \param cmd the script to execute - \return 0 -*/ -TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd); - -#ifdef __cplusplus -} -#endif - -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/include/private/sangoma_tdm_api.h b/libs/freetdm/src/include/private/sangoma_tdm_api.h deleted file mode 100644 index 6880199110..0000000000 --- a/libs/freetdm/src/include/private/sangoma_tdm_api.h +++ /dev/null @@ -1,321 +0,0 @@ -/***************************************************************************** - * sangoma_tdm_api.h Sangoma TDM API Portability functions - * - * Author(s): Anthony Minessale II - * Nenad Corbic - * Michael Jerris - * David Rokhvarg - * - * Copyright: (c) 2006 Nenad Corbic - * Anthony Minessale II - * (c) 1984-2007 Sangoma Technologies Inc. - * - * ============================================================================ - */ - -#ifndef _SANGOMA_TDM_API_H -#define _SANGOMA_TDM_API_H - -/* This entire block of defines and includes from this line, through #define FNAME_LEN probably dont belong here */ -/* most of them probably belong in wanpipe_defines.h, then each header file listed included below properly included */ -/* in the header files that depend on them, leaving only the include for wanpipe_tdm_api.h left in this file or */ -/* possibly integrating the rest of this file diretly into wanpipe_tdm_api.h */ -#ifndef __WINDOWS__ -#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) -#define __WINDOWS__ -#endif /* defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) */ -#endif /* ndef __WINDOWS__ */ - -#if defined(__WINDOWS__) -#if defined(_MSC_VER) -/* disable some warnings caused by wanpipe headers that will need to be fixed in those headers */ -#pragma warning(disable:4201 4214) - -/* sang_api.h(74) : warning C4201: nonstandard extension used : nameless struct/union */ - -/* wanpipe_defines.h(219) : warning C4214: nonstandard extension used : bit field types other than int */ -/* wanpipe_defines.h(220) : warning C4214: nonstandard extension used : bit field types other than int */ -/* this will break for any compilers that are strict ansi or strict c99 */ - -/* The following definition for that struct should resolve this warning and work for 32 and 64 bit */ -#if 0 -struct iphdr { - -#if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned ihl:4, - version:4; -#elif defined (__BIG_ENDIAN_BITFIELD) - unsigned version:4, - ihl:4; -#else -# error "unknown byteorder!" -#endif - unsigned tos:8; - unsigned tot_len:16; - unsigned id:16; - unsigned frag_off:16; - __u8 ttl; - __u8 protocol; - __u16 check; - __u32 saddr; - __u32 daddr; - /*The options start here. */ -}; -#endif /* #if 0 */ - -#define __inline__ __inline -#endif /* defined(_MSC_VER) */ -#include -/* do we like the name WP_INVALID_SOCKET or should it be changed? */ -#define WP_INVALID_SOCKET INVALID_HANDLE_VALUE -#else /* defined(__WINDOWS__) */ -#define WP_INVALID_SOCKET -1 -#include -#include -#include -#endif - -#include -#include -#include -#include -#ifdef __WINDOWS__ -#include -#include -#endif -#include - -#define FNAME_LEN 50 - - -#if defined(__WINDOWS__) -/* This might be broken on windows, as POLL_EVENT_TELEPHONY seems to be commented out in sang_api.h.. it should be added to POLLPRI */ -#define POLLPRI (POLL_EVENT_LINK_STATE | POLL_EVENT_LINK_CONNECT | POLL_EVENT_LINK_DISCONNECT) -#endif - -/* return -1 for error, 0 for timeout or 1 for success. *flags is set to the poll evetns POLLIN | POLLOUT | POLLPRI based on the result of the poll */ -/* on windows we actually have POLLPRI defined with several events, so we could theoretically poll */ -/* for specific events. Is there any way to do this on *nix as well? */ - -/* a cross platform way to poll on an actual pollset (span and/or list of spans) will probably also be needed for analog */ -/* so we can have one analong handler thread that will deal with all the idle analog channels for events */ -/* the alternative would be for the driver to provide one socket for all of the oob events for all analog channels */ -static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int *flags) -{ -#if defined(__WINDOWS__) - DWORD ln; - API_POLL_STRUCT api_poll; - - memset(&api_poll, 0x00, sizeof(API_POLL_STRUCT)); - - api_poll.user_flags_bitmap = *flags; - api_poll.timeout = timeout; - - if (!DeviceIoControl( - fd, - IoctlApiPoll, - (LPVOID)NULL, - 0L, - (LPVOID)&api_poll, - sizeof(API_POLL_STRUCT), - (LPDWORD)(&ln), - (LPOVERLAPPED)NULL)) { - return -1; - } - - *flags = 0; - - switch(api_poll.operation_status) - { - case SANG_STATUS_RX_DATA_AVAILABLE: - break; - - case SANG_STATUS_RX_DATA_TIMEOUT: - return 0; - - default: - return -1; - } - - if (api_poll.poll_events_bitmap == 0){ - return -1; - } - - if (api_poll.poll_events_bitmap & POLL_EVENT_TIMEOUT) { - return 0; - } - - *flags = api_poll.poll_events_bitmap; - - return 1; -#else - struct pollfd pfds[1]; - int res; - - memset(&pfds[0], 0, sizeof(pfds[0])); - pfds[0].fd = fd; - pfds[0].events = *flags; - res = poll(pfds, 1, timeout); - *flags = 0; - - if (pfds[0].revents & POLLERR) { - res = -1; - } - - if (res > 0) { - *flags = pfds[0].revents; - } - - return res; -#endif -} - -/* on windows right now, there is no way to specify if we want to read events here or not, we allways get them here */ -/* we need some what to select if we are reading regular tdm msgs or events */ -/* need to either have 2 functions, 1 for events, 1 for regural read, or a flag on this function to choose */ -/* 2 functions preferred. Need implementation for the event function for both nix and windows that is threadsafe */ -static __inline__ int tdmv_api_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, int datalen) -{ - /* What do we need to do here to avoid having to do all */ - /* the memcpy's on windows and still maintain api compat with nix */ - int rx_len=0; -#if defined(__WINDOWS__) - static RX_DATA_STRUCT rx_data; - api_header_t *pri; - wp_tdm_api_rx_hdr_t *tdm_api_rx_hdr; - wp_tdm_api_rx_hdr_t *user_buf = (wp_tdm_api_rx_hdr_t*)hdrbuf; - DWORD ln; - - if (hdrlen != sizeof(wp_tdm_api_rx_hdr_t)){ - return -1; - } - - if (!DeviceIoControl( - fd, - IoctlReadCommand, - (LPVOID)NULL, - 0L, - (LPVOID)&rx_data, - sizeof(RX_DATA_STRUCT), - (LPDWORD)(&ln), - (LPOVERLAPPED)NULL - )){ - return -1; - } - - pri = &rx_data.api_header; - tdm_api_rx_hdr = (wp_tdm_api_rx_hdr_t*)rx_data.data; - - user_buf->wp_tdm_api_event_type = pri->operation_status; - - switch(pri->operation_status) - { - case SANG_STATUS_RX_DATA_AVAILABLE: - if (pri->data_length > datalen){ - break; - } - memcpy(databuf, rx_data.data, pri->data_length); - rx_len = pri->data_length; - break; - - default: - break; - } - -#else - struct msghdr msg; - struct iovec iov[2]; - - memset(&msg,0,sizeof(struct msghdr)); - - iov[0].iov_len=hdrlen; - iov[0].iov_base=hdrbuf; - - iov[1].iov_len=datalen; - iov[1].iov_base=databuf; - - msg.msg_iovlen=2; - msg.msg_iov=iov; - - rx_len = read(fd,&msg,datalen+hdrlen); - - if (rx_len <= sizeof(wp_tdm_api_rx_hdr_t)){ - return -EINVAL; - } - - rx_len-=sizeof(wp_tdm_api_rx_hdr_t); -#endif - return rx_len; -} - -static __inline__ int tdmv_api_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen, void *databuf, unsigned short datalen) -{ - /* What do we need to do here to avoid having to do all */ - /* the memcpy's on windows and still maintain api compat with nix */ - int bsent = 0; -#if defined(__WINDOWS__) - static TX_DATA_STRUCT local_tx_data; - api_header_t *pri; - DWORD ln; - - /* Are these really not needed or used??? What about for nix?? */ - (void)hdrbuf; - (void)hdrlen; - - pri = &local_tx_data.api_header; - - pri->data_length = datalen; - memcpy(local_tx_data.data, databuf, pri->data_length); - - if (!DeviceIoControl( - fd, - IoctlWriteCommand, - (LPVOID)&local_tx_data, - (ULONG)sizeof(TX_DATA_STRUCT), - (LPVOID)&local_tx_data, - sizeof(TX_DATA_STRUCT), - (LPDWORD)(&ln), - (LPOVERLAPPED)NULL - )){ - return -1; - } - - if (local_tx_data.api_header.operation_status == SANG_STATUS_SUCCESS) { - bsent = datalen; - } -#else - struct msghdr msg; - struct iovec iov[2]; - - memset(&msg,0,sizeof(struct msghdr)); - - iov[0].iov_len = hdrlen; - iov[0].iov_base = hdrbuf; - - iov[1].iov_len = datalen; - iov[1].iov_base = databuf; - - msg.msg_iovlen = 2; - msg.msg_iov = iov; - - bsent = write(fd, &msg, datalen + hdrlen); - if (bsent > 0){ - bsent -= sizeof(wp_tdm_api_tx_hdr_t); - } -#endif - return bsent; -} - -#endif /* _SANGOMA_TDM_API_H */ - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/include/private/uart.h b/libs/freetdm/src/include/private/uart.h deleted file mode 100644 index b1b04c09a4..0000000000 --- a/libs/freetdm/src/include/private/uart.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * uart.h - * - * Copyright (c) 2005 Robert Krten. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This module contains the manifest constants and declarations for - * the UART module. - * - * 2005 06 19 R. Krten created -*/ - -#ifndef __UART_H__ -#define __UART_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*bytehandler_func_t) (void *, int); -typedef void (*bithandler_func_t) (void *, int); - - -typedef struct dsp_uart_attr_s -{ - bytehandler_func_t bytehandler; /* byte handler */ - void *bytehandler_arg; /* arbitrary ID passed to bytehandler as first argument */ -} dsp_uart_attr_t; - -typedef struct -{ - dsp_uart_attr_t attr; - int have_start; /* wait for start bit to show up */ - int data; /* data buffer */ - int nbits; /* number of bits accumulated so far */ -} dsp_uart_handle_t; - -/* - * Function prototypes - * - * General calling order is: - * a) create the attributes structure (dsp_uart_attr_init) - * b) initialize fields in the attributes structure (dsp_uart_attr_set_*) - * c) create a Bell-202 handle (dsp_uart_create) - * d) feed bits through dsp_uart_bit_handler -*/ - -void dsp_uart_attr_init(dsp_uart_attr_t *attributes); - -bytehandler_func_t dsp_uart_attr_get_bytehandler(dsp_uart_attr_t *attributes, void **bytehandler_arg); -void dsp_uart_attr_set_bytehandler(dsp_uart_attr_t *attributes, bytehandler_func_t bytehandler, void *bytehandler_arg); - -dsp_uart_handle_t * dsp_uart_create(dsp_uart_attr_t *attributes); -void dsp_uart_destroy(dsp_uart_handle_t **handle); - -void dsp_uart_bit_handler(void *handle, int bit); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/libs/freetdm/src/isdn/5ESSStateNT.c b/libs/freetdm/src/isdn/5ESSStateNT.c deleted file mode 100644 index 6d38f4582e..0000000000 --- a/libs/freetdm/src/isdn/5ESSStateNT.c +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************** - - FileName: 5ESSStateNT.c - - Contents: AT&T 5ESS ISDN State Engine for NT (Network Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Copyright (c) 2007, Michael S. Collins, All rights reserved. - email:mcollins@fcnetwork.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "5ESS.h" - -/***************************************************************************** - Function: ATT5ESSCreateNT - - Description: Will create the AT&T 5ESS ISDN NT as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void ATT5ESSCreateNT(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingNT, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingNT, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, Q931ProcConnectNT, Q931Umes_Connect, Q931Pmes_Connect); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, Q931ProcConnectAckNT, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressNT, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupNT, Q931Umes_Setup, Q931Pmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckNT, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeNT, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckNT, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectNT, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendNT, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckNT, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectNT, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationNT, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectNT, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseNT, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteNT, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartNT, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckNT, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlNT, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationNT, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyNT, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusNT, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryNT, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentNT, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityNT, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldNT, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckNT, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectNT, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterNT, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveNT, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckNT, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectNT, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - Q931SetIEProc(Q931ie_GENERIC_DIGITS, i, Q931Pie_GenericDigits, Q931Uie_GenericDigits); - - Q931SetIEProc(Q931ie_CONNECTED_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_FACILITY, i, Q931Pie_Generic, Q931Uie_Generic); - - /* The following define a state machine. The point is that the Message */ - /* procs can when search this to find out if the message/state */ - /* combination is legale. If not, the proc for unexpected message apply.*/ - - /* TODO define state table here */ -} diff --git a/libs/freetdm/src/isdn/5ESSStateTE.c b/libs/freetdm/src/isdn/5ESSStateTE.c deleted file mode 100644 index 6c31df88c7..0000000000 --- a/libs/freetdm/src/isdn/5ESSStateTE.c +++ /dev/null @@ -1,291 +0,0 @@ -/***************************************************************************** - - FileName: 5ESSStateTE.c - - Contents: AT&T 5ESS ISDN State Engine for TE (User Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - This reference implementation uses a process per message, - meaning that each message must check call states. This - is easier for dialect maintenance as each message proc - can be replaced individually. A new TE variant only - need to copy the Q931CreateTE and replace those procs or - need to override. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Copyright (c) 2007, Michael S. Collins, All rights reserved. - email:mcollins@fcnetwork.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "5ESS.h" -extern L3INT Q931L4HeaderSpace; - -/***************************************************************************** - Function: ATT5ESSCreateTE - - Description: Will create the AT&T 5ESS TE as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void ATT5ESSCreateTE(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingTE, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingTE, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, ATT5ESSProc0x07TE, ATT5ESSUmes_0x07, ATT5ESSPmes_0x07); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, ATT5ESSProc0x0fTE, ATT5ESSUmes_0x0f, ATT5ESSPmes_0x0f); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressTE, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupTE, ATT5ESSUmes_Setup, ATT5ESSPmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckTE, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeTE, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckTE, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectTE, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendTE, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckTE, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectTE, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationTE, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectTE, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseTE, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteTE, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartTE, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckTE, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlTE, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationTE, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyTE, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusTE, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryTE, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentTE, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityTE, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldTE, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckTE, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectTE, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterTE, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveTE, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckTE, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectTE, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANGE_STATUS, i, Q931Pie_ChangeStatus, Q931Uie_ChangeStatus); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - Q931SetIEProc(Q931ie_GENERIC_DIGITS, i, Q931Pie_GenericDigits, Q931Uie_GenericDigits); - - Q931SetIEProc(Q931ie_CONNECTED_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_FACILITY, i, Q931Pie_Generic, Q931Uie_Generic); - - /* The following define a state machine. The point is that the Message */ - /* procs can when search this to find out if the message/state */ - /* combination is legale. If not, the proc for unexpected message apply.*/ - - /* State 0 Idle */ - Q931AddStateEntry(i, Q931_U0, Q931mes_RESUME, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_STATUS, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE_COMPLETE, 4); - - /* State 1 Call Initiating */ - Q931AddStateEntry(i, Q931_U1, Q931mes_DISCONNECT, 2); - Q931AddStateEntry(i, Q931_U1, Q931mes_SETUP_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_RELEASE_COMPLETE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CONNECT, 4); - - /* State 2 Overlap Sending */ - Q931AddStateEntry(i, Q931_U2, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U2, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_RELEASE, 2); - - /* State 3 Outgoing Call Proceeding */ - Q931AddStateEntry(i, Q931_U3, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_RELEASE, 2); - - /* State 4 Call Delivered */ - Q931AddStateEntry(i, Q931_U4, Q931mes_CONNECT, 4); - - /* State 6 Call Precent */ - Q931AddStateEntry(i, Q931_U6, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CALL_PROCEEDING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE_COMPLETE, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U6, Q931mes_DISCONNECT, 4); - - /* State 7 Call Received */ - Q931AddStateEntry(i, Q931_U7, Q931mes_CONNECT, 2); - - /* State 8 Connect request */ - Q931AddStateEntry(i, Q931_U8, Q931mes_CONNECT_ACKNOWLEDGE, 4); - - /* State 9 Incoming Call Proceeding */ - Q931AddStateEntry(i, Q931_U9, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_PROGRESS, 2); - - /* State 10 Active */ - Q931AddStateEntry(i, Q931_U10, Q931mes_SUSPEND, 2); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 4); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 2); - - /* State 11 Disconnect Request */ - Q931AddStateEntry(i, Q931_U11, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_NOTIFY, 4); - - /* State 12 Disconnect Ind */ - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 2); - - /* State 15 Suspend Request */ - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_REJECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_RELEASE, 4); - -/* TODO - Q931AddStateEntry(i, Q931_U17, - Q931AddStateEntry(i, Q931_U19, - Q931AddStateEntry(i, Q931_U25, -*/ -} - -/***************************************************************************** - - Function: ATT5ESSProc0x0fTE - -*****************************************************************************/ -L3INT ATT5ESSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (pMes->ProtDisc == 8) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - } - if (iFrom == 4) { - /* TODO Add proc here*/ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom ==2) { - /* TODO Add proc here*/ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - - if (pMes->ProtDisc == 3 && pTrunk->autoServiceAck) { - printf("autoServiceAck is on, responding to Service Req from network...\n"); - Q931AckService(pTrunk, buf); - } - } - return ret; - -} - -/***************************************************************************** - - Function: ATT5ESSProc0x07TE - -*****************************************************************************/ -L3INT ATT5ESSProc0x07TE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (pMes->ProtDisc == 8) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - } - if (iFrom == 4) { - /* TODO Add proc here*/ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here*/ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; - -} diff --git a/libs/freetdm/src/isdn/5ESSmes.c b/libs/freetdm/src/isdn/5ESSmes.c deleted file mode 100644 index 9d7e3b9030..0000000000 --- a/libs/freetdm/src/isdn/5ESSmes.c +++ /dev/null @@ -1,361 +0,0 @@ -/***************************************************************************** - - FileName: 5ESSmes.c - - Contents: Pack/Unpack functions. These functions will unpack a 5ESS ISDN - message from the bit packed original format into structs - that contains variables sized by the user. It will also pack - the struct back into a Q.931 message as required. - - See 5ESS.h for description. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Copyright (c) 2007, Michael S. Collins, All rights reserved. - email:mcollins@fcnetwork.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*****************************************************************************/ - -#include "5ESS.h" - -/***************************************************************************** - - Function: ATT5ESSUmes_Setup - -*****************************************************************************/ -L3INT ATT5ESSUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT ir = 0; - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - L3UCHAR last_codeset = 0, codeset = 0; - L3UCHAR shift_nolock = 1; - - while (IOff < Size) { - - if (shift_nolock) { - codeset = last_codeset; - } - - if ((IBuf[IOff] & 0xF0) == Q931ie_SHIFT) { - shift_nolock = (IBuf[IOff] & 0x08); - if (shift_nolock) { - last_codeset = codeset; - } - codeset = ((IBuf[IOff] & 0x07)); - IOff++; - } - - if (codeset == 0) { - switch (IBuf[IOff]) - { - case Q931ie_SENDING_COMPLETE: - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_NETWORK_SPECIFIC_FACILITIES: - case Q931ie_DISPLAY: - case Q931ie_DATETIME: - case Q931ie_KEYPAD_FACILITY: - case Q931ie_SIGNAL: - case Q931ie_CALLING_PARTY_NUMBER: - case Q931ie_CALLING_PARTY_SUBADDRESS: - case Q931ie_CALLED_PARTY_NUMBER: - case Q931ie_CALLED_PARTY_SUBADDRESS: - case Q931ie_TRANSIT_NETWORK_SELECTION: - case Q931ie_LOW_LAYER_COMPATIBILITY: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - case Q931ie_FACILITY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - case Q931ie_REPEAT_INDICATOR: - if (ir < 2) { - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - ir++; - } else { - return Q931E_ILLEGAL_IE; - } - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } else if (codeset == 6) { - switch (IBuf[IOff]) - { - case Q931ie_GENERIC_DIGITS: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } else if (codeset == 7) { - switch (IBuf[IOff]) - { - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } else { - return Q931E_ILLEGAL_IE; - } - } - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: ATT5ESSPmes_Setup - - Decription: Pack a Q931mes_Generic into a real Q.931 message. The user will - set up a SETUP message and issue this to the stack where it - is processed by Q931ProcSetup that processes and validates - it before it actually sends it out. This function is called - to compute the real Q.931 message. - - Parameters: IBuf[IN] Ptr to un-packed struct - ISize[IN] Size of input buffer (unpacked message). - OBuf[OUT] Ptr to packed 'octet' wise message. - OSize[OUT] Size of packed message. - - Called By: Q931ProcSetup - -*****************************************************************************/ -L3INT ATT5ESSPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3INT rc = Q931E_NO_ERROR; - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Sending Complete */ - if (Q931IsIEPresent(pMes->SendComplete)) { - OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff); - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->RepeatInd)) { - OBuf[Octet++] = (L3UCHAR)(pMes->RepeatInd & 0x00ff); - } - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) - return rc; - } else { - rc = Q931E_BEARERCAP; - } - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Network specific facilities */ - if (Q931IsIEPresent(pMes->NetFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_NETWORK_SPECIFIC_FACILITIES](pTrunk, Q931GetIEPtr(pMes->NetFac,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Date/Time */ - if (Q931IsIEPresent(pMes->DateTime)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DATETIME](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Keypad Facility */ - if (Q931IsIEPresent(pMes->KeypadFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_KEYPAD_FACILITY](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Calling Party Number */ - if (Q931IsIEPresent(pMes->CallingNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CallingNum,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Calling Party Subaddress */ - if (Q931IsIEPresent(pMes->CallingSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CallingSub,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Called Party number */ - if (Q931IsIEPresent(pMes->CalledNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Called party subaddress */ - if (Q931IsIEPresent(pMes->CalledSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CalledSub,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Transit network selection */ - if (Q931IsIEPresent(pMes->TransNetSel)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_TRANSIT_NETWORK_SELECTION](pTrunk, Q931GetIEPtr(pMes->TransNetSel,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->LLRepeatInd)) { - rc = Q931E_UNKNOWN_IE;/* TODO */ - } - - /* Low Layer Compatibility */ - if (Q931IsIEPresent(pMes->LLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_LOW_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0) - return rc; - } - - *OSize = Octet; - return rc; -} - - -/***************************************************************************** - - Function: ATT5ESSUmes_0x0f - -*****************************************************************************/ -L3INT ATT5ESSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - if (mes->ProtDisc == 8) { - return Q931Umes_ConnectAck(pTrunk, IBuf, mes, IOff, Size); - } - - if (mes->ProtDisc == 3) { - return Q931Umes_Service(pTrunk, IBuf, mes, IOff, Size); - } - - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: ATT5ESSPmes_0x0f - -*****************************************************************************/ -L3INT ATT5ESSPmes_0x0f(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *mes = (Q931mes_Generic *)IBuf; - - if (mes->ProtDisc == 8) { - return Q931Pmes_ConnectAck(pTrunk, IBuf, ISize, OBuf, OSize); - } - - if (mes->ProtDisc == 3) { - return Q931Pmes_Service(pTrunk, IBuf, ISize, OBuf, OSize); - } - - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: ATT5ESSUmes_0x07 - -*****************************************************************************/ -L3INT ATT5ESSUmes_0x07(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - if (mes->ProtDisc == 8) { - return Q931Umes_Connect(pTrunk, IBuf, mes, IOff, Size); - } - - if (mes->ProtDisc == 3) { - return Q931Umes_ServiceAck(pTrunk, IBuf, mes, IOff, Size); - } - - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: ATT5ESSPmes_0x07 - -*****************************************************************************/ -L3INT ATT5ESSPmes_0x07(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *mes = (Q931mes_Generic *)IBuf; - - if (mes->ProtDisc == 8) { - return Q931Pmes_Connect(pTrunk, IBuf, ISize, OBuf, OSize); - } - - if (mes->ProtDisc == 3) { - return Q931Pmes_ServiceAck(pTrunk, IBuf, ISize, OBuf, OSize); - } - - return Q931E_UNKNOWN_MESSAGE; -} diff --git a/libs/freetdm/src/isdn/DMSStateNT.c b/libs/freetdm/src/isdn/DMSStateNT.c deleted file mode 100644 index e8814ba8ef..0000000000 --- a/libs/freetdm/src/isdn/DMSStateNT.c +++ /dev/null @@ -1,126 +0,0 @@ -/***************************************************************************** - - FileName: DMSStateNT.c - - Contents: DMS-100 ISDN State Engine for NT (Network Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "DMS.h" - -/***************************************************************************** - Function: DMSCreateNT - - Description: Will create the National ISDN NT as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void DMSCreateNT(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingNT, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingNT, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, Q931ProcConnectNT, Q931Umes_Connect, Q931Pmes_Connect); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, Q931ProcConnectAckNT, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressNT, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupNT, DMSUmes_Setup, DMSPmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckNT, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeNT, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckNT, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectNT, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendNT, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckNT, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectNT, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationNT, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectNT, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseNT, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteNT, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartNT, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckNT, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlNT, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationNT, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyNT, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusNT, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryNT, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentNT, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityNT, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldNT, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckNT, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectNT, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterNT, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveNT, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckNT, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectNT, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - Q931SetIEProc(Q931ie_GENERIC_DIGITS, i, Q931Pie_GenericDigits, Q931Uie_GenericDigits); - - /* The following define a state machine. The point is that the Message */ - /* procs can when search this to find out if the message/state */ - /* combination is legale. If not, the proc for unexpected message apply.*/ - - /* TODO define state table here */ -} diff --git a/libs/freetdm/src/isdn/DMSStateTE.c b/libs/freetdm/src/isdn/DMSStateTE.c deleted file mode 100644 index cb740d3c2f..0000000000 --- a/libs/freetdm/src/isdn/DMSStateTE.c +++ /dev/null @@ -1,284 +0,0 @@ -/***************************************************************************** - - FileName: DMSStateTE.c - - Contents: DMS-100 ISDN State Engine for TE (User Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - This reference implementation uses a process per message, - meaning that each message must check call states. This - is easier for dialect maintenance as each message proc - can be replaced individually. A new TE variant only - need to copy the Q931CreateTE and replace those procs or - need to override. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "DMS.h" -extern L3INT Q931L4HeaderSpace; - -/***************************************************************************** - Function: DMSCreateTE - - Description: Will create the National TE as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void DMSCreateTE(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingTE, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingTE, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, DMSProc0x07TE, DMSUmes_0x07, DMSPmes_0x07); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, DMSProc0x0fTE, DMSUmes_0x0f, DMSPmes_0x0f); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressTE, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupTE, DMSUmes_Setup, DMSPmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckTE, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeTE, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckTE, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectTE, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendTE, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckTE, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectTE, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationTE, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectTE, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseTE, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteTE, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartTE, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckTE, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlTE, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationTE, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyTE, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusTE, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryTE, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentTE, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityTE, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldTE, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckTE, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectTE, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterTE, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveTE, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckTE, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectTE, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANGE_STATUS, i, Q931Pie_ChangeStatus, Q931Uie_ChangeStatus); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - Q931SetIEProc(Q931ie_GENERIC_DIGITS, i, Q931Pie_GenericDigits, Q931Uie_GenericDigits); - - /* The following define a state machine. The point is that the Message */ - /* procs can when search this to find out if the message/state */ - /* combination is legale. If not, the proc for unexpected message apply.*/ - - /* State 0 Idle */ - Q931AddStateEntry(i, Q931_U0, Q931mes_RESUME, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_STATUS, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE_COMPLETE, 4); - - /* State 1 Call Initiating */ - Q931AddStateEntry(i, Q931_U1, Q931mes_DISCONNECT, 2); - Q931AddStateEntry(i, Q931_U1, Q931mes_SETUP_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_RELEASE_COMPLETE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CONNECT, 4); - - /* State 2 Overlap Sending */ - Q931AddStateEntry(i, Q931_U2, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U2, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_RELEASE, 2); - - /* State 3 Outgoing Call Proceeding */ - Q931AddStateEntry(i, Q931_U3, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_RELEASE, 2); - - /* State 4 Call Delivered */ - Q931AddStateEntry(i, Q931_U4, Q931mes_CONNECT, 4); - - /* State 6 Call Precent */ - Q931AddStateEntry(i, Q931_U6, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CALL_PROCEEDING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE_COMPLETE, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U6, Q931mes_DISCONNECT, 4); - - /* State 7 Call Received */ - Q931AddStateEntry(i, Q931_U7, Q931mes_CONNECT, 2); - - /* State 8 Connect request */ - Q931AddStateEntry(i, Q931_U8, Q931mes_CONNECT_ACKNOWLEDGE, 4); - - /* State 9 Incoming Call Proceeding */ - Q931AddStateEntry(i, Q931_U9, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_PROGRESS, 2); - - /* State 10 Active */ - Q931AddStateEntry(i, Q931_U10, Q931mes_SUSPEND, 2); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 4); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 2); - - /* State 11 Disconnect Request */ - Q931AddStateEntry(i, Q931_U11, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_NOTIFY, 4); - - /* State 12 Disconnect Ind */ - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 2); - - /* State 15 Suspend Request */ - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_REJECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_RELEASE, 4); - -/* TODO - Q931AddStateEntry(i, Q931_U17, - Q931AddStateEntry(i, Q931_U19, - Q931AddStateEntry(i, Q931_U25, -*/ -} - -/***************************************************************************** - - Function: DMSProc0x0fTE - -*****************************************************************************/ -L3INT DMSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (pMes->ProtDisc == 8) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - } - if (iFrom == 4) { - /* TODO Add proc here*/ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here*/ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - - if (pMes->ProtDisc == 3 && pTrunk->autoServiceAck) { - Q931AckService(pTrunk, buf); - } - } - return ret; - -} - -/***************************************************************************** - - Function: DMSProc0x07TE - -*****************************************************************************/ -L3INT DMSProc0x07TE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (pMes->ProtDisc == 8) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - } - if (iFrom == 4) { - /* TODO Add proc here*/ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here*/ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; - -} diff --git a/libs/freetdm/src/isdn/DMSmes.c b/libs/freetdm/src/isdn/DMSmes.c deleted file mode 100644 index 3ce82f2ded..0000000000 --- a/libs/freetdm/src/isdn/DMSmes.c +++ /dev/null @@ -1,344 +0,0 @@ -/***************************************************************************** - - FileName: DMSmes.c - - Contents: Pack/Unpack functions. These functions will unpack a DMS-100 ISDN - message from the bit packed original format into structs - that contains variables sized by the user. It will also pack - the struct back into a Q.931 message as required. - - See national.h for description. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*****************************************************************************/ - -#include "DMS.h" - -/***************************************************************************** - - Function: DMSUmes_Setup - -*****************************************************************************/ -L3INT DMSUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT ir = 0; - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - L3UCHAR last_codeset = 0, codeset = 0; - L3UCHAR shift_lock = 1; - - while (IOff < Size) { - if (!shift_lock) { - codeset = last_codeset; - } - - if ((IBuf[IOff] & 0xF0) == Q931ie_SHIFT ) { - shift_lock = (IBuf[IOff] & 0x08); - if (shift_lock) { - last_codeset = codeset; - } - codeset = ((IBuf[IOff] & 0x07)); - IOff++; - } - - if (codeset == 0) { - switch (IBuf[IOff]) { - case Q931ie_SENDING_COMPLETE: - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_NETWORK_SPECIFIC_FACILITIES: - case Q931ie_DISPLAY: - case Q931ie_DATETIME: - case Q931ie_KEYPAD_FACILITY: - case Q931ie_SIGNAL: - case Q931ie_CALLING_PARTY_NUMBER: - case Q931ie_CALLING_PARTY_SUBADDRESS: - case Q931ie_CALLED_PARTY_NUMBER: - case Q931ie_CALLED_PARTY_SUBADDRESS: - case Q931ie_TRANSIT_NETWORK_SELECTION: - case Q931ie_LOW_LAYER_COMPATIBILITY: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - case Q931ie_REPEAT_INDICATOR: - if (ir < 2) { - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - ir++; - } else { - return Q931E_ILLEGAL_IE; - } - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } else if (codeset == 6) { - switch (IBuf[IOff]) { - case Q931ie_GENERIC_DIGITS: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - - } else { - return Q931E_ILLEGAL_IE; - } - } - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: DMSPmes_Setup - - Decription: Pack a Q931mes_Generic into a real Q.931 message. The user will - set up a SETUP message and issue this to the stack where it - is processed by Q931ProcSetup that processes and validates - it before it actually sends it out. This function is called - to compute the real Q.931 message. - - Parameters: IBuf[IN] Ptr to un-packed struct - ISize[IN] Size of input buffer (unpacked message). - OBuf[OUT] Ptr to packed 'octet' wise message. - OSize[OUT] Size of packed message. - - Called By: Q931ProcSetup - -*****************************************************************************/ -L3INT DMSPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3INT rc = Q931E_NO_ERROR; - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Sending Complete */ - if (Q931IsIEPresent(pMes->SendComplete)) { - OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff); - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->RepeatInd)) { - OBuf[Octet++] = (L3UCHAR)(pMes->RepeatInd & 0x00ff); - } - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } else { - rc = Q931E_BEARERCAP; - } - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Network spesific facilities */ - if (Q931IsIEPresent(pMes->NetFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_NETWORK_SPECIFIC_FACILITIES](pTrunk, Q931GetIEPtr(pMes->NetFac,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Date/Time */ - if (Q931IsIEPresent(pMes->DateTime)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DATETIME](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Keypad Facility */ - if (Q931IsIEPresent(pMes->KeypadFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_KEYPAD_FACILITY](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Calling Party Number */ - if (Q931IsIEPresent(pMes->CallingNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CallingNum,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Calling Party Subaddress */ - if (Q931IsIEPresent(pMes->CallingSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CallingSub,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Called Party number */ - if (Q931IsIEPresent(pMes->CalledNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - - /* Called party subaddress */ - if (Q931IsIEPresent(pMes->CalledSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CalledSub,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Transit network selection */ - if (Q931IsIEPresent(pMes->TransNetSel)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_TRANSIT_NETWORK_SELECTION](pTrunk, Q931GetIEPtr(pMes->TransNetSel,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->LLRepeatInd)) { - rc = Q931E_UNKNOWN_IE;/* TODO */ - } - - /* Low Layer Compatibility */ - if (Q931IsIEPresent(pMes->LLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_LOW_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - - -/***************************************************************************** - - Function: DMSUmes_0x0f - -*****************************************************************************/ -L3INT DMSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - if (mes->ProtDisc == 8) { - return Q931Umes_ConnectAck(pTrunk, IBuf, mes, IOff, Size); - } - - if (mes->ProtDisc == 3) { - return Q931Umes_Service(pTrunk, IBuf, mes, IOff, Size); - } - - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: DMSPmes_0x0f - -*****************************************************************************/ -L3INT DMSPmes_0x0f(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *mes = (Q931mes_Generic *)IBuf; - - if (mes->ProtDisc == 8) { - return Q931Pmes_ConnectAck(pTrunk, IBuf, ISize, OBuf, OSize); - } - - if (mes->ProtDisc == 3) { - return Q931Pmes_Service(pTrunk, IBuf, ISize, OBuf, OSize); - } - - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: DMSUmes_0x07 - -*****************************************************************************/ -L3INT DMSUmes_0x07(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - if (mes->ProtDisc == 8) { - return Q931Umes_Connect(pTrunk, IBuf, mes, IOff, Size); - } - - if (mes->ProtDisc == 3) { - return Q931Umes_ServiceAck(pTrunk, IBuf, mes, IOff, Size); - } - - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: DMSPmes_0x07 - -*****************************************************************************/ -L3INT DMSPmes_0x07(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *mes = (Q931mes_Generic *)IBuf; - - if (mes->ProtDisc == 8) { - return Q931Pmes_Connect(pTrunk, IBuf, ISize, OBuf, OSize); - } - - if (mes->ProtDisc == 3) { - return Q931Pmes_ServiceAck(pTrunk, IBuf, ISize, OBuf, OSize); - } - - return Q931E_UNKNOWN_MESSAGE; -} diff --git a/libs/freetdm/src/isdn/EuroISDNStateNT.c b/libs/freetdm/src/isdn/EuroISDNStateNT.c deleted file mode 100644 index 6b26c91e04..0000000000 --- a/libs/freetdm/src/isdn/EuroISDNStateNT.c +++ /dev/null @@ -1,44 +0,0 @@ -/***************************************************************************** - - FileName: EuroISDNStateNT.c - - Contents: EuroISDN State Engine for NT (Network Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q931.h" diff --git a/libs/freetdm/src/isdn/EuroISDNStateTE.c b/libs/freetdm/src/isdn/EuroISDNStateTE.c deleted file mode 100644 index ef6b39e8e5..0000000000 --- a/libs/freetdm/src/isdn/EuroISDNStateTE.c +++ /dev/null @@ -1,58 +0,0 @@ -/***************************************************************************** - - FileName: EuroISDNStateTE.c - - Contents: EuroISDN State Engine for TE (User Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q931.h" - -/* - EuroISDN is a sub-set of Q.931. Q.931 is very generic as it embrase a lot, - while EuroISDN is more exact and make decitions on some of the - 'implementation options' in the original standard. EuroISDN will - however run smoothly under the generic space, so these functions are more - for show -*/ -#if 0 -static void EuroISDNCreateTE(L3UCHAR i) -{ - Q931CreateTE(i); -} -#endif diff --git a/libs/freetdm/src/isdn/Q921.c b/libs/freetdm/src/isdn/Q921.c deleted file mode 100644 index d1cbab6e6f..0000000000 --- a/libs/freetdm/src/isdn/Q921.c +++ /dev/null @@ -1,3518 +0,0 @@ -/***************************************************************************** - - FileName: q921.c - - Description: Contains the implementation of a Q.921 protocol - - Created: 27.dec.2000/JVB - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*****************************************************************************/ - -/**************************************************************************** - * Changes: - * - * - June-August 2008: Stefan Knoblich : - * Add PTMP TEI management (NT + TE mode) - * Add timers - * Add retransmit counters - * Add logging - * Various cleanups - * Queues, retransmission of I frames - * PTMP NT mode - * - * - * TODO: - * - * - Cleanup queueing, test retransmission - * - * - Q921Start() /-Stop() TEI acquire + release - * (move everything related into these functions) - * - * - Q.921 '97 Appendix I (and maybe III, IV) - * - * - More complete Appendix II - * - * - Test PTP mode - * - * - PTMP NT mode (in progress) - * - * - NT mode TEI management: (ab)use T202 for TEI Check Request retransmission - * - * - General cleanup (move all non-public declarations into private header file) - * - * - Statistics, per-Frame type debug message filter - * - ****************************************************************************/ - -#include -#include -#include -#include - -#include "freetdm.h" -#include "Q921.h" -#include "Q921priv.h" -#include "mfifo.h" - -#ifdef WIN32 -#pragma warning(disable:4100 4244) -#endif - -/****************************************************************************************************** - * Actual code below this line - ******************************************************************************************************/ - - -/** - * Q921StateNames - * \brief Static array of state name / value mappings - */ -static struct Q921StateName { - Q921State_t value; - const char *name; -} Q921StateNames[10] = { - { Q921_STATE_STOPPED, "Stopped" }, - { Q921_STATE_TEI_UNASSIGNED, "TEI Unassigned" }, - { Q921_STATE_TEI_AWAITING, "TEI Awaiting Assignment" }, - { Q921_STATE_TEI_ESTABLISH, "TEI Awaiting Establishment" }, - { Q921_STATE_TEI_ASSIGNED, "TEI Assigned" }, - { Q921_STATE_AWAITING_ESTABLISHMENT, "Awaiting Establishment" }, - { Q921_STATE_AWAITING_RELEASE, "Awaiting Release" }, - { Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, "Multiple Frame Mode Established" }, - { Q921_STATE_TIMER_RECOVERY, "Timer Recovery" }, - { 0, 0 } -}; - -/** - * Q921State2Name - * \brief Convert state value to name - * \param[in] state the state value - * \return the state name or "Unknown" - * - * \author Stefan Knoblich - */ -static const char *Q921State2Name(Q921State_t state) -{ - struct Q921StateName *p = Q921StateNames; - - while(p->name) { - if(p->value == state) - return p->name; - p++; - } - - return "Unknown"; -} - - -/** - * Q921SendEnquiry - */ -static int Q921SendEnquiry(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - /* send enquiry: begin */ - if(Q921_CHECK_FLAG(link, Q921_FLAG_RECV_BUSY)) { - - Q921SendRNR(trunk, trunk->sapi, Q921_COMMAND(trunk), tei, 1); - } - else { - Q921SendRR(trunk, trunk->sapi, Q921_COMMAND(trunk), tei, 1); - } - - /* clear acknowledge pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - - /* "Start" T200 */ - Q921T200TimerReset(trunk, tei); - - /* send enquiry: end */ - return 1; -} - -/** - * Q921SendEnquiryResponse - */ -static int Q921SendEnquiryResponse(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - /* send enquiry: begin */ - if(Q921_CHECK_FLAG(link, Q921_FLAG_RECV_BUSY)) { - - Q921SendRNR(trunk, trunk->sapi, Q921_RESPONSE(trunk), tei, 1); - } - else { - Q921SendRR(trunk, trunk->sapi, Q921_RESPONSE(trunk), tei, 1); - - /* clear acknowledge pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - /* send enquiry: end */ - return 1; -} - -/** - * Q921ResetExceptionConditions - * \brief Reset Q.921 Exception conditions procedure - * \param trunk Q.921 data structure - * \param tei TEI - * \todo Do something - */ -static void Q921ResetExceptionConditions(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - /* Clear peer receiver busy */ - Q921_CLEAR_FLAG(link, Q921_FLAG_PEER_RECV_BUSY); - - /* Clear reject exception */ - Q921_CLEAR_FLAG(link, Q921_FLAG_REJECT); - - /* Clear own receiver busy */ - Q921_CLEAR_FLAG(link, Q921_FLAG_RECV_BUSY); - - /* Clear acknowledge pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - - return; -} - -/** - * Q921EstablishDataLink - * \brief Q.921 Establish data link procedure - * \param trunk Q.921 data structure - * \param tei TEI - * \return always 1 (success) - */ -static int Q921EstablishDataLink(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - /* reset exception conditions */ - Q921ResetExceptionConditions(trunk, tei); - - /* RC = 0 */ - link->N200 = 0; - - /* Send SABME */ - Q921SendSABME(trunk, trunk->sapi, Q921_COMMAND(trunk), tei, 1); - - /* Restart T200, stop T203 */ - Q921T200TimerReset(trunk, tei); - Q921T203TimerStop(trunk, tei); - - return 1; -} - -/** - * Q921NrErrorRecovery - * \brief NR(R) Error recovery procedure - * \param trunk Q.921 data structure - * \param tei TEI - * \return always 1 (success) - */ -static int Q921NrErrorRecovery(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - /* MDL Error indication (J) */ - - /* Establish datalink */ - Q921EstablishDataLink(trunk, tei); - - /* Clear L3 initiated */ - Q921_CLEAR_FLAG(link, Q921_FLAG_L3_INITIATED); - - return 1; -} - - -/** - * Q921InvokeRetransmission - * \brief I Frame retransmission procedure - * \param trunk Q.921 data structure - * \param tei TEI - * \param nr N(R) for retransmission - * \return always 1 (success) - */ -static int Q921InvokeRetransmission(L2TRUNK trunk, L2UCHAR tei, L2UCHAR nr) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - L2UCHAR *mes; - L2INT qpos, qnum, size = 0; - - qnum = MFIFOGetMesCount(link->IFrameResendQueue); - qpos = qnum - 1; - - /* - * slightly different than what is shown in the spec - * (Q.921 '97 Annex B, Figure B.9, page 104) - * - * what the above mentioned figure probably means is: - * "as long as V(S) != N(R), move the pointer marking - * the first frame to start resending at to the previous - * frame" - * - * if we actually implemented it as shown in the figure, we'd be - * resending frames in the wrong order (moving backwards in time) - * meaning we'd have to add an incoming queue to reorder the frames - * - */ - /* - * TODO: There's a "traditional" off-by-one error hidden in the original - * mfifo implementation + it's late, i'm tired and being lazy, - * so i'll probably have added another one :P - * - * wow, the first while loop sucks and can be removed - */ - while(link->vs != nr && qpos > 0) { /* ???? */ - /* V(S) = V(S) - 1 */ - Q921_DEC_COUNTER(link->vs); /* huh? backwards? */ - - /* next frame in queue (backtrack along I queue) ??? */ - qpos--; - } - - /* - * being lazy and trying to avoid mod 128 math this way... - */ - if(link->vs != nr && !qpos) { - /* fatal, we don't have enough history to resend all missing frames */ - /* TODO: how to handle this? */ - } - - /* - * resend frames in correct order (oldest missing frame first, - * contrary to what the spec figure shows) - */ - while(qpos < qnum) { - /* Grab frame's buffer ptr and size from queue */ - mes = MFIFOGetMesPtrOffset(link->IFrameResendQueue, &size, qpos); - if(mes) { - /* requeue frame (TODO: check queue full condition) */ - MFIFOWriteMes(link->IFrameQueue, mes, size); - - /* set I frame queued */ - } - - qpos++; - } - - return 1; -} - - -static int Q921AcknowledgePending(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - case Q921_STATE_TIMER_RECOVERY: - if(Q921_CHECK_FLAG(link, Q921_FLAG_ACK_PENDING)) { - /* clear acknowledge pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - - /* send RR */ - Q921SendRR(trunk, trunk->sapi, Q921_COMMAND(trunk), tei, 0); - - return 1; - } - break; - - default: - break; - } - - return 0; -} - -/***************************************************************************** - - Function: Q921_InitTrunk - - Decription: Initialize a Q.921 trunk so it is ready for use. This - function MUST be called before you call any other functions. - -*****************************************************************************/ -int Q921_InitTrunk(L2TRUNK trunk, - L2UCHAR sapi, - L2UCHAR tei, - Q921NetUser_t NetUser, - Q921NetType_t NetType, - L2INT hsize, - Q921Tx21CB_t cb21, - Q921Tx23CB_t cb23, - void *priv21, - void *priv23) -{ - int numlinks = 0; - - trunk->sapi = sapi; - trunk->tei = tei; - trunk->NetUser = NetUser; - trunk->NetType = NetType; - trunk->Q921Tx21Proc = cb21; - trunk->Q921Tx23Proc = cb23; - trunk->PrivateData21 = priv21; - trunk->PrivateData23 = priv23; - trunk->Q921HeaderSpace = hsize; - - numlinks = Q921_IS_PTMP_NT(trunk) ? Q921_TEI_MAX : 1; - - if (trunk->initialized != INITIALIZED_MAGIC) { - MFIFOCreate(trunk->HDLCInQueue, Q921MAXHDLCSPACE, 10); - - /* - * Allocate space for per-link context(s) - */ - trunk->context = ftdm_malloc(numlinks * sizeof(struct Q921_Link)); - if(!trunk->context) - return -1; - - trunk->initialized = INITIALIZED_MAGIC; - } - - /* timeout default values */ - trunk->T200Timeout = 1000; /* 1 second */ - trunk->T203Timeout = 10000; /* 10 seconds */ - trunk->T202Timeout = 2000; /* 2 seconds */ - trunk->T201Timeout = 200000; /* 200 seconds */ - trunk->TM01Timeout = 10000; /* 10 seconds */ - - /* octet / retransmit counter default limits */ - trunk->N200Limit = 3; /* 3 retransmits */ - trunk->N201Limit = 260; /* 260 octets */ - trunk->N202Limit = 3; /* 3 retransmits */ - trunk->k = 7; /* 7 outstanding ACKs */ - - /* reset counters, timers, etc. */ - trunk->T202 = 0; - trunk->N202 = 0; - - /* Reset per-link contexts */ - memset(trunk->context, 0, numlinks * sizeof(struct Q921_Link)); - - /* clear tei map */ - memset(trunk->tei_map, 0, Q921_TEI_MAX + 1); - - if(Q921_IS_PTMP(trunk)) { - /* - * We're either the Network side (NT, TEI = 0) - * or user-side equipment (TE) which will get it's TEI via - * dynamic assignment - */ - trunk->tei = 0; - } - - return 0; -} - - -/** - * Q921Tx21Proc - * \brief Submit frame to layer 1 (for sending) - * \param[in] trunk Pointer to trunk struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - */ -static int Q921Tx21Proc(L2TRUNK trunk, L2UCHAR *Msg, L2INT size) -{ - Q921LogMesg(trunk, Q921_LOG_DEBUG, 0, Msg, size, "Sending frame"); - - return trunk->Q921Tx21Proc(trunk->PrivateData21, Msg, size); -} - - -/** - * Q921Tx23Proc - * \brief Submit frame to layer 3 - * \param[in] trunk Pointer to trunk struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - */ -static int Q921Tx23Proc(L2TRUNK trunk, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *Msg, L2INT size) -{ - return trunk->Q921Tx23Proc(trunk->PrivateData23, ind, tei, Msg, size); -} - - -/** - * Q921LogProc - * \brief Used for logging, converts to string and submits to higher level log function via callback - * \param[in] trunk Pointer to trunk struct - * \param[in] level Q921 Loglevel - * \param[in] fmt format of logmessage - * \return >= 0 on success, < 0 on error - * - * \author Stefan Knoblich - */ -static int Q921Log(L2TRUNK trunk, Q921LogLevel_t level, const char *fmt, ...) -{ - char buf[Q921_LOGBUFSIZE]; - L2INT len; - va_list ap; - - if(!trunk->Q921LogProc) - return 0; - - if(trunk->loglevel < level) - return 0; - - va_start(ap, fmt); - - len = vsnprintf(buf, sizeof(buf)-1, fmt, ap); - if(len <= 0) { - /* TODO: error handling */ - return -1; - } - if(len >= sizeof(buf)) - len = sizeof(buf) - 1; - - buf[len] = '\0'; - - va_end(ap); - - return trunk->Q921LogProc(trunk->PrivateDataLog, level, buf, len); -} - - -static int print_hex(char *buf, int bsize, const unsigned char *in, const int len) -{ - static const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - int offset = 0; - int pos = 0; - int nr = 0; - - buf[pos++] = '['; - bsize -= 3; - - while((bsize - pos) > 0 && offset < len) { - buf[pos++] = hex[(in[offset] & 0xF0) >> 4]; - buf[pos++] = hex[(in[offset++] & 0x0F)]; - - if(++nr == 32 && offset < len && (bsize - pos) > 3) { - nr = 0; - buf[pos++] = ']'; - buf[pos++] = '\n'; - buf[pos++] = '['; - } - else if(offset < len) { - buf[pos++] = ' '; - } - } - - buf[pos++] = ']'; - buf[pos++] = '\n'; - buf[pos] = '\0'; - - return pos; -} - -#define APPEND_MSG(buf, off, lef, fmt, ...) \ - len = snprintf(buf + off, lef, fmt, ##__VA_ARGS__); \ - if(len > 0) { \ - off += len; \ - lef -= len; \ - } else { \ - goto out; \ - } - -/** - * Q921LogProcMesg - * \brief Used for logging, converts to string and submits to higher level log function via callback - * \param[in] trunk Pointer to trunk struct - * \param[in] level Q921 Loglevel - * \param[in] received direction of the message (received = 1, sending = 0) - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \param[in] fmt format of logmessage - * \return >= 0 on success, < 0 on error - * - * \author Stefan Knoblich - */ -static int Q921LogMesg(L2TRUNK trunk, Q921LogLevel_t level, L2UCHAR received, L2UCHAR *mes, L2INT size, const char *fmt, ...) -{ - char buf[Q921_LOGBUFSIZE]; - size_t len, left; - va_list ap; - - if(!trunk->Q921LogProc) - return 0; - - if(trunk->loglevel < level) - return 0; - - if(!mes) - return 0; - - memset(buf, 0, sizeof(buf)); - - left = sizeof(buf) - 1; - - va_start(ap, fmt); - - len = vsnprintf(buf, left, fmt, ap); - if(len > 0) - left -= len; - else { - /* TODO: error handling */ - return -1; - } - - va_end(ap); - - if(trunk->loglevel == Q921_LOG_DEBUG) { - char pbuf[1024]; - size_t pleft, poffset; - L2UCHAR sapi, tei, cr; - L2UCHAR *pmes = mes + trunk->Q921HeaderSpace; - struct Q921_Link *link; - - memset(pbuf, 0, sizeof(pbuf)); - - pleft = sizeof(pbuf); - poffset = 0; - - /* - * Decode packet - */ - sapi = (pmes[0] & 0xfc) >> 2; - cr = (pmes[0] & 0x02) >> 1; - tei = (pmes[1] & 0xfe) >> 1; - link = Q921_LINK_CONTEXT(trunk, tei); - - /* make cr actually useful */ - cr = (received) ? Q921_IS_COMMAND(trunk, cr) : Q921_IS_RESPONSE(trunk, cr); - - /* filter */ - if((pmes[2] & 0x01) == 0x00) { - ; - } - else if((pmes[2] & 0x03) == 0x01) { - ; //return 0; - } - else if((pmes[2] & 0x03) == 0x03) { - ; - } - - APPEND_MSG(pbuf, poffset, pleft, "\n----------------- Q.921 Packet [%s%s] ---------------\n", received ? "Incoming" : "Outgoing", - (tei == link->tei || tei == Q921_TEI_BCAST) ? "" : ", Ignored" ); - - /* common header */ - APPEND_MSG(pbuf, poffset, pleft, " SAPI: %u, TEI: %u, C/R: %s (%d)\n\n", sapi, tei, (cr) ? "Command" : "Response", (mes[0] & 0x02) >> 1 ); - - /* - * message specific - */ - if((pmes[2] & 0x01) == 0x00) { - /* - * I frame - */ - L2UCHAR pf = pmes[3] & 0x01; /* poll / final flag */ - L2UCHAR nr = pmes[3] >> 1; /* receive sequence number */ - L2UCHAR ns = pmes[2] >> 1; /* send sequence number */ - - APPEND_MSG(pbuf, poffset, pleft, " Type: I Frame\n P/F: %d, N(S): %d, N(R): %d [V(A): %d, V(R): %d, V(S): %d]\n", pf, ns, nr, - link->va, link->vr, link->vs); - - /* Dump content of I Frames for foreign TEIs */ - if(tei != link->tei) { - APPEND_MSG(pbuf, poffset, pleft, " CONTENT:\n"); - - len = print_hex(pbuf + poffset, (int)pleft, &pmes[4], size - (trunk->Q921HeaderSpace + 4)); - poffset += len; - pleft -= len; - } - } - else if((pmes[2] & 0x03) == 0x01) { - /* - * S frame - */ - L2UCHAR sv = (pmes[2] & 0x0c) >> 2; /* supervisory format id */ - L2UCHAR pf = pmes[3] & 0x01; /* poll / final flag */ - L2UCHAR nr = pmes[3] >> 1; /* receive sequence number */ - const char *type; - - switch(sv) { - case 0x00: /* RR : Receive Ready */ - type = "RR (Receive Ready)"; - break; - - case 0x02: /* RNR : Receive Not Ready */ - type = "RNR (Receiver Not Ready)"; - break; - - case 0x04: /* REJ : Reject */ - type = "REJ (Reject)"; - break; - - default: /* Invalid / Unknown */ - type = "Unknown"; - break; - } - - APPEND_MSG(pbuf, poffset, pleft, " Type: S Frame, SV: %s\n P/F: %d, N(R): %d [V(A): %d, V(R): %d, V(S): %d]\n", type, pf, nr, - link->va, link->vr, link->vs); - } - else if((pmes[2] & 0x03) == 0x03) { - /* - * U frame - */ - L2UCHAR m = (pmes[2] & 0xe0) >> 3 | (pmes[2] & 0x0c) >> 2; /* modifier function id */ - L2UCHAR pf = (pmes[2] & 0x10) >> 4; /* poll / final flag */ - const char *type; - - switch(m) { - case 0x00: - type = "UI (Unnumbered Information)"; - break; - - case 0x03: - type = "DM (Disconnected Mode)"; - break; - - case 0x08: - type = "DISC (Disconnect)"; - break; - - case 0x0c: - type = "UA (Unnumbered Acknowledgement)"; - break; - - case 0x0f: - type = "SABME"; - break; - - case 0x11: - type = "FRMR (Frame Reject)"; - break; - - case 0x17: - type = "XID (Exchange Identification)"; - break; - - default: - type = "Unknown"; - } - - - APPEND_MSG(pbuf, poffset, pleft, " Type: U Frame (%s)\n P/F: %d\n", type, pf); - - if(m == 0x00) { - switch(pmes[3]) { - case Q921_LAYER_ENT_ID_TEI: - type = "TEI Mgmt"; - break; - - case Q921_LAYER_ENT_ID_Q931: - type = "Q.931"; - break; - - default: - type = "Unknown"; - } - - if(pmes[3] == Q921_LAYER_ENT_ID_TEI) { - const char *command = ""; - - switch(pmes[6]) { - case Q921_TEI_ID_REQUEST: - command = "Request"; - break; - case Q921_TEI_ID_VERIFY: - command = "Verify"; - break; - case Q921_TEI_ID_CHECKREQ: - command = "Check req"; - break; - case Q921_TEI_ID_CHECKRESP: - command = "Check resp"; - break; - case Q921_TEI_ID_REMOVE: - command = "Remove"; - break; - case Q921_TEI_ID_ASSIGNED: - command = "Assign"; - break; - case Q921_TEI_ID_DENIED: - command = "Denied"; - break; - } - APPEND_MSG(pbuf, poffset, pleft, " ENT ID: %d (%s), COMMAND: %d (%s), RI: %#x, AI: %d\n", - pmes[3], type, pmes[6], command, (int)((pmes[4] << 8) | pmes[5]), pmes[7] >> 1); - } - else { - APPEND_MSG(pbuf, poffset, pleft, " ENT ID: %d (%s), MESSAGE CONTENT:\n", pmes[3], type); - - len = print_hex(pbuf + poffset, (int)pleft, &pmes[3], size - (trunk->Q921HeaderSpace + 3)); - poffset += len; - pleft -= len; - } - } - } - else { - /* - * Unknown - */ - strncat(pbuf + poffset, " -- unknown frame type --\n", pleft); - - len = (sizeof(pbuf) - poffset) - strlen(pbuf + poffset); - if(len > 0) { - poffset += len; - pleft -= len; - } else - goto out; - } - - APPEND_MSG(pbuf, poffset, pleft, "\n Q.921 state: \"%s\" (%d) [flags: %c%c%c%c]\n", Q921State2Name(link->state), link->state, - Q921_CHECK_FLAG(link, Q921_FLAG_ACK_PENDING) ? 'A' : '-', - Q921_CHECK_FLAG(link, Q921_FLAG_REJECT) ? 'R' : '-', - Q921_CHECK_FLAG(link, Q921_FLAG_PEER_RECV_BUSY) ? 'P' : '-', - Q921_CHECK_FLAG(link, Q921_FLAG_RECV_BUSY) ? 'B' : '-'); - - strncat(pbuf + poffset, "----------------------------------------------\n\n", pleft); - - len = (sizeof(pbuf) - poffset) - strlen(pbuf + poffset); - if(len > 0) { - poffset += len; - pleft -= len; - } else - goto out; - - - /* concat buffers together */ - len = strlen(pbuf); - if(len <= left) - strncat(buf, pbuf, left); - else - strncat(buf, "-- packet truncated --\n", left); - } - -out: - buf[sizeof(buf) - 1] = '\0'; - - return trunk->Q921LogProc(trunk->PrivateDataLog, level, buf, (int)strlen(buf)); -} - -/***************************************************************************** - - Function: Q921TimeTick - - Description: Called periodically from an external source to allow the - stack to process and maintain it's own timers. - - Return Value: none - -*****************************************************************************/ -static L2ULONG (*Q921GetTimeProc) (void) = NULL; /* callback for func reading time in ms */ -static L2ULONG tLast = {0}; - -static L2ULONG Q921GetTime(void) -{ - L2ULONG tNow = 0; - - if(Q921GetTimeProc) - { - tNow = Q921GetTimeProc(); - if(tNow < tLast) /* wrapped */ - { - /* TODO */ - } - tLast = tNow; - } - return tNow; -} - -/* - * T200 handling (per-TEI in PTMP NT mode, tei=0 otherwise) - */ -static void Q921T200TimerStart(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - if (!link->T200) { - link->T200 = Q921GetTime() + trunk->T200Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T200 (timeout: %d msecs) started for TEI %d\n", trunk->T200Timeout, tei); - } -} - -static void Q921T200TimerStop(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->T200 = 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "T200 stopped for TEI %d\n", tei); -} - -static void Q921T200TimerReset(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->T200 = Q921GetTime() + trunk->T200Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T200 (timeout: %d msecs) restarted for TEI %d\n", trunk->T200Timeout, tei); -} - -/* - * T203 handling (per-TEI in PTMP NT mode, tei=0 otherwise) - */ -static void Q921T203TimerStart(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - if (!link->T203) { - link->T203 = Q921GetTime() + trunk->T203Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T203 (timeout: %d msecs) started for TEI %d\n", trunk->T203Timeout, tei); - } -} - -static void Q921T203TimerStop(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->T203 = 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "T203 stopped for TEI %d\n", tei); -} - -static void Q921T203TimerReset(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->T203 = Q921GetTime() + trunk->T203Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T203 (timeout: %d msecs) restarted for TEI %d\n", trunk->T203Timeout, tei); -} - -/* - * T202 handling (TEI message timeout, TE mode only) - */ -static void Q921T202TimerStart(L2TRUNK trunk) -{ - if (!trunk->T202) { - trunk->T202 = Q921GetTime() + trunk->T202Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T202 (timeout: %d msecs) started\n", trunk->T202Timeout); - } -} - -static void Q921T202TimerStop(L2TRUNK trunk) -{ - trunk->T202 = 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "T202 stopped\n"); -} - -static void Q921T202TimerReset(L2TRUNK trunk) -{ - trunk->T202 = Q921GetTime() + trunk->T202Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T202 (timeout: %d msecs) restarted\n", trunk->T202Timeout); -} - -/* - * T201 handling (TEI management (NT side), per-TEI) - */ -static void Q921T201TimerStart(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - if (!link->T201) { - link->T201 = Q921GetTime() + trunk->T201Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T201 (timeout: %d msecs) started for TEI %d\n", trunk->T201Timeout, tei); - } -} - -static void Q921T201TimerStop(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->T201 = 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "T201 stopped for TEI %d\n", tei); -} - -#ifdef __UNUSED_FOR_NOW__ -static void Q921T201TimerReset(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->T201 = Q921GetTime() + trunk->T201Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "T201 (timeout: %d msecs) restarted for TEI %d\n", trunk->T201Timeout, tei); -} -#endif - -/* - * TM01 handling (Datalink inactivity shutdown timer) - */ -static void Q921TM01TimerStart(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - if (!link->TM01) { - link->TM01 = Q921GetTime() + trunk->TM01Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "TM01 (timeout: %d msecs) started for TEI %d\n", trunk->TM01Timeout, tei); - } -} - -#ifdef __UNUSED_FOR_NOW__ -static void Q921TM01TimerStop(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->TM01 = 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "TM01 stopped for TEI %d\n", tei); -} -#endif - -static void Q921TM01TimerReset(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - link->TM01 = Q921GetTime() + trunk->TM01Timeout; - - Q921Log(trunk, Q921_LOG_DEBUG, "TM01 (timeout: %d msecs) restarted for TEI %d\n", trunk->TM01Timeout, tei); -} - -/* - * Expiry callbacks - */ -static void Q921T200TimerExpire(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - struct Q921_Link *trlink = Q921_TRUNK_CONTEXT(trunk); - - Q921Log(trunk, Q921_LOG_DEBUG, "T200 expired for TEI %d (trunk TEI %d)\n", tei, trlink->tei); - - /* Stop timer first */ - Q921T200TimerStop(trunk, tei); - - switch(link->state) { - case Q921_STATE_AWAITING_ESTABLISHMENT: - if(link->N200 >= trunk->N200Limit) { - /* Discard I queue */ - MFIFOClear(link->IFrameQueue); - - /* MDL-Error indication (G) */ - Q921Log(trunk, Q921_LOG_ERROR, "Failed to establish Q.921 link in %d retries\n", link->N200); - - /* DL-Release indication */ - Q921Tx23Proc(trunk, Q921_DL_RELEASE, tei, NULL, 0); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_TEI_ASSIGNED, tei); - } else { - /* Increment retry counter */ - link->N200++; - - /* Send SABME */ - Q921SendSABME(trunk, - trunk->sapi, - Q921_COMMAND(trunk), - tei, - 1); - - /* Start T200 */ - Q921T200TimerStart(trunk, tei); - } - break; - - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - link->N200 = 0; - - if(!Q921_CHECK_FLAG(link, Q921_FLAG_PEER_RECV_BUSY)) { - /* get last transmitted I frame */ - - /* V(S) = V(S) - 1 */ - Q921_DEC_COUNTER(link->vs); - - /* retransmit I frame */ - - /* V(S) = V(S) + 1 (done by Q921SendI() ) */ - //Q921_INC_COUNTER(link->vs); - - /* clear acknowledge pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - - /* Start T200 */ - Q921T200TimerStart(trunk, tei); - } else { - /* transmit enquiry */ - Q921SendEnquiry(trunk, tei); - } - - /* increment counter */ - link->N200++; - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_TIMER_RECOVERY, tei); - break; - - case Q921_STATE_TIMER_RECOVERY: - if(link->N200 == trunk->N200Limit) { - /* MDL Error indication (I) */ - - /* Establish data link */ - Q921EstablishDataLink(trunk, tei); - - /* Clear L3 initiated */ - Q921_CLEAR_FLAG(link, Q921_FLAG_L3_INITIATED); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } else { - if(link->vs == link->va) { - /* transmit enquiry */ - Q921SendEnquiry(trunk, tei); - - } else if(!Q921_CHECK_FLAG(link, Q921_FLAG_PEER_RECV_BUSY)) { - /* get last transmitted frame */ - - /* V(S) = V(S) - 1 */ - Q921_DEC_COUNTER(link->vs); - - /* retrans frame */ - - /* V(S) = V(S) + 1 (done by Q921SendI() ) */ - //Q921_INC_COUNTER(link->vs); - - /* clear acknowledge pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - - /* Start T200 */ - Q921T200TimerStart(trunk, tei); - } - - /* increment counter */ - link->N200++; - - /* no state change */ - } - break; - - default: - break; - } -} - -static void Q921T203TimerExpire(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - struct Q921_Link *trlink = Q921_TRUNK_CONTEXT(trunk); - - Q921Log(trunk, Q921_LOG_DEBUG, "T203 expired for TEI %d (trunk TEI %d)\n", tei, trlink->tei); - - /* Stop Timer first */ - Q921T203TimerStop(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - /* Send Enquiry */ - Q921SendEnquiry(trunk, tei); - - /* RC = 0 */ - link->N200 = 0; - - /* no state change */ - break; - - default: - break; - } -} - -static void Q921T202TimerExpire(L2TRUNK trunk) -{ - struct Q921_Link *link = Q921_TRUNK_CONTEXT(trunk); - - Q921T202TimerReset(trunk); - - Q921Log(trunk, Q921_LOG_DEBUG, "T202 expired for Q.921 trunk with TEI %d\n", link->tei); - - /* todo: implement resend counter */ - - switch(link->state) { - case Q921_STATE_TEI_ASSIGNED: /* Tei identity verify timeout */ - Q921TeiSendVerifyRequest(trunk); - break; - - default: /* Tei assignment request timeout (TODO: refine) */ - - if(trunk->N202 >= trunk->N202Limit) { - /* Too many retransmits, reset counter, stop timer and handle case (TODO) */ - trunk->N202 = 0; - - Q921T202TimerStop(trunk); - - return; - } - Q921TeiSendAssignRequest(trunk); - - trunk->N202++; - } -} - -static void Q921T201TimerExpire(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - struct Q921_Link *trlink = Q921_TRUNK_CONTEXT(trunk); - - Q921Log(trunk, Q921_LOG_DEBUG, "T201 expired for TEI %d (trunk TEI: %d)\n", tei, trlink->tei); - - Q921T201TimerStop(trunk, tei); - - /* NOTE: abusing N202 for this */ - if(link->N202 < trunk->N202Limit) { - /* send check request */ - Q921TeiSendCheckRequest(trunk, tei); - - /* increment counter */ - link->N202++; - } else { - /* put context in STOPPED state */ - Q921ChangeState(trunk, Q921_STATE_STOPPED, tei); - - /* NOTE: should we clear the link too? */ - memset(link, 0, sizeof(struct Q921_Link)); - - /* mark TEI free */ - trunk->tei_map[tei] = 0; - } -} - -#ifdef __UNUSED_FOR_NOW__ -static void Q921TM01TimerExpire(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - struct Q921_Link *trlink = Q921_TRUNK_CONTEXT(trunk); - - Q921Log(trunk, Q921_LOG_DEBUG, "TM01 expired for TEI %d (trunk TEI: %d)\n", tei, trlink->tei); - - /* Restart TM01 */ - Q921TM01TimerReset(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - case Q921_STATE_TIMER_RECOVERY: -/* - * NT-only, needs more support from L3 - */ -#if 0 - /* No activity, shutdown link */ - Q921SendDISC(trunk, trunk->sapi, Q921_COMMAND(trunk), tei, 1); - - /* clear I queue */ - MFIFOClear(link->IFrameQueue); - - /* change state */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_RELEASE, tei); -#endif - break; - - default: - break; - } -} -#endif - -/* - * Timer Tick function - */ -void Q921TimerTick(L2TRUNK trunk) -{ - struct Q921_Link *link; - L2ULONG tNow = Q921GetTime(); - int numlinks = Q921_IS_PTMP_NT(trunk) ? Q921_TEI_MAX : 1; - int x; - - for(x = 0; x <= numlinks; x++) { - link = Q921_LINK_CONTEXT(trunk, x); - - /* TODO: check if TEI is assigned and skip check if not (speedup!) */ - if(link->state == Q921_STATE_STOPPED) - continue; - - if (link->T200 && tNow > link->T200) { - Q921T200TimerExpire(trunk, link->tei); - } - if (link->T203 && tNow > link->T203) { - Q921T203TimerExpire(trunk, link->tei); - } - - if(Q921_IS_PTMP_NT(trunk) && link->tei) { - if (link->T201 && tNow > link->T201) { - Q921T201TimerExpire(trunk, link->tei); - } - } - - if(!Q921_IS_PTMP_NT(trunk)) { - if (trunk->T202 && tNow > trunk->T202) { - Q921T202TimerExpire(trunk); - } - } - - /* Send enqueued I frame, if available */ - Q921SendQueuedIFrame(trunk, link->tei); - - /* Send ack if pending */ - Q921AcknowledgePending(trunk, link->tei); - } - -} - -void Q921SetGetTimeCB(L2ULONG (*callback)(void)) -{ - Q921GetTimeProc = callback; -} - -/***************************************************************************** - - Function: Q921QueueHDLCFrame - - Description: Called to receive and queue an incoming HDLC frame. Will - queue this in Q921HDLCInQueue. The called must either call - Q921Rx12 directly afterwards or signal Q921Rx12 to be called - later. Q921Rx12 will read from the same queue and process - the frame. - - This function assumes that the message contains header - space. This is removed for internal Q921 processing, but - must be keept for I frames. - - Parameters: trunk trunk # - b ptr to frame; - size size of frame in bytes - -*****************************************************************************/ -int Q921QueueHDLCFrame(L2TRUNK trunk, L2UCHAR *b, L2INT size) -{ - return MFIFOWriteMes(trunk->HDLCInQueue, b, size); -} - -/** - * Q921EnqueueI - * \brief Put I frame into transmit queue - * - */ -static int Q921EnqueueI(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR *mes, L2INT size) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, Tei); - - /* I frame header */ - mes[trunk->Q921HeaderSpace+0] = ((Sapi << 2) & 0xfc) | ((cr << 1) & 0x02); - mes[trunk->Q921HeaderSpace+1] = (Tei << 1) | 0x01; - mes[trunk->Q921HeaderSpace+2] = 0x00; - mes[trunk->Q921HeaderSpace+3] = (pf & 0x01); - - Q921Log(trunk, Q921_LOG_DEBUG, "Enqueueing I frame for TEI %d [%d]\n", link->tei, Tei); - - /* transmit queue, (TODO: check for full condition!) */ - MFIFOWriteMes(link->IFrameQueue, mes, size); - - /* try to send queued frame */ - Q921SendQueuedIFrame(trunk, link->tei); - - return 1; -} - -/** - * Q921SendQueuedIFrame - * \brief Try to transmit queued I frame (if available) - */ -static int Q921SendQueuedIFrame(L2TRUNK trunk, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - L2INT size = 0; - L2UCHAR *mes; - - if(MFIFOGetMesCount(link->IFrameQueue) == 0) { - return 0; - } - - /* Link ready? */ - if(link->state != Q921_STATE_MULTIPLE_FRAME_ESTABLISHED) { - return 0; - } - - /* peer receiver busy? */ - if(Q921_CHECK_FLAG(link, Q921_FLAG_PEER_RECV_BUSY)) { - return 0; - } - - /* V(S) = V(A) + k? */ - if(link->vs == ((link->va + trunk->k) % 128)) { - Q921Log(trunk, Q921_LOG_WARNING, "Maximum number (%d) of outstanding I frames reached for TEI %d\n", trunk->k, tei); - return 0; - } - - mes = MFIFOGetMesPtr(link->IFrameQueue, &size); - if(mes) { - /* Fill in + update counter values */ - mes[trunk->Q921HeaderSpace+2] = link->vs << 1; - mes[trunk->Q921HeaderSpace+3] |= link->vr << 1; - - if(MFIFOGetMesCount(link->IFrameQueue) == 0) { - /* clear I frame queued */ - } - - /* Send I frame */ - Q921Tx21Proc(trunk, mes, size); - - /* V(S) = V(S) + 1 */ - Q921_INC_COUNTER(link->vs); - - /* clear acknowledge pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - - /* T200 running? */ - if(!link->T200) { - /* Stop T203, Start T200 */ - Q921T200TimerStart(trunk, tei); - Q921T203TimerStop(trunk, tei); - } - - /* put frame into resend queue */ - MFIFOWriteMesOverwrite(link->IFrameResendQueue, mes, size); - - /* dequeue frame */ - MFIFOKillNext(link->IFrameQueue); - - /* Restart TM01 */ - if(Q921_IS_NT(trunk)) { - Q921TM01TimerReset(trunk, tei); - } - - /* no state change */ - return 1; - } - - return 0; -} - -/** - * Q921SendS - * \brief Prepare and send S frame - */ -static int Q921SendS(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR sv, L2UCHAR *mes, L2INT size) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, Tei); - - if(!Q921_IS_READY(link)) { - /* don't even bother trying */ - Q921Log(trunk, Q921_LOG_DEBUG, "Link not ready, discarding S frame for TEI %d\n", Tei); - return 0; - } - - /* S frame header */ - mes[trunk->Q921HeaderSpace+0] = ((Sapi << 2) & 0xfc) | ((cr << 1) & 0x02); - mes[trunk->Q921HeaderSpace+1] = (Tei << 1) | 0x01; - mes[trunk->Q921HeaderSpace+2] = ((sv << 2) & 0x0c) | 0x01; - mes[trunk->Q921HeaderSpace+3] = (link->vr << 1) | (pf & 0x01); - - return Q921Tx21Proc(trunk, mes, size); -} - - -/** - * Q921SendU - * \brief Prepare and send U frame - */ -static int Q921SendU(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR m, L2UCHAR *mes, L2INT size) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, Tei); - - /* U frame header */ - mes[trunk->Q921HeaderSpace+0] = ((Sapi << 2) & 0xfc) | ((cr << 1) & 0x02); - mes[trunk->Q921HeaderSpace+1] = (Tei << 1) | 0x01; - mes[trunk->Q921HeaderSpace+2] = ((m << 3) & 0xe0) | ((pf << 4) & 0x10) | ((m << 2) & 0x0c) | 0x03; - - /* link not ready? enqueue non-TEI-mgmt UI (DL-UNIT DATA) frames */ - if(m == 0x00 && Sapi != Q921_SAPI_TEI && link->state < Q921_STATE_TEI_ASSIGNED) { - - /* write frame to queue */ - MFIFOWriteMes(link->UIFrameQueue, mes, size); - - Q921Log(trunk, Q921_LOG_DEBUG, "Link not ready, UI Frame of size %d bytes queued for TEI %d\n", size, Tei); - return 1; - } - - return Q921Tx21Proc(trunk, mes, size); -} - -/** - * TODO: NT mode handling? Need a way to get Link context from Q.931 - */ -int Q921Rx32(L2TRUNK trunk, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR * Mes, L2INT Size) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); /* TODO: need real link tei for NT mode */ - L2INT res = 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "Got frame from Q.931, type: %d, tei: %d, size: %d\n", ind, tei, Size); - - switch(ind) { - case Q921_DL_ESTABLISH: - /* - * Hmm... - */ - switch(link->state) { - case Q921_STATE_TEI_ASSIGNED: - if(!Q921_IS_NT(trunk)) { - /* establish data link */ - Q921EstablishDataLink(trunk, link->tei); - - /* Set layer 3 initiated */ - Q921_SET_FLAG(link, Q921_FLAG_L3_INITIATED); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, link->tei); - } - break; - - case Q921_STATE_AWAITING_ESTABLISHMENT: - if(!Q921_IS_NT(trunk)) { - /* Discard I queue */ - MFIFOClear(link->IFrameQueue); - - /* Set layer 3 initiated */ - Q921_SET_FLAG(link, Q921_FLAG_L3_INITIATED); - } - break; - - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - case Q921_STATE_TIMER_RECOVERY: - if(!Q921_IS_NT(trunk)) { - /* Discard I queue */ - MFIFOClear(link->IFrameQueue); - - /* establish data link */ - Q921EstablishDataLink(trunk, link->tei); - - /* Set layer 3 initiated */ - Q921_SET_FLAG(link, Q921_FLAG_L3_INITIATED); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, link->tei); - } - break; - - default: - break; - } - break; - - case Q921_DL_RELEASE: - switch(link->state) { - case Q921_STATE_TEI_ASSIGNED: - /* send DL-RELEASE confirm */ - Q921Tx23Proc(trunk, Q921_DL_RELEASE, tei, NULL, 0); - break; - - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - case Q921_STATE_TIMER_RECOVERY: - if(!Q921_IS_NT(trunk)) { - /* Discard I queue */ - MFIFOClear(link->IFrameQueue); - - /* RC = 0 */ - link->N200 = 0; - - /* send DISC command */ - Q921SendDISC(trunk, trunk->sapi, Q921_COMMAND(trunk), link->tei, 1); - - /* Stop T203, restart T200 */ - if(link->state == Q921_STATE_MULTIPLE_FRAME_ESTABLISHED) { - Q921T203TimerStop(trunk, link->tei); - } - Q921T200TimerReset(trunk, link->tei); - - /* change state */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_RELEASE, link->tei); - } - break; - - default: - break; - } - break; - - case Q921_DL_DATA: /* DL-DATA request */ - res = Q921EnqueueI(trunk, - trunk->sapi, - Q921_COMMAND(trunk), - link->tei, - 0, - Mes, - Size); - - if(link->state < Q921_STATE_MULTIPLE_FRAME_ESTABLISHED) { - /* Treat as implicit DL-ESTABLISH request */ - - /* establish data link */ - Q921EstablishDataLink(trunk, link->tei); - - /* Set layer 3 initiated */ - Q921_SET_FLAG(link, Q921_FLAG_L3_INITIATED); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, link->tei); - } - break; - - case Q921_DL_UNIT_DATA: /* DL-UNIT DATA request */ - res = Q921SendUN(trunk, - trunk->sapi, - Q921_COMMAND(trunk), - Q921_TEI_BCAST, - 0, - Mes, - Size); - /* NOTE: Let the other side initiate link establishment */ - break; - - default: - break; - } - - return res; -} -/***************************************************************************** - - Function: Q921SendRR - - Description: Compose and send Receive Ready. - - Parameters: trunk trunk # - Sapi Sapi - cr C/R field. - Tei Tei. - pf P/F fiels octet 5 - - Return Value: 0 if failed, 1 if Send. - -*****************************************************************************/ - -static int Q921SendRR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf) -{ - L2UCHAR mes[25]; - - return Q921SendS(trunk, Sapi, cr, Tei, pf, 0x00, mes, trunk->Q921HeaderSpace+4); -} - -/***************************************************************************** - - Function: Q921SendRNR - - Description: Compose and send Receive Nor Ready - - Parameters: trunk trunk # - Sapi Sapi - cr C/R field. - Tei Tei. - pf P/F fiels octet 5 - - Return Value: 0 if failed, 1 if Send. - -*****************************************************************************/ -static int Q921SendRNR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf) -{ - L2UCHAR mes[25]; - - return Q921SendS(trunk, Sapi, cr, Tei, pf, 0x01, mes, trunk->Q921HeaderSpace+4); -} - -/***************************************************************************** - - Function: Q921SendREJ - - Description: Compose and Send Reject. - - Parameters: trunk trunk # - Sapi Sapi - cr C/R field. - Tei Tei. - pf P/F fiels octet 5 - - Return Value: 0 if failed, 1 if Send. - -*****************************************************************************/ -static int Q921SendREJ(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf) -{ - L2UCHAR mes[25]; - - return Q921SendS(trunk, Sapi, cr, Tei, pf, 0x03, mes, trunk->Q921HeaderSpace+4); -} - -/***************************************************************************** - - Function: Q921SendSABME - - Description: Compose and send SABME - - Parameters: trunk trunk # - Sapi Sapi - cr C/R field. - Tei Tei. - pf P fiels octet 4 - - Return Value: 0 if failed, 1 if Send. - -*****************************************************************************/ -static int Q921SendSABME(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf) -{ - L2UCHAR mes[25]; - - return Q921SendU(trunk, Sapi, cr, Tei, pf, 0x0f, mes, trunk->Q921HeaderSpace+3); -} - - -/** - * Q921Start - * \brief Start trunk - * \param[in] trunk pointer to Q921 data struct - * \return > 0 on success; <= 0 on error - */ -int Q921Start(L2TRUNK trunk) -{ - int x, numlinks = Q921_IS_PTMP_NT(trunk) ? Q921_TEI_MAX : 1; - struct Q921_Link *link = Q921_TRUNK_CONTEXT(trunk); - - if(trunk->initialized != INITIALIZED_MAGIC) - return 0; - - memset(trunk->context, 0, numlinks * sizeof(struct Q921_Link)); - - /* Common init part */ - for(x = 0; x <= numlinks; x++) { - link = Q921_LINK_CONTEXT(trunk, x); - - link->state = Q921_STATE_TEI_UNASSIGNED; - link->tei = 0; - - /* Initialize per-TEI I + UI queues */ - MFIFOCreate(link->UIFrameQueue, Q921MAXHDLCSPACE, 10); - MFIFOCreate(link->IFrameQueue, Q921MAXHDLCSPACE, 10); - MFIFOCreate(link->IFrameResendQueue, Q921MAXHDLCSPACE, 10); - } - - if(Q921_IS_PTMP_TE(trunk)) { - link->state = Q921_STATE_TEI_UNASSIGNED; - link->tei = 0; - } - else if(Q921_IS_PTMP_NT(trunk)) { - link = Q921_TRUNK_CONTEXT(trunk); - - link->state = Q921_STATE_TEI_ASSIGNED; - link->tei = trunk->tei; - - /* clear tei map */ - memset(trunk->tei_map, 0, Q921_TEI_MAX + 1); - } - else { - link->state = Q921_STATE_TEI_ASSIGNED; - link->tei = trunk->tei; - } - - Q921Log(trunk, Q921_LOG_DEBUG, "Starting trunk %p (sapi: %d, tei: %d, mode: %s %s)\n", - trunk, - trunk->sapi, - link->tei, - Q921_IS_PTMP(trunk) ? "PTMP" : "PTP", - Q921_IS_TE(trunk) ? "TE" : "NT"); - - if(Q921_IS_PTP(trunk)) { - Q921Log(trunk, Q921_LOG_DEBUG, "Sending SABME\n"); - - return Q921SendSABME(trunk, - trunk->sapi, - Q921_COMMAND(trunk), - link->tei, - 1); - - } else if(Q921_IS_PTMP_NT(trunk)) { - - Q921Log(trunk, Q921_LOG_DEBUG, "Revoking all TEIs\n"); - - return Q921TeiSendRemoveRequest(trunk, Q921_TEI_BCAST); /* Revoke all TEIs in use */ - } else { - - Q921Log(trunk, Q921_LOG_DEBUG, "Requesting TEI\n"); - - return Q921TeiSendAssignRequest(trunk); - } -} - - -/** - * Q921Stop - * \brief Stop trunk - * \param[in] trunk pointer to Q921 data struct - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -int Q921Stop(L2TRUNK trunk) -{ - struct Q921_Link *link; - int x, numlinks; - - if(!trunk) - return -1; - - link = Q921_TRUNK_CONTEXT(trunk); - numlinks = Q921_IS_PTMP_NT(trunk) ? Q921_TEI_MAX : 1; - - if(Q921_IS_STOPPED(link)) - return 0; - - /* Release TEI */ - if(Q921_IS_PTMP_TE(trunk)) { - /* send verify request */ - Q921TeiSendVerifyRequest(trunk); - - /* drop TEI */ - link->tei = 0; - } - - /* Stop timers, stop link, flush queues */ - for(x = 0; x <= numlinks; x++) { - Q921T200TimerStop(trunk, x); - Q921T203TimerStop(trunk, x); - Q921T201TimerStop(trunk, x); - - /* Change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_STOPPED, x); - - /* Flush per-tei I/UI queues */ - MFIFOClear(link->UIFrameQueue); - MFIFOClear(link->IFrameQueue); - MFIFOClear(link->IFrameResendQueue); - } - Q921T202TimerStop(trunk); - - /* Flush HDLC queue */ - MFIFOClear(trunk->HDLCInQueue); - - return 0; -} - - -/***************************************************************************** - - Function: Q921SendDM - - Description: Compose and Send DM (Disconnected Mode) - - Parameters: trunk trunk # - Sapi Sapi - cr C/R field. - Tei Tei. - pf F fiels octet 4 - - Return Value: 0 if failed, 1 if Send. - -*****************************************************************************/ -static int Q921SendDM(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf) -{ - L2UCHAR mes[25]; - - return Q921SendU(trunk, Sapi, cr, Tei, pf, 0x03, mes, trunk->Q921HeaderSpace+3); -} - -/***************************************************************************** - - Function: Q921SendDISC - - Description: Compose and Send Disconnect - - Parameters: trunk trunk # - Sapi Sapi - cr C/R field. - Tei Tei. - pf P fiels octet 4 - - Return Value: 0 if failed, 1 if Send. - -*****************************************************************************/ -static int Q921SendDISC(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf) -{ - L2UCHAR mes[25]; - - return Q921SendU(trunk, Sapi, cr, Tei, pf, 0x08, mes, trunk->Q921HeaderSpace+3); -} - -/***************************************************************************** - - Function: Q921SendUA - - Description: Compose and Send UA - - Parameters: trunk trunk # - Sapi Sapi - cr C/R field. - Tei Tei. - pf F fiels octet 4 - - Return Value: 0 if failed, 1 if Send. - -*****************************************************************************/ -static int Q921SendUA(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf) -{ - L2UCHAR mes[25]; - - return Q921SendU(trunk, Sapi, cr, Tei, pf, 0x0c, mes, trunk->Q921HeaderSpace+3); -} - -static int Q921SendUN(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf, L2UCHAR *mes, L2INT size) -{ - return Q921SendU(trunk, Sapi, cr, Tei, pf, 0x00, mes, size+trunk->Q921HeaderSpace+3); -} - - -/** - * Q921ProcSABME - * \brief Handle incoming SABME - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success, <= 0 on error - */ -static int Q921ProcSABME(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR pf = (mes[2] & 0x10) >> 4; /* poll / final flag */ - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_TEI_ASSIGNED: - /* send UA */ - Q921SendUA(trunk, - trunk->sapi, - Q921_RESPONSE(trunk), /* or command? */ - tei, pf); - - /* clear counters */ - link->vr=0; - link->vs=0; - link->va=0; - - /* TODO: send DL-Establish indication to Q.931 */ - Q921Tx23Proc(trunk, Q921_DL_ESTABLISH, tei, NULL, 0); - - /* start T203 */ - Q921T203TimerStart(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, tei); - break; - - case Q921_STATE_AWAITING_ESTABLISHMENT: - /* send UA */ - Q921SendUA(trunk, - trunk->sapi, - Q921_RESPONSE(trunk), - tei, pf); - - /* no state change */ - break; - - case Q921_STATE_AWAITING_RELEASE: - /* send DM */ - Q921SendDM(trunk, - trunk->sapi, - Q921_RESPONSE(trunk), - tei, pf); - - /* no state change */ - break; - - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - case Q921_STATE_TIMER_RECOVERY: - /* send UA */ - Q921SendUA(trunk, - trunk->sapi, - Q921_RESPONSE(trunk), - tei, pf); - - /* clear exception conditions */ - Q921ResetExceptionConditions(trunk, tei); - - /* send MDL-Error indication */ - - /* V(S) == V(A) ? */ - if(link->vs != link->va) { - /* clear I queue */ - MFIFOClear(link->IFrameQueue); - - /* DL-Establish indication */ - Q921Tx23Proc(trunk, Q921_DL_ESTABLISH, tei, NULL, 0); - } - - /* clear counters */ - link->vr=0; - link->vs=0; - link->va=0; - - /* Stop T200, start T203 */ - Q921T200TimerStop(trunk, tei); - Q921T203TimerStart(trunk, tei); - - /* state change only if in TIMER_RECOVERY state */ - if(link->state == Q921_STATE_TIMER_RECOVERY) - Q921ChangeState(trunk, Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, tei); - break; - - default: - break; - } - - return 1; -} - - -/** - * Q921ProcDM - * \brief Handle incoming DM - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success, <= 0 on error - */ -static int Q921ProcDM(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR pf = (mes[2] & 0x10) >> 4; /* poll / final flag */ - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_TEI_ASSIGNED: - if(!pf) { - /* to next state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - case Q921_STATE_AWAITING_ESTABLISHMENT: - case Q921_STATE_AWAITING_RELEASE: - if(pf) { - if(link->state == Q921_STATE_AWAITING_ESTABLISHMENT) { - /* Discard I queue */ - MFIFOClear(link->IFrameQueue); - } - - /* Send DL-Release indication to Q.931 */ - Q921Tx23Proc(trunk, Q921_DL_RELEASE, tei, NULL, 0); - - /* Stop T200 */ - Q921T200TimerStop(trunk, tei); - - /* Change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_TEI_ASSIGNED, tei); - } - break; - - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - if(pf) { - /* MDL-Error indication (B) */ - - /* no state change */ - } else { - /* MDL-Error indication (E) */ - - /* establish data link */ - Q921EstablishDataLink(trunk, tei); - - /* clear L3 initiated */ - Q921_CLEAR_FLAG(link, Q921_FLAG_L3_INITIATED); - - /* change state (no action?) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - case Q921_STATE_TIMER_RECOVERY: - if(pf) { - /* MDL Error indication (B) */ - } else { - /* MDL Error indication (E) */ - } - - /* establish data link */ - Q921EstablishDataLink(trunk, tei); - - /* clear layer 3 initiated */ - Q921_CLEAR_FLAG(link, Q921_FLAG_L3_INITIATED); - - /* change state */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - break; - - default: - break; - } - - return 1; -} - -/** - * Q921ProcUA - * \brief Handle incoming UA - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success, <= 0 on error - */ -static int Q921ProcUA(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR pf = (mes[2] & 0x10) >> 4; /* poll / final flag */ - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_TEI_ASSIGNED: - case Q921_STATE_TIMER_RECOVERY: - /* MDL Error indication (C, D) */ - Q921Log(trunk, Q921_LOG_ERROR, "Received UA frame in invalid state\n"); - break; - - case Q921_STATE_AWAITING_ESTABLISHMENT: - if(pf) { - /* TODO: other fancy stuff (see docs) */ - if(Q921_CHECK_FLAG(link, Q921_FLAG_L3_INITIATED)) { /* layer3 initiated */ - link->vr = 0; - - /* DL-Establish confirm */ - Q921Tx23Proc(trunk, Q921_DL_ESTABLISH_CONFIRM, tei, NULL, 0); - - } else if(link->vs != link->va) { - - /* discard I queue */ - MFIFOClear(link->IFrameQueue); - - /* DL-Establish indication */ - Q921Tx23Proc(trunk, Q921_DL_ESTABLISH, tei, NULL, 0); - } - - /* Stop T200, start T203 */ - Q921T200TimerStop(trunk, tei); - Q921T203TimerStart(trunk, tei); - - link->vs = 0; - link->va = 0; - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, tei); - } else { - /* MDL Error indication (C, D) */ - Q921Log(trunk, Q921_LOG_ERROR, "Received UA frame is not a response to a request\n"); - - /* no state change */ - } - break; - - case Q921_STATE_AWAITING_RELEASE: - if(pf) { - /* DL Release confirm */ - Q921Tx23Proc(trunk, Q921_DL_RELEASE_CONFIRM, tei, NULL, 0); - - /* Stop T200 */ - Q921T200TimerStop(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_TEI_ASSIGNED, tei); - } else { - /* MDL Error indication (D) */ - Q921Log(trunk, Q921_LOG_ERROR, "Received UA frame is not a response to a request\n"); - - /* no state change */ - } - break; - - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - /* MDL Error indication (C, D) */ - Q921Log(trunk, Q921_LOG_ERROR, "Received UA frame in invalid state\n"); - - /* no state change */ - break; - - default: - break; - } - - return 1; -} - - -/** - * Q921ProcDISC - * \brief Handle incoming DISC - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success, <= 0 on error - */ -static int Q921ProcDISC(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR pf = (mes[2] & 0x10) >> 4; /* poll / final flag */ - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_TEI_ASSIGNED: - case Q921_STATE_AWAITING_ESTABLISHMENT: - /* Send DM */ - Q921SendDM(trunk, - trunk->sapi, - Q921_RESPONSE(trunk), - tei, pf); - - /* no state change */ - break; - - case Q921_STATE_AWAITING_RELEASE: - Q921SendUA(trunk, - trunk->sapi, - Q921_RESPONSE(trunk), - tei, pf); - - /* no state change */ - break; - - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - case Q921_STATE_TIMER_RECOVERY: - /* Discard I queue */ - MFIFOClear(link->IFrameQueue); - - /* send UA */ - Q921SendUA(trunk, - trunk->sapi, - Q921_RESPONSE(trunk), - tei, pf); - - /* DL Release indication */ - Q921Tx23Proc(trunk, Q921_DL_RELEASE, tei, NULL, 0); - - /* Stop T200 */ - Q921T200TimerStop(trunk, tei); - - if(link->state == Q921_STATE_MULTIPLE_FRAME_ESTABLISHED) { - /* Stop T203 */ - Q921T203TimerStop(trunk, tei); - } - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_TEI_ASSIGNED, tei); - break; - - default: - Q921Log(trunk, Q921_LOG_ERROR, "Invalid DISC received in state \"%s\" (%d)", Q921State2Name(link->state), link->state); - break; - } - - return 1; -} - - -/** - * Q921ProcRR - * \brief Handle incoming RR - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success, <= 0 on error - */ -static int Q921ProcRR(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR cr = (mes[0] & 0x02) >> 1; - L2UCHAR pf = mes[3] & 0x01; /* poll / final flag */ - L2UCHAR nr = (mes[3] >> 1); -// L2UCHAR sapi = (mes[0] & 0xfc) >> 2; - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - /* clear receiver peer busy */ - Q921_CLEAR_FLAG(link, Q921_FLAG_PEER_RECV_BUSY); - - if (Q921_IS_COMMAND(trunk, cr)) { /* if this is a command */ - if(pf) { - /* Enquiry response */ - Q921SendEnquiryResponse(trunk, tei); - } - } else { - if(pf) { - /* MDL Error indication */ - } - } - - /* */ - if(link->va <= nr && nr <= link->vs) { - - if(nr == link->vs) { - /* V(A) = N(R) */ - link->va = nr; - - /* Stop T200, restart T203 */ - Q921T200TimerStop(trunk, tei); - Q921T203TimerReset(trunk, tei); - - } else if(nr == link->va) { - - /* do nothing */ - - } else { - /* V(A) = N(R) */ - link->va = nr; - - /* Restart T200 */ - Q921T200TimerReset(trunk, tei); - } - /* no state change */ - - } else { - /* N(R) Error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - case Q921_STATE_TIMER_RECOVERY: - /* clear receiver peer busy */ - Q921_CLEAR_FLAG(link, Q921_FLAG_PEER_RECV_BUSY); - - /* command + P? */ - if(Q921_IS_COMMAND(trunk, cr) && pf) { - /* Enquiry response */ - Q921SendEnquiryResponse(trunk, tei); - } - - /* */ - if(link->va <= nr && nr <= link->vs) { - /* V(A) = N(R) */ - link->va = nr; - - if(!Q921_IS_COMMAND(trunk, cr) && pf) { - /* Stop T200, start T203 */ - Q921T200TimerStop(trunk, tei); - Q921T203TimerStart(trunk, tei); - - /* Invoke retransmission */ - Q921InvokeRetransmission(trunk, tei, nr); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, tei); - } - /* no state change otherwise */ - } else { - /* N(R) Error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - default: - break; - } - return 1; -} - - -/** - * Q921ProcREJ - * \brief Handle incoming REJ - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success, <= 0 on error - */ -static int Q921ProcREJ(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR cr = (mes[0] & 0x02) >> 1; - L2UCHAR pf = mes[3] & 0x01; /* poll / final flag */ - L2UCHAR nr = (mes[3] >> 1); -// L2UCHAR sapi = (mes[0] & 0xfc) >> 2; - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - /* clear receiver peer busy */ - Q921_CLEAR_FLAG(link, Q921_FLAG_PEER_RECV_BUSY); - - /* command? */ - if(Q921_IS_COMMAND(trunk, cr)) { - if(pf) { - /* Enquiry response */ - Q921SendEnquiryResponse(trunk, tei); - } - } else { - if(pf) { - /* MDL Error indication (A) */ - } - } - - /* */ - if(link->va <= nr && nr <= link->vs) { - - /* V(A) = N(R) */ - link->va = nr; - - /* Stop T200, start T203 */ - Q921T200TimerStop(trunk, tei); - Q921T203TimerStart(trunk, tei); - - /* Invoke retransmission of frame >N(R) (?) */ - Q921InvokeRetransmission(trunk, tei, nr); - - /* no state change */ - } else { - /* N(R) Error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - case Q921_STATE_TIMER_RECOVERY: - /* clear receiver peer busy */ - Q921_CLEAR_FLAG(link, Q921_FLAG_PEER_RECV_BUSY); - - /* command + P ? */ - if(Q921_IS_COMMAND(trunk, cr) && pf) { - /* Enquiry response */ - Q921SendEnquiryResponse(trunk, tei); - } - - /* */ - if(link->va <= nr && nr <= link->vs) { - - /* V(A) = N(R) */ - link->va = nr; - - if(!Q921_IS_COMMAND(trunk, cr) && pf) { - /* Stop T200, start T203 */ - Q921T200TimerStop(trunk, tei); - Q921T203TimerStart(trunk, tei); - - /* Invoke retransmission */ - Q921InvokeRetransmission(trunk, tei, nr); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, tei); - } - /* no state change otherwise */ - } else { - /* N(R) Error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - default: - break; - } - - return 1; -} - - -/** - * Q921ProcRNR - * \brief Handle incoming RNR - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success, <= 0 on error - */ -static int Q921ProcRNR(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR cr = (mes[0] & 0x02) >> 1; - L2UCHAR pf = mes[3] & 0x01; /* poll / final flag */ - L2UCHAR nr = (mes[3] >> 1); -// L2UCHAR sapi = (mes[0] & 0xfc) >> 2; - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - /* set peer receiver busy */ - Q921_SET_FLAG(link, Q921_FLAG_PEER_RECV_BUSY); - - /* command? */ - if(Q921_IS_COMMAND(trunk, cr)) { - if(pf) { - /* Enquiry response */ - Q921SendEnquiryResponse(trunk, tei); - } - } else { - if(pf) { - /* MDL Error indication (A) */ - } - } - - /* */ - if(link->va <= nr && nr <= link->vs) { - - /* V(A) = N(R) */ - link->va = nr; - - /* Stop T203, restart T200 */ - Q921T200TimerReset(trunk, tei); - Q921T203TimerStop(trunk, tei); - - /* no state change */ - } else { - /* N(R) Error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - case Q921_STATE_TIMER_RECOVERY: - /* set peer receiver busy */ - Q921_SET_FLAG(link, Q921_FLAG_PEER_RECV_BUSY); - - /* command + P? */ - if(Q921_IS_COMMAND(trunk, cr) && pf) { - /* Enquiry response */ - Q921SendEnquiryResponse(trunk, tei); - } - - /* */ - if(link->va <= nr && nr <= link->vs) { - - /* V(A) = N(R) */ - link->va = nr; - - if(!Q921_IS_COMMAND(trunk, cr) && pf) { - /* Restart T200 */ - Q921T200TimerReset(trunk, tei); - - /* Invoke retransmission */ - Q921InvokeRetransmission(trunk, tei, nr); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, tei); - } - /* no state change otherwise */ - } else { - /* N(R) Error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - default: - break; - } - - return 1; -} - -#if 0 -static int Q921SetReceiverBusy(L2TRUNK trunk) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - if(!Q921_CHECK_FLAG(link, Q921_FLAG_RECV_BUSY)) { - /* set own receiver busy */ - Q921_SET_FLAG(link, Q921_FLAG_RECV_BUSY); - - /* send RR response */ - Q921SendRR(trunk, trunk->sapi, Q921_RESPONSE(trunk), link->tei, 0); - - /* clear ack pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - break; - - case Q921_STATE_TIMER_RECOVERY: - if(!Q921_CHECK_FLAG(link, Q921_FLAG_RECV_BUSY)) { - /* set own receiver busy */ - Q921_SET_FLAG(link, Q921_FLAG_RECV_BUSY); - - /* send RNR response */ - Q921SendRNR(trunk, trunk->sapi, Q921_RESPONSE(trunk), link->tei, 0); - - /* clear ack pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - break; - - default: - break; - } - - return 0; -} - -static int Q921ClearReceiverBusy(L2TRUNK trunk) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - case Q921_STATE_TIMER_RECOVERY: - if(Q921_CHECK_FLAG(link, Q921_FLAG_RECV_BUSY)) { - /* clear own receiver busy */ - Q921_CLEAR_FLAG(link, Q921_FLAG_RECV_BUSY); - - /* send RNR response */ - Q921SendRNR(trunk, trunk->sapi, Q921_RESPONSE(trunk), link->tei, 0); - - /* clear ack pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - break; - - default: - break; - } - - return 0; -} -#endif - -static int Q921ProcIFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - /* common fields: get sapi, tei and cr */ -// L2UCHAR sapi = (mes[0] & 0xfc) >> 2; -// L2UCHAR cr = (mes[0] & 0x02) >> 1; - L2UCHAR tei = (mes[1] & 0xfe) >> 1; - L2UCHAR pf = mes[3] & 0x01; /* poll / final flag */ - L2UCHAR nr = mes[3] >> 1; /* receive sequence number */ - L2UCHAR ns = mes[2] >> 1; /* send sequence number */ - L2UCHAR discard = 0; - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - /* Ignore I frames in earlier states */ - if(link->state < Q921_STATE_MULTIPLE_FRAME_ESTABLISHED) { - Q921Log(trunk, Q921_LOG_NOTICE, "I frame in invalid state ignored\n"); - return 0; - } - - /* Receiver busy? */ - if(Q921_CHECK_FLAG(link, Q921_FLAG_RECV_BUSY)) { - /* discard information */ - discard = 1; - - if(pf) { - /* send RNR Response */ - Q921SendRNR(trunk, trunk->sapi, Q921_RESPONSE(trunk), tei, 1); - - /* Clear ack pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - } - else { - if(ns != link->vr) { - /* discard information */ - discard = 1; - - if(Q921_CHECK_FLAG(link, Q921_FLAG_REJECT) && pf) { - - /* Send RR response */ - Q921SendRR(trunk, trunk->sapi, Q921_RESPONSE(trunk), tei, 1); - - /* clear ack pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - else if(!Q921_CHECK_FLAG(link, Q921_FLAG_REJECT)){ - - /* set reject exception */ - Q921_SET_FLAG(link, Q921_FLAG_REJECT); - - /* Send REJ response */ - Q921SendREJ(trunk, trunk->sapi, Q921_RESPONSE(trunk), tei, pf); - - /* clear ack pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - } - else { - /* V(R) = V(R) + 1 */ - Q921_INC_COUNTER(link->vr); - - /* clear reject exception */ - Q921_CLEAR_FLAG(link, Q921_FLAG_REJECT); - - /* DL-Data indication */ - Q921Tx23Proc(trunk, Q921_DL_DATA, tei, mes, size); - - if(pf) { - /* Send RR response */ - Q921SendRR(trunk, trunk->sapi, Q921_RESPONSE(trunk), tei, 1); - - /* clear ack pending */ - Q921_CLEAR_FLAG(link, Q921_FLAG_ACK_PENDING); - } - else if(!Q921_CHECK_FLAG(link, Q921_FLAG_ACK_PENDING)) { - /* ack pending */ - - /* Send RR response */ - Q921SendRR(trunk, trunk->sapi, Q921_RESPONSE(trunk), tei, 0); - - /* set ack pending*/ - Q921_SET_FLAG(link, Q921_FLAG_ACK_PENDING); - } - } - } - - - switch(link->state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - if(link->va <= nr && nr <= link->vs) { - if(Q921_CHECK_FLAG(link, Q921_FLAG_PEER_RECV_BUSY)) { - link->va = nr; - } - else if(nr == link->vs) { - /* V(A) = N(R) */ - link->va = nr; - - /* stop t200, restart t203 */ - Q921T200TimerStop(trunk, tei); - Q921T203TimerReset(trunk, tei); - } - else if(nr != link->va) { - /* V(A) = N(R) */ - link->va = nr; - - /* restart T200 */ - Q921T200TimerReset(trunk, tei); - } - - /* Restart TM01 */ - if(Q921_IS_NT(trunk)) { - Q921TM01TimerReset(trunk, tei); - } - } - else { - /* N(R) error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - case Q921_STATE_TIMER_RECOVERY: - if(link->va <= nr && nr <= link->vs) { - /* V(A) = N(R) */ - link->va = nr; - - /* Restart TM01 */ - if(Q921_IS_NT(trunk)) { - Q921TM01TimerReset(trunk, tei); - } - } - else { - /* N(R) error recovery */ - Q921NrErrorRecovery(trunk, tei); - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_AWAITING_ESTABLISHMENT, tei); - } - break; - - default: - break; - } - - return 0; -} - - -static int Q921ProcSFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR sv = (mes[2] & 0x0c) >> 2; /* supervisory format id */ - //L2UCHAR pf = mes[3] & 0x01; /* poll / final flag */ - //L2UCHAR nr = mes[3] >> 1; /* receive sequence number */ - L2INT res = -1; - - switch(sv) { - case 0x00: /* RR : Receive Ready */ - res = Q921ProcRR(trunk, mes, size); - break; - - case 0x02: /* RNR : Receive Not Ready */ - res = Q921ProcRNR(trunk, mes, size); - break; - - case 0x04: /* REJ : Reject */ - res = Q921ProcREJ(trunk, mes, size); - break; - - default: /* Invalid / Unknown */ - Q921Log(trunk, Q921_LOG_ERROR, "Invalid S frame type %d\n", sv); - break; - } - - return res; -} - - - -static int Q921ProcUFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR m = (mes[2] & 0xe0) >> 3 | (mes[2] & 0x0c) >> 2; /* modifier function id */ -// L2UCHAR pf = (mes[2] & 0x10) >> 4; /* poll / final flag */ - L2INT res = -1; - - switch(m) { - case 0x00: /* UN : Unnumbered Information */ - if(mes[3] == Q921_LAYER_ENT_ID_TEI) - { - if(!Q921_IS_PTMP(trunk)) { - /* wtf? nice try */ - return res; - } - - switch(mes[6]) { - case Q921_TEI_ID_REQUEST: /* (TE ->) NT */ - res = Q921TeiProcAssignRequest(trunk, mes, size); - break; - - case Q921_TEI_ID_ASSIGNED: /* (NT ->) TE */ - case Q921_TEI_ID_DENIED: - res = Q921TeiProcAssignResponse(trunk, mes, size); - break; - - case Q921_TEI_ID_CHECKREQ: /* (NT ->) TE */ - res = Q921TeiProcCheckRequest(trunk, mes, size); - break; - - case Q921_TEI_ID_CHECKRESP: /* (TE ->) NT */ - res = Q921TeiProcCheckResponse(trunk, mes, size); - break; - - case Q921_TEI_ID_REMOVE: /* (NT ->) TE */ - res = Q921TeiProcRemoveRequest(trunk, mes, size); - break; - - case Q921_TEI_ID_VERIFY: /* (TE ->) NT */ - res = Q921TeiProcVerifyRequest(trunk, mes, size); - break; - - default: /* Invalid / Unknown */ - Q921Log(trunk, Q921_LOG_ERROR, "Invalid UN message from TEI management/endpoint\n"); - break; - } - } - else if(mes[3] == Q921_LAYER_ENT_ID_Q931) { - - Q921Log(trunk, Q921_LOG_DEBUG, "UI Frame for Layer 3 received\n"); - - res = Q921Tx23Proc(trunk, Q921_DL_UNIT_DATA, 0, mes, size); - } - break; - - case 0x03: /* DM : Disconnect Mode */ - res = Q921ProcDM(trunk, mes, size); - break; - - case 0x08: /* DISC : Disconnect */ - res = Q921ProcDISC(trunk, mes, size); - break; - - case 0x0c: /* UA : Unnumbered Acknowledgement */ - res = Q921ProcUA(trunk, mes, size); - break; - - case 0x0f: /* SABME : Set Asynchronous Balanced Mode Extend */ - res = Q921ProcSABME(trunk, mes, size); - break; - - case 0x11: /* FRMR : Frame Reject */ - case 0x17: /* XID : Exchange Identification */ - res = 0; - break; - - default: /* Unknown / Invalid */ - Q921Log(trunk, Q921_LOG_ERROR, "Invalid U frame type: %d\n", m); - break; - } - - return res; -} - - -/***************************************************************************** - - Function: Q921Rx12 - - Description: Called to process a message frame from layer 1. Will - identify the message and call the proper 'processor' for - layer 2 messages and forward I frames to the layer 3 entity. - - Q921Rx12 will check the input fifo for a message, and if a - message exist process one message before it exits. The caller - must either call Q921Rx12 polling or keep track on # - messages in the queue. - - Parameters: trunk trunk #. - - Return Value: # messages processed (always 1 or 0). - -*****************************************************************************/ -int Q921Rx12(L2TRUNK trunk) -{ - L2INT size; /* receive size & Q921 frame size*/ - L2UCHAR *smes = MFIFOGetMesPtr(trunk->HDLCInQueue, &size); - - if(smes) - { - struct Q921_Link *link; - L2UCHAR sapi, tei; - L2UCHAR *mes; - L2INT rs; - - rs = size - trunk->Q921HeaderSpace; - mes = &smes[trunk->Q921HeaderSpace]; - - Q921LogMesg(trunk, Q921_LOG_DEBUG, 1, mes, rs, "New packet received (%d bytes)", rs); - - /* common fields: get sapi, tei and cr */ - sapi = (mes[0] & 0xfc) >> 2; - tei = (mes[1] & 0xfe) >> 1; - link = Q921_LINK_CONTEXT(trunk, tei); - - if(Q921_IS_PTMP_TE(trunk) && ( - (link->state >= Q921_STATE_TEI_ASSIGNED && tei != link->tei && tei != Q921_TEI_BCAST) || /* Assigned TEI: Only BCAST and directed */ - (link->state == Q921_STATE_TEI_UNASSIGNED && tei != Q921_TEI_BCAST))) /* No assigned TEI: Only BCAST */ - { - /* Ignore Messages with foreign TEIs */ - goto out; - } - - if((mes[2] & 0x01) == 0x00) { /* I frame */ - Q921ProcIFrame(trunk, mes, rs); - } - else if((mes[2] & 0x03) == 0x01) { /* S frame */ - Q921ProcSFrame(trunk, mes, rs); - } - else if((mes[2] & 0x03) == 0x03) { /* U frame */ - Q921ProcUFrame(trunk, mes, rs); - } - else { - Q921Log(trunk, Q921_LOG_ERROR, "Invalid frame type: %d\n", (int)(mes[2] & 0x03)); - /* TODO: send FRMR or REJ */ - } - -out: - MFIFOKillNext(trunk->HDLCInQueue); - - return 1; - } - - return 0; -} - -/* - * Misc - */ -/** - * Q921SetLogCB - * \brief Set logging callback - * \param[in] trunk pointer to Q921 data struct - * \param[in] func pointer to logging callback function - * \param[in] priv pointer to private data - * - * \author Stefan Knoblich - */ -void Q921SetLogCB(L2TRUNK trunk, Q921LogCB_t func, void *priv) -{ - if(!trunk) - return; - - trunk->Q921LogProc = func; - trunk->PrivateDataLog = priv; -} - -/** - * Q921SetLogLevel - * \brief Set loglevel of Q.921 logging functions - * \param[in] trunk pointer to Q921 data struct - * \param[in] level new loglevel - * - * \author Stefan Knoblich - */ -void Q921SetLogLevel(L2TRUNK trunk, Q921LogLevel_t level) -{ - if(!trunk) - return; - - if (level < Q921_LOG_NONE) { - level = Q921_LOG_NONE; - } else if (level > Q921_LOG_DEBUG) { - level = Q921_LOG_DEBUG; - } - - trunk->loglevel = level; -} - - -/** - * Q921ChangeState - * \brief Change state, invoke neccessary actions - * \param[in] trunk pointer to Q921 data struct - * \param[in] state state to change to - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921ChangeState(L2TRUNK trunk, Q921State_t state, L2UCHAR tei) -{ - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - Q921State_t oldstate = link->state; - int res = 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "Changing state from \"%s\" (%d) to \"%s\" (%d) for TEI %d\n", - Q921State2Name(oldstate), oldstate, - Q921State2Name(state), state, - tei); - - /* - * generic actions (depending on the target state only) - */ - switch(state) { - case Q921_STATE_MULTIPLE_FRAME_ESTABLISHED: - /* Start TM01 */ - if(Q921_IS_NT(trunk)) { - Q921TM01TimerStart(trunk, tei); - } - break; - - default: - break; - } - - /* - * actions that depend on type of the old -> new state transition - */ - switch(oldstate) { - case Q921_STATE_STOPPED: - - switch(state) { - case Q921_STATE_TEI_UNASSIGNED: - if(Q921_IS_PTMP_TE(trunk)) { - res = Q921TeiSendAssignRequest(trunk); - } - break; - - case Q921_STATE_TEI_ASSIGNED: - if(Q921_IS_PTMP_NT(trunk)) { - res = Q921TeiSendRemoveRequest(trunk, Q921_TEI_BCAST); - } - break; - - default: - break; - } - break; - - default: - break; - } - - link->state = state; - - Q921Log(trunk, Q921_LOG_DEBUG, "Q921ChangeState() returns %d, new state is \"%s\" (%d) for TEI %d\n", res, Q921State2Name(state), state, tei); - - return res; -} - -/* - * TEI Management functions - * \note All TEI-mgmt UN frames are sent with cr = command! - */ -static int Q921TeiSend(L2TRUNK trunk, L2UCHAR type, L2USHORT ri, L2UCHAR ai) -{ - L2UCHAR mes[10]; - L2UCHAR offset = Q921_UFRAME_DATA_OFFSET(trunk); - - mes[offset++] = Q921_LAYER_ENT_ID_TEI; /* layer management entity identifier */ - mes[offset++] = (ri & 0xff00) >> 8; /* reference number upper part */ - mes[offset++] = ri & 0xff; /* reference number lower part */ - mes[offset++] = type; /* message type: Identity Request */ - mes[offset++] = ai << 1 | 0x01; /* action indicator: TEI */ - - return Q921SendU(trunk, Q921_SAPI_TEI, Q921_COMMAND(trunk), Q921_TEI_BCAST, 0, 0x00, mes, offset); -} - - -/** - * Q921TeiSendAssignRequest - * \brief Ask for new TEI (TE mode only) - * \param[in] trunk pointer to Q921 data struct - * \return > 0 on success, <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiSendAssignRequest(L2TRUNK trunk) -{ - struct Q921_Link *link = Q921_TRUNK_CONTEXT(trunk); - L2INT res; - - if (!Q921_IS_PTMP_TE(trunk)) /* only ptmp te mode*/ - return 0; - -#ifndef WIN32 - link->ri = (L2USHORT)(random() % 0xffff); -#else - link->ri = (L2USHORT)(rand() % 0xffff); //todo -#endif - - /* send TEI assign request */ - res = Q921TeiSend(trunk, Q921_TEI_ID_REQUEST, link->ri, Q921_TEI_BCAST); - - /* start T202 */ - Q921T202TimerStart(trunk); - - return res; -} - - -/** - * Q921TeiProcessAssignResponse - * \brief Process assign response (TE mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiProcAssignResponse(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - struct Q921_Link *link = Q921_TRUNK_CONTEXT(trunk); - L2UCHAR offset = Q921_UFRAME_DATA_OFFSET(trunk); - L2USHORT ri = 0; - - if (!Q921_IS_PTMP_TE(trunk)) /* PTMP TE only */ - return 0; - - ri = (mes[offset + 1] << 8) | mes[offset + 2]; - - if(ri != link->ri) { - /* hmmm ..., not our response i guess */ - return 0; - } - - switch(mes[offset + 3]) { - case Q921_TEI_ID_ASSIGNED: - /* Yay, use the new TEI and change state to assigned */ - link->tei = mes[offset + 4] >> 1; - - Q921Log(trunk, Q921_LOG_DEBUG, "Assigned TEI %d, setting state to TEI_ASSIGNED\n", link->tei); - - Q921ChangeState(trunk, Q921_STATE_TEI_ASSIGNED, link->tei); - break; - - case Q921_TEI_ID_DENIED: - /* oops, what to do now? */ - if ((mes[offset + 4] >> 1) == Q921_TEI_BCAST) { - /* No more free TEIs? this is bad */ - - //Q921TeiSendVerifyRequest(trunk, Q921_TEI_BCAST); /* TODO: does this work ?? */ - } else { - /* other reason, this is fatal, shutdown link */ - } - - Q921Log(trunk, Q921_LOG_DEBUG, "TEI assignment has been denied, reason: %s\n", - ((mes[offset +4] >> 1) == Q921_TEI_BCAST) ? "No free TEIs available" : "Unknown"); - - Q921ChangeState(trunk, Q921_STATE_TEI_UNASSIGNED, link->tei); - break; - - default: - return 0; - } - - /* stop T202 */ - Q921T202TimerStop(trunk); - - return 1; -} - - -/** - * Q921TeiSendVerifyRequest - * \brief Verify TEI (TE mode only) - * \param[in] trunk pointer to Q921 data struct - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiSendVerifyRequest(L2TRUNK trunk) -{ - struct Q921_Link *link = Q921_TRUNK_CONTEXT(trunk); - L2INT res; - - if (!Q921_IS_PTMP_TE(trunk)) /* only ptmp te mode*/ - return 0; - - /* Request running? */ - if (trunk->T202) - return 0; - - /* Send TEI verify request */ - res = Q921TeiSend(trunk, Q921_TEI_ID_VERIFY, link->ri, link->tei); - - /* start T202 */ - Q921T202TimerStart(trunk); - - return res; -} - - -/** - * Q921TeiProcCheckRequest - * \brief Process Check Request (TE mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiProcCheckRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - struct Q921_Link *link = Q921_TRUNK_CONTEXT(trunk); - L2UCHAR offset = Q921_UFRAME_DATA_OFFSET(trunk); - L2UCHAR tei = (mes[offset + 4] >> 1); /* action indicator => tei */ - L2INT res = 0; - - if (!Q921_IS_PTMP_TE(trunk)) /* ptmp te mode only */ - return 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "Received TEI Check request for TEI %d\n", tei); - - if (tei == Q921_TEI_BCAST || tei == link->tei) { - /* - * Broadcast TEI check or for our assigned TEI - */ - - /* send TEI check reponse */ - res = Q921TeiSend(trunk, Q921_TEI_ID_CHECKRESP, link->ri, link->tei); - - Q921T202TimerStop(trunk); - } - - return res; -} - - -/** - * Q921TeiProcRemoveRequest - * \brief Process remove Request (TE mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiProcRemoveRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - struct Q921_Link *link = Q921_TRUNK_CONTEXT(trunk); - L2UCHAR offset = Q921_UFRAME_DATA_OFFSET(trunk); - L2UCHAR tei = (mes[offset + 4] >> 1); /* action indicator => tei */ - L2INT res = 0; - - if (!Q921_IS_PTMP_TE(trunk)) /* ptmp te mode only */ - return 0; - - Q921Log(trunk, Q921_LOG_DEBUG, "Received TEI Remove request for TEI %d\n", tei); - - if (tei == Q921_TEI_BCAST || tei == link->tei) { - /* - * Broadcast TEI remove or for our assigned TEI - */ - - /* reset tei */ - link->tei = 0; - - /* change state (no action) */ - Q921ChangeState(trunk, Q921_STATE_TEI_UNASSIGNED, link->tei); - - /* TODO: hmm, request new one ? */ - res = Q921TeiSendAssignRequest(trunk); - } - return res; -} - - -/** - * Q921TeiProcAssignRequest - * \brief Process assign request from peer (NT mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiProcAssignRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR offset = Q921_UFRAME_DATA_OFFSET(trunk); - L2USHORT ri = 0; - L2UCHAR tei = 0; - - if (!Q921_IS_PTMP_NT(trunk)) /* PTMP NT only */ - return 0; - - ri = (mes[offset + 1] << 8) | mes[offset + 2]; - tei = mes[offset + 4] >> 1; - - if(tei == Q921_TEI_BCAST) { - int x; - - /* dynamically allocate TEI */ - for(x = Q921_TEI_DYN_MIN, tei = 0; x <= Q921_TEI_MAX; x++) { - if(!trunk->tei_map[x]) { - tei = x; - break; - } - } - } - else if(!(tei > 0 && tei < Q921_TEI_DYN_MIN)) { - /* reject TEIs that are not in the static area */ - Q921TeiSendDenyResponse(trunk, 0, ri); - - return 0; - } - - if(!tei) { - /* no free TEI found */ - Q921TeiSendDenyResponse(trunk, Q921_TEI_BCAST, ri); - } - else { - struct Q921_Link *link = Q921_LINK_CONTEXT(trunk, tei); - - /* mark used */ - trunk->tei_map[tei] = 1; - - /* assign tei */ - link->tei = tei; - - /* put context in TEI ASSIGNED state */ - Q921ChangeState(trunk, Q921_STATE_TEI_ASSIGNED, tei); - - /* send assign response */ - Q921TeiSendAssignedResponse(trunk, tei, ri); - - /* Start T201 */ - Q921T201TimerStart(trunk, tei); - } - return 0; -} - -/** - * Q921TeiSendCheckRequest - * \brief Send check request (NT mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] tei TEI to check - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiSendCheckRequest(L2TRUNK trunk, L2UCHAR tei) -{ - L2INT res = 0; - - if (!Q921_IS_PTMP_NT(trunk)) /* PTMP NT only */ - return 0; - - /* send TEI check request */ - res = Q921TeiSend(trunk, Q921_TEI_ID_CHECKREQ, 0, tei); - - /* (Re-)Start T201 timer */ - Q921T201TimerStart(trunk, tei); - - return res; -} - -/** - * Q921TeiProcCheckResponse - * \brief Process Check Response (NT mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiProcCheckResponse(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - struct Q921_Link *link; - L2UCHAR offset = Q921_UFRAME_DATA_OFFSET(trunk); - L2USHORT ri = 0; - L2UCHAR tei = 0; - - if (!Q921_IS_PTMP_NT(trunk)) /* PTMP NT mode only */ - return 0; - - ri = (mes[offset + 1] << 8) | mes[offset + 2]; - tei = mes[offset + 4] >> 1; - - /* restart T201 */ - Q921T201TimerStop(trunk, tei); - - /* reset counter */ - link = Q921_LINK_CONTEXT(trunk, tei); - link->N202 = 0; - - if(!(tei > 0 && tei < Q921_TEI_MAX) || !trunk->tei_map[tei]) { - /* TODO: Should we send a DISC first? */ - - /* TEI not assigned? Invalid TEI? */ - Q921TeiSendRemoveRequest(trunk, tei); - - /* change state */ - Q921ChangeState(trunk, Q921_STATE_STOPPED, tei); - - /* clear */ - memset(link, 0, sizeof(struct Q921_Link)); - } else { - /* Start T201 */ - Q921T201TimerStart(trunk, tei); - } - - return 0; -} - - -/** - * Q921TeiProcVerifyRequest - * \brief Process Verify Request (NT mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] mes pointer to message buffer - * \param[in] size size of message - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiProcVerifyRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size) -{ - L2UCHAR resp[25]; - L2UCHAR offset = Q921_UFRAME_DATA_OFFSET(trunk); - L2UCHAR tei = 0; - - if (!Q921_IS_PTMP_NT(trunk)) /* PTMP NT mode only */ - return 0; - - tei = mes[offset + 4] >> 1; - - /* todo: handle response... verify assigned TEI */ - resp[offset + 0] = 0; - - return 0; -} - -/** - * Q921TeiSendDenyResponse - * \brief Send Deny Response (NT mode only) - * \param[in] trunk pointer to Q921 data struct - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiSendDenyResponse(L2TRUNK trunk, L2UCHAR tei, L2USHORT ri) -{ - if (!Q921_IS_PTMP_NT(trunk)) /* PTMP NT only */ - return 0; - - return Q921TeiSend(trunk, Q921_TEI_ID_DENIED, ri, tei); -} - - -/** - * Q921TeiSendAssignedResponse - * \brief Send Assigned Response (NT mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] tei TEI to assign - * \param[in] ri RI of request - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiSendAssignedResponse(L2TRUNK trunk, L2UCHAR tei, L2USHORT ri) -{ - if (!Q921_IS_PTMP_NT(trunk)) /* PTMP NT only */ - return 0; - - return Q921TeiSend(trunk, Q921_TEI_ID_ASSIGNED, ri, tei); -} - -/** - * Q921TeiSendRemoveRequest - * \brief Send Remove Request (NT mode only) - * \param[in] trunk pointer to Q921 data struct - * \param[in] tei TEI to remove - * \return > 0 on success; <= 0 on error - * - * \author Stefan Knoblich - */ -static int Q921TeiSendRemoveRequest(L2TRUNK trunk, L2UCHAR tei) -{ - if (!Q921_IS_PTMP_NT(trunk)) /* PTMP NT only */ - return 0; - - return Q921TeiSend(trunk, Q921_TEI_ID_REMOVE, 0, tei); -} diff --git a/libs/freetdm/src/isdn/Q931.c b/libs/freetdm/src/isdn/Q931.c deleted file mode 100644 index b245c144d8..0000000000 --- a/libs/freetdm/src/isdn/Q931.c +++ /dev/null @@ -1,888 +0,0 @@ -/***************************************************************************** - - FileName: Q931.c - - Contents: Implementation of Q.931 stack main interface functions. - See q931.h for description. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q921.h" -#include "Q931.h" -#include "national.h" -#include "DMS.h" -#include "5ESS.h" - - -/***************************************************************************** - - Dialect function pointers tables. - - The following function pointer arrays define pack/unpack functions and - processing furnctions for the different Q.931 based dialects. - - The arrays are initialized with pointers to dummy functions and later - overrided with pointers to actual functions as new dialects are added. - - The initial Q.931 will as an example define 2 dialects as it treats User - and Network mode as separate ISDN dialects. - - The API messages Q931AddProc, Q931AddMes, Q931AddIE are used to initialize - these table entries during system inititialization of a stack. - -*****************************************************************************/ -q931proc_func_t *Q931Proc[Q931MAXDLCT][Q931MAXMES]; - -q931umes_func_t *Q931Umes[Q931MAXDLCT][Q931MAXMES]; -q931pmes_func_t *Q931Pmes[Q931MAXDLCT][Q931MAXMES]; - -q931uie_func_t *Q931Uie[Q931MAXDLCT][Q931MAXIE]; -q931pie_func_t *Q931Pie[Q931MAXDLCT][Q931MAXIE]; - -q931timeout_func_t *Q931Timeout[Q931MAXDLCT][Q931MAXTIMER]; -q931timer_t Q931Timer[Q931MAXDLCT][Q931MAXTIMER]; - -void (*Q931CreateDialectCB[Q931MAXDLCT])(L3UCHAR iDialect) = { NULL, NULL }; - -Q931State Q931st[Q931MAXSTATE]; - -/***************************************************************************** - - Core system tables and variables. - -*****************************************************************************/ - -L3INT Q931L4HeaderSpace = {0}; /* header space to be ignoder/inserted */ - /* at head of each message. */ - -L3INT Q931L2HeaderSpace = {4}; /* Q921 header space, sapi, tei etc */ - -/***************************************************************************** - - Main interface callback functions. - -*****************************************************************************/ - -Q931ErrorCB_t Q931ErrorProc; /* callback for error messages. */ -L3ULONG (*Q931GetTimeProc) (void) = NULL; /* callback for func reading time in ms */ - -/***************************************************************************** - - Function: Q931SetL4HeaderSpace - - Description: Set the # of bytes to be inserted/ignored at the head of - each message. Q931 will issue a message with space for header - and the user will use this to fill in whatever header info - is required to support the architecture used. - -*****************************************************************************/ -void Q931SetL4HeaderSpace(L3INT space) -{ - Q931L4HeaderSpace = space; -} - -/***************************************************************************** - - Function: Q931SetL2HeaderSpace - - Description: Set the # of bytes to be inserted/ignored at the head of - each message. Q931 will issue a message with space for header - and the user will use this to fill in whatever header info - is required to support the architecture used. - -*****************************************************************************/ -void Q931SetL2HeaderSpace(L3INT space) -{ - Q931L2HeaderSpace = space; -} - -/***************************************************************************** - - Function: Q931ProcDummy - - Description: Dummy function for message processing. - -*****************************************************************************/ -L3INT Q931ProcDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b,L3INT c) -{ - return Q931E_INTERNAL; -} - -/***************************************************************************** - - Function: Q931UmesDummy - - Description: Dummy function for message processing - -*****************************************************************************/ -L3INT Q931UmesDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size) -{ - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: Q931UieDummy - - Description: Dummy function for message processing - -*****************************************************************************/ -L3INT Q931UieDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - return Q931E_UNKNOWN_IE; -} - -/***************************************************************************** - - Function: Q931PmesDummy - - Description: Dummy function for message processing - -*****************************************************************************/ -L3INT Q931PmesDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - return Q931E_UNKNOWN_MESSAGE; -} - -/***************************************************************************** - - Function: Q931PieDummy - - Description: Dummy function for message processing - -*****************************************************************************/ -L3INT Q931PieDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - return Q931E_UNKNOWN_IE; -} - -/***************************************************************************** - - Function: Q931TxDummy - - Description: Dummy function for message processing - -*****************************************************************************/ -L3INT Q931TxDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT n) -{ - return Q931E_MISSING_CB; -} - -/***************************************************************************** - - Function: Q931ErrorDummy - - Description: Dummy function for error processing - -*****************************************************************************/ -L3INT Q931ErrorDummy(void *priv, L3INT a, L3INT b, L3INT c) -{ - return 0; -} - -/***************************************************************************** - - Function: Q931Initialize - - Description: This function Initialize the stack. - - Will set up the trunk array, channel - arrays and initialize Q931 function arrays before it finally - set up EuroISDN processing with User as dialect 0 and - Network as dialect 1. - - Note: Initialization of other stacks should be inserted after - the initialization of EuroISDN. - -*****************************************************************************/ -void Q931Initialize() -{ - L3INT x,y; - - /* Secure the callbacks to default procs */ - Q931ErrorProc = Q931ErrorDummy; - - /* The user will only add the message handlers and IE handlers he need, - * so we need to initialize every single entry to a default function - * that will throw an appropriate error if they are ever called. - */ - for (x = 0; x < Q931MAXDLCT; x++) { - for (y = 0; y < Q931MAXMES; y++) { - Q931Proc[x][y] = Q931ProcDummy; - Q931Umes[x][y] = Q931UmesDummy; - Q931Pmes[x][y] = Q931PmesDummy; - } - for (y = 0; y < Q931MAXIE; y++) { - Q931Pie[x][y] = Q931PieDummy; - Q931Uie[x][y] = Q931UieDummy; - } - for (y = 0; y < Q931MAXTIMER; y++) { - Q931Timeout[x][y] = Q931TimeoutDummy; - Q931Timer[x][y] = 0; - } - } - - if (Q931CreateDialectCB[Q931_Dialect_Q931 + Q931_TE] == NULL) - Q931AddDialect(Q931_Dialect_Q931 + Q931_TE, Q931CreateTE); - - if (Q931CreateDialectCB[Q931_Dialect_Q931 + Q931_NT] == NULL) - Q931AddDialect(Q931_Dialect_Q931 + Q931_NT, Q931CreateNT); - - if (Q931CreateDialectCB[Q931_Dialect_National + Q931_TE] == NULL) - Q931AddDialect(Q931_Dialect_National + Q931_TE, nationalCreateTE); - - if (Q931CreateDialectCB[Q931_Dialect_National + Q931_NT] == NULL) - Q931AddDialect(Q931_Dialect_National + Q931_NT, nationalCreateNT); - - if (Q931CreateDialectCB[Q931_Dialect_DMS + Q931_TE] == NULL) - Q931AddDialect(Q931_Dialect_DMS + Q931_TE, DMSCreateTE); - - if (Q931CreateDialectCB[Q931_Dialect_DMS + Q931_NT] == NULL) - Q931AddDialect(Q931_Dialect_DMS + Q931_NT, DMSCreateNT); - - if (Q931CreateDialectCB[Q931_Dialect_5ESS + Q931_TE] == NULL) - Q931AddDialect(Q931_Dialect_5ESS + Q931_TE, ATT5ESSCreateTE); - - if (Q931CreateDialectCB[Q931_Dialect_5ESS + Q931_NT] == NULL) - Q931AddDialect(Q931_Dialect_5ESS + Q931_NT, ATT5ESSCreateNT); - - /* The last step we do is to call the callbacks to create the dialects */ - for (x = 0; x < Q931MAXDLCT; x++) { - if (Q931CreateDialectCB[x] != NULL) { - Q931CreateDialectCB[x]((L3UCHAR)x); - } - } -} - -/** - * Q931TimerTick - * \brief Periodically called to update and check for expired timers - * \param pTrunk Q.931 trunk - */ -void Q931TimerTick(Q931_TrunkInfo_t *pTrunk) -{ - struct Q931_Call *call = NULL; - L3ULONG now = 0; - L3INT x; - - /* TODO: Loop through all active calls, check timers and call timout procs - * if timers are expired. - * Implement a function array so each dialect can deal with their own - * timeouts. - */ - now = Q931GetTime(); - - for (x = 0; x < Q931MAXCALLPERTRUNK; x++) { - call = &pTrunk->call[x]; - - if (!call->InUse || !call->Timer || !call->TimerID) - continue; - - if (call->Timer <= now) { - /* Stop Timer */ - Q931StopTimer(pTrunk, x, call->TimerID); - - /* Invoke dialect timeout callback */ - Q931Timeout[pTrunk->Dialect][call->TimerID](pTrunk, x); - } - } -} - -/***************************************************************************** - - Function: Q931Rx23 - - Description: Receive message from layer 2 (LAPD). Receiving a message - is always done in 2 steps. First the message must be - interpreted and translated to a static struct. Secondly - the message is processed and responded to. - - The Q.931 message contains a static header that is - interpreted in this function. The rest is interpreted - in a sub function according to mestype. - - Parameters: pTrunk [IN] Ptr to trunk info. - buf [IN] Ptr to buffer containing message. - Size [IN] Size of message. - - Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning - see q931errors.h for details. - -*****************************************************************************/ -L3INT Q931Rx23(Q931_TrunkInfo_t *pTrunk, L3INT ind, L3UCHAR tei, L3UCHAR * buf, L3INT Size) -{ - L3UCHAR *Mes = NULL; - L3INT RetCode = Q931E_NO_ERROR; - Q931mes_Generic *m = (Q931mes_Generic *) pTrunk->L3Buf; - L3INT ISize; - L3INT IOff = 0; - L3INT L2HSize = Q931L2HeaderSpace; - - switch (ind) { - case Q921_DL_UNIT_DATA: /* DL-UNITDATA indication (UI frame, 3 byte header) */ - L2HSize = 3; - - case Q921_DL_DATA: /* DL-DATA indication (I frame, 4 byte header) */ - /* Reset our decode buffer */ - memset(pTrunk->L3Buf, 0, sizeof(pTrunk->L3Buf)); - - /* L2 Header Offset */ - Mes = &buf[L2HSize]; - - /* Protocol Discriminator */ - m->ProtDisc = Mes[IOff++]; - - /* CRV */ - m->CRVFlag = (Mes[IOff + 1] >> 7) & 0x01; - m->CRV = Q931Uie_CRV(pTrunk, Mes, m->buf, &IOff, &ISize); - - /* Message Type */ - m->MesType = Mes[IOff++]; - - /* Store tei */ - m->Tei = tei; - - /* d'oh a little ugly but this saves us from: - * a) doing Q.921 work in the lower levels (extracting the TEI ourselves) - * b) adding a tei parameter to _all_ Proc functions - */ - if (tei) { - L3INT callIndex = 0; - - /* Find the call using CRV */ - RetCode = Q931FindCRV(pTrunk, m->CRV, &callIndex); - if (RetCode == Q931E_NO_ERROR && !pTrunk->call[callIndex].Tei) { - pTrunk->call[callIndex].Tei = tei; - } - } - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Received message from Q.921 (ind %d, tei %d, size %d)\nMesType: %d, CRVFlag %d (%s), CRV %d (Dialect: %d)\n", ind, m->Tei, Size, - m->MesType, m->CRVFlag, m->CRVFlag ? "Terminator" : "Originator", m->CRV, pTrunk->Dialect); - - RetCode = Q931Umes[pTrunk->Dialect][m->MesType](pTrunk, Mes, (Q931mes_Generic *)pTrunk->L3Buf, IOff, Size - L2HSize); - if (RetCode >= Q931E_NO_ERROR) { - RetCode = Q931Proc[pTrunk->Dialect][m->MesType](pTrunk, pTrunk->L3Buf, 2); - } - break; - - default: - break; - } - - return RetCode; -} - -/***************************************************************************** - - Function: Q931Tx34 - - Description: Called from the stack to send a message to layer 4. - - Parameters: Mes[IN] Ptr to message buffer. - Size[IN] Message size in bytes. - - Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning - see q931errors.h for details. - -*****************************************************************************/ -L3INT Q931Tx34(Q931_TrunkInfo_t *pTrunk, L3UCHAR * Mes, L3INT Size) -{ - Q931Log(pTrunk, Q931_LOG_DEBUG, "Sending message to Layer4 (size: %d)\n", Size); - - if (pTrunk->Q931Tx34CBProc) { - return pTrunk->Q931Tx34CBProc(pTrunk->PrivateData34, Mes, Size); - } - return Q931E_MISSING_CB; -} - -/***************************************************************************** - - Function: Q931Rx43 - - Description: Receive message from Layer 4 (application). - - Parameters: pTrunk[IN] Trunk #. - buf[IN] Message Pointer. - Size[IN] Message size in bytes. - - Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning - see q931errors.h for details. - -*****************************************************************************/ -L3INT Q931Rx43(Q931_TrunkInfo_t *pTrunk,L3UCHAR * buf, L3INT Size) -{ - Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; - L3INT RetCode = Q931E_NO_ERROR; - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Receiving message from Layer4 (size: %d, type: %d)\n", Size, ptr->MesType); - - RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4); - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Q931Rx43 return code: %d\n", RetCode); - - return RetCode; -} - -/***************************************************************************** - - Function: Q931Tx32 - - Description: Called from the stack to send a message to L2. The input is - always a non-packed message so it will first make a proper - call to create a packed message before it transmits that - message to layer 2. - - Parameters: pTrunk[IN] Trunk # - buf[IN] Ptr to message buffer. - Size[IN] Message size in bytes. - - Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning - see q931errors.h for details. - -*****************************************************************************/ -L3INT Q931Tx32Data(Q931_TrunkInfo_t *pTrunk, L3UCHAR bcast, L3UCHAR * Mes, L3INT Size) -{ - Q931mes_Generic *ptr = (Q931mes_Generic*)Mes; - L3INT RetCode = Q931E_NO_ERROR; - L3INT iDialect = pTrunk->Dialect; - L3INT Offset = bcast ? (Q931L2HeaderSpace - 1) : Q931L2HeaderSpace; - L3INT OSize; - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Sending message to Q.921 (size: %d)\n", Size); - - memset(pTrunk->L2Buf, 0, sizeof(pTrunk->L2Buf)); - - /* Call pack function through table. */ - RetCode = Q931Pmes[iDialect][ptr->MesType](pTrunk, (Q931mes_Generic *)Mes, Size, &pTrunk->L2Buf[Offset], &OSize); - if (RetCode >= Q931E_NO_ERROR) { - L3INT callIndex; - L3UCHAR tei = 0; - - if (ptr->CRV) { - /* Find the call using CRV */ - RetCode = Q931FindCRV(pTrunk, ptr->CRV, &callIndex); - if (RetCode != Q931E_NO_ERROR) - return RetCode; - - tei = pTrunk->call[callIndex].Tei; - } - - if (pTrunk->Q931Tx32CBProc) { - RetCode = pTrunk->Q931Tx32CBProc(pTrunk->PrivateData32, bcast ? Q921_DL_UNIT_DATA : Q921_DL_DATA, tei, pTrunk->L2Buf, OSize + Offset); - } else { - RetCode = Q931E_MISSING_CB; - } - } - - return RetCode; -} - - -/***************************************************************************** - - Function: Q931SetError - - Description: Called from the stack to indicate an error. - - Parameters: ErrID ID of ie or message causing error. - ErrPar1 Error parameter 1 - ErrPar2 Error parameter 2. - - -*****************************************************************************/ -void Q931SetError(Q931_TrunkInfo_t *pTrunk,L3INT ErrID, L3INT ErrPar1, L3INT ErrPar2) -{ - if (pTrunk->Q931ErrorCBProc) { - pTrunk->Q931ErrorCBProc(pTrunk->PrivateData34, ErrID, ErrPar1, ErrPar2); - } else { - Q931ErrorProc(pTrunk->PrivateData34, ErrID, ErrPar1, ErrPar2); - } -} - -void Q931SetDefaultErrorCB(Q931ErrorCB_t Q931ErrorPar) -{ - Q931ErrorProc = Q931ErrorPar; -} - -/***************************************************************************** - - Function: Q931CreateCRV - - Description: Create a CRV entry and return it's index. The function will - locate a free entry in the call tables allocate it and - allocate a unique CRV value attached to it. - - Parameters: pTrunk [IN] Trunk number - callindex [OUT] return call table index. - - Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning - see q931errors.h for details. -****************************************************************************/ -L3INT Q931CreateCRV(Q931_TrunkInfo_t *pTrunk, L3INT * callIndex) -{ - L3INT CRV = Q931GetUniqueCRV(pTrunk); - - return Q931AllocateCRV(pTrunk, CRV, callIndex); -} - - -L3INT Q931ReleaseCRV(Q931_TrunkInfo_t *pTrunk, L3INT CRV) -{ - int callIndex; - - if ((Q931FindCRV(pTrunk, CRV, &callIndex)) == Q931E_NO_ERROR) { - pTrunk->call[callIndex].InUse = 0; - return Q931E_NO_ERROR; - } - - return Q931E_INVALID_CRV; -} - -/***************************************************************************** - - Function: Q931AllocateCRV - - Description: Allocate a call table entry and assigns the given CRV value - to it. - - Parameters: pTrunk [IN] Trunk number - iCRV [IN] Call Reference Value. - callindex [OUT] return call table index. - - Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning - see q931errors.h for details. - -*****************************************************************************/ -L3INT Q931AllocateCRV(Q931_TrunkInfo_t *pTrunk, L3INT iCRV, L3INT * callIndex) -{ - L3INT x; - for (x = 0; x < Q931MAXCALLPERTRUNK; x++) { - if (!pTrunk->call[x].InUse) { - pTrunk->call[x].CRV = iCRV; - pTrunk->call[x].BChan = 255; - pTrunk->call[x].State = 0; /* null state - idle */ - pTrunk->call[x].TimerID = 0; /* no timer running */ - pTrunk->call[x].Timer = 0; - pTrunk->call[x].InUse = 1; /* mark as used */ - *callIndex = x; - return Q931E_NO_ERROR; - } - } - return Q931E_TOMANYCALLS; -} - -/***************************************************************************** - - Function: Q931GetCallState - - Description: Look up CRV and return current call state. A non existing - CRV is the same as state zero (0). - - Parameters: pTrunk [IN] Trunk number. - iCRV [IN] CRV - - Return Value: Call State. - -*****************************************************************************/ -L3INT Q931GetCallState(Q931_TrunkInfo_t *pTrunk, L3INT iCRV) -{ - L3INT x; - for (x = 0; x < Q931MAXCALLPERTRUNK; x++) { - if (pTrunk->call[x].InUse) { - if (pTrunk->call[x].CRV == iCRV) { - return pTrunk->call[x].State; - } - } - } - return 0; /* assume state zero for non existing CRV's */ -} - -/** - * Q931StartTimer - * \brief Start a timer - * \param pTrunk Q.931 trunk - * \param callindex Index of the call - * \param iTimerID ID of timer - * \return always 0 - */ -L3INT Q931StartTimer(Q931_TrunkInfo_t *pTrunk, L3INT callIndex, L3USHORT iTimerID) -{ -#if 0 - L3ULONG duration = Q931Timer[pTrunk->Dialect][iTimerID]; - - if (duration) { - pTrunk->call[callIndex].Timer = Q931GetTime() + duration; - pTrunk->call[callIndex].TimerID = iTimerID; - } -#endif - return 0; -} - -/** - * Q931StopTimer - * \brief Stop a timer - * \param pTrunk Q.931 trunk - * \param callindex Index of the call - * \param iTimerID ID of timer - * \return always 0 - */ -L3INT Q931StopTimer(Q931_TrunkInfo_t *pTrunk, L3INT callindex, L3USHORT iTimerID) -{ - if (pTrunk->call[callindex].TimerID == iTimerID) - pTrunk->call[callindex].TimerID = 0; - - return 0; -} - -L3INT Q931SetState(Q931_TrunkInfo_t *pTrunk, L3INT callIndex, L3INT iState) -{ - pTrunk->call[callIndex].State = iState; - - return 0; -} - -L3ULONG Q931GetTime() -{ - L3ULONG tNow = 0; - static L3ULONG tLast = 0; - - if (Q931GetTimeProc != NULL) { - tNow = Q931GetTimeProc(); - if (tNow < tLast) { /* wrapped */ - /* TODO */ - } - tLast = tNow; - } - return tNow; -} - -void Q931SetGetTimeCB(L3ULONG (*callback)(void)) -{ - Q931GetTimeProc = callback; -} - -L3INT Q931FindCRV(Q931_TrunkInfo_t *pTrunk, L3INT crv, L3INT *callindex) -{ - L3INT x; - for (x = 0; x < Q931MAXCALLPERTRUNK; x++) { - if (pTrunk->call[x].InUse) { - if (pTrunk->call[x].CRV == crv) { - *callindex = x; - return Q931E_NO_ERROR; - } - } - } - return Q931E_INVALID_CRV; -} - - -void Q931AddDialect(L3UCHAR i, void (*callback)(L3UCHAR iD )) -{ - if (i < Q931MAXDLCT) { - Q931CreateDialectCB[i] = callback; - } -} - -/***************************************************************************** - Function: Q931AddStateEntry - - Description: Find an empty entry in the dialects state table and add this - entry. -*****************************************************************************/ -void Q931AddStateEntry(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir) -{ - int x; - for (x = 0; x < Q931MAXSTATE; x++) { - if (Q931st[x].Message == 0) { - Q931st[x].State = iState; - Q931st[x].Message = iMes; - Q931st[x].Direction = cDir; - /* TODO Sort table and use bsearch */ - return; - } - } -} - -/***************************************************************************** - Function: Q931IsEventLegal - - Description: Check state table for matching criteria to indicate if this - Message is legal in this state or not. - - Note: Someone write a bsearch or invent something smart here - please - sequential is ok for now. -*****************************************************************************/ -L3BOOL Q931IsEventLegal(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir) -{ - int x; - /* TODO Sort table and use bsearch */ - for (x = 0; x < Q931MAXSTATE; x++) { - if (Q931st[x].State == iState && Q931st[x].Message == iMes && - Q931st[x].Direction == cDir) { - return L3TRUE; - } - } - return L3FALSE; -} - -/***************************************************************************** - Function: q931_error_to_name() - - Description: Check state table for matching criteria to indicate if this - Message is legal in this state or not. - - Note: Someone write a bsearch or invent something smart here - please - sequential is ok for now. -*****************************************************************************/ -static const char *q931_error_names[] = { - "Q931E_NO_ERROR", /* 0 */ - - "Q931E_UNKNOWN_MESSAGE", /* -3001 */ - "Q931E_ILLEGAL_IE", /* -3002 */ - "Q931E_UNKNOWN_IE", /* -3003 */ - "Q931E_BEARERCAP", /* -3004 */ - "Q931E_HLCOMP", /* -3005 */ - "Q931E_LLCOMP", /* -3006 */ - "Q931E_INTERNAL", /* -3007 */ - "Q931E_MISSING_CB", /* -3008 */ - "Q931E_UNEXPECTED_MESSAGE", /* -3009 */ - "Q931E_ILLEGAL_MESSAGE", /* -3010 */ - "Q931E_TOMANYCALLS", /* -3011 */ - "Q931E_INVALID_CRV", /* -3012 */ - "Q931E_CALLID", /* -3013 */ - "Q931E_CALLSTATE", /* -3014 */ - "Q931E_CALLEDSUB", /* -3015 */ - "Q931E_CALLEDNUM", /* -3016 */ - "Q931E_CALLINGNUM", /* -3017 */ - "Q931E_CALLINGSUB", /* -3018 */ - "Q931E_CAUSE", /* -3019 */ - "Q931E_CHANID", /* -3020 */ - "Q931E_DATETIME", /* -3021 */ - "Q931E_DISPLAY", /* -3022 */ - "Q931E_KEYPADFAC", /* -3023 */ - "Q931E_NETFAC", /* -3024 */ - "Q931E_NOTIFIND", /* -3025 */ - "Q931E_PROGIND", /* -3026 */ - "Q931E_RESTARTIND", /* -3027 */ - "Q931E_SEGMENT", /* -3028 */ - "Q931E_SIGNAL", /* -3029 */ - "Q931E_GENERIC_DIGITS" /* -3030 */ - -}; - -#define Q931_MAX_ERROR 30 - -const char *q931_error_to_name(q931_error_t error) -{ - int index = 0; - if ((int)error < 0) { - index = (((int)error * -1) -3000); - } - if (index < 0 || index > Q931_MAX_ERROR) { - return ""; - } - return q931_error_names[index]; -} -/* - * Logging - */ -#include - -L3INT Q931Log(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level, const char *fmt, ...) -{ - char buf[Q931_LOGBUFSIZE]; - L3INT len; - va_list ap; - - if (!trunk->Q931LogCBProc) - return 0; - - if (trunk->loglevel < level) - return 0; - - va_start(ap, fmt); - - len = vsnprintf(buf, sizeof(buf)-1, fmt, ap); - if (len <= 0) { - /* TODO: error handling */ - return -1; - } - if (len >= sizeof(buf)) - len = sizeof(buf) - 1; - - buf[len] = '\0'; - - va_end(ap); - - return trunk->Q931LogCBProc(trunk->PrivateDataLog, level, buf, len); -} - -/** - * Q921SetLogCB - * \brief Set Logging callback function and private data - */ -void Q931SetLogCB(Q931_TrunkInfo_t *trunk, Q931LogCB_t func, void *priv) -{ - trunk->Q931LogCBProc = func; - trunk->PrivateDataLog = priv; -} - -/** - * Q921SetLogLevel - * \brief Set Loglevel - */ -void Q931SetLogLevel(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level) -{ - if(!trunk) - return; - - if (level < Q931_LOG_NONE) { - level = Q931_LOG_NONE; - } else if (level > Q931_LOG_DEBUG) { - level = Q931_LOG_DEBUG; - } - - trunk->loglevel = level; -} - -/** - * Q931TimeoutDummy - * \brief Dummy handler for timeouts - * \param pTrunk Q.931 trunk - * \param callIndex Index of call - */ -L3INT Q931TimeoutDummy(Q931_TrunkInfo_t *pTrunk, L3INT callIndex) -{ - Q931Log(pTrunk, Q931_LOG_DEBUG, "Timer %d of call %d (CRV: %d) timed out\n", pTrunk->call[callIndex].TimerID, callIndex, pTrunk->call[callIndex].CRV); - - return 0; -} diff --git a/libs/freetdm/src/isdn/Q931StateNT.c b/libs/freetdm/src/isdn/Q931StateNT.c deleted file mode 100644 index 8d05fb6d03..0000000000 --- a/libs/freetdm/src/isdn/Q931StateNT.c +++ /dev/null @@ -1,1218 +0,0 @@ -/***************************************************************************** - - FileName: q931StateNT.c - - Contents: Q.931 State Engine for NT (Network Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q931.h" - -extern L3INT Q931L4HeaderSpace; - -/***************************************************************************** - Function: Q931CreateNT - - Description: Will create the Q931 NT as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void Q931CreateNT(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingNT, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingNT, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, Q931ProcConnectNT, Q931Umes_Connect, Q931Pmes_Connect); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, Q931ProcConnectAckNT, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressNT, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupNT, Q931Umes_Setup, Q931Pmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckNT, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeNT, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckNT, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectNT, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendNT, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckNT, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectNT, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationNT, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectNT, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseNT, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteNT, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartNT, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckNT, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlNT, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationNT, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyNT, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusNT, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryNT, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentNT, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityNT, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldNT, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckNT, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectNT, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterNT, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveNT, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckNT, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectNT, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - - Q931SetIEProc(Q931ie_CONNECTED_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_FACILITY, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_REDIRECTING_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - - /* The following define a state machine. The point is that the Message - * procs can when search this to find out if the message/state - * combination is legale. If not, the proc for unexpected message apply. - */ - - /* TODO define state table here */ - - /* Timer default values */ - Q931SetTimerDefault(i, Q931_TIMER_T301, 180000); /* T301: 180s */ - Q931SetTimerDefault(i, Q931_TIMER_T302, 15000); /* T302: 15s */ - Q931SetTimerDefault(i, Q931_TIMER_T303, 4000); /* T303: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T304, 20000); /* T304: 20s */ - Q931SetTimerDefault(i, Q931_TIMER_T305, 30000); /* T305: 30s */ - Q931SetTimerDefault(i, Q931_TIMER_T306, 30000); /* T306: 30s */ - Q931SetTimerDefault(i, Q931_TIMER_T307, 180000); /* T307: 180s */ - Q931SetTimerDefault(i, Q931_TIMER_T308, 4000); /* T308: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T309, 60000); /* T309: 60s */ - Q931SetTimerDefault(i, Q931_TIMER_T310, 10000); /* T310: 10s */ - Q931SetTimerDefault(i, Q931_TIMER_T312, 12000); /* T312: 12s */ - Q931SetTimerDefault(i, Q931_TIMER_T314, 4000); /* T314: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T316, 120000); /* T316: 120s */ - Q931SetTimerDefault(i, Q931_TIMER_T317, 90000); /* T317: 90s */ - Q931SetTimerDefault(i, Q931_TIMER_T320, 30000); /* T320: 30s */ - Q931SetTimerDefault(i, Q931_TIMER_T321, 30000); /* T321: 30s */ - Q931SetTimerDefault(i, Q931_TIMER_T322, 4000); /* T322: 4s */ -} - -/***************************************************************************** - - Function: Q931ProcAlertingNT - -*****************************************************************************/ -L3INT Q931ProcAlertingNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* Reset 4 sec timer. */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcCallProceedingNT - -*****************************************************************************/ -L3INT Q931ProcCallProceedingNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcConnectNT - -*****************************************************************************/ -L3INT Q931ProcConnectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcConnectAckNT - -*****************************************************************************/ -L3INT Q931ProcConnectAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcProgressNT - -*****************************************************************************/ -L3INT Q931ProcProgressNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSetupNT - - Description: Process a SETUP message. - - *****************************************************************************/ -L3INT Q931ProcSetupNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)&buf[Q931L4HeaderSpace]; - L3INT rc = 0; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Reject SETUP on existing calls */ - if (Q931GetCallState(pTrunk, pMes->CRV) != Q931_U0) { - Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); - return Q931E_UNEXPECTED_MESSAGE; - } - - /* outgoing call */ - if (iFrom == 4) { - ret = Q931CreateCRV(pTrunk, &callIndex); - if (ret) - return ret; - - pMes->CRV = pTrunk->call[callIndex].CRV; - - /* - * Outgoing SETUP message will be broadcasted in PTMP mode - */ - ret = Q931Tx32Data(pTrunk, Q931_IS_PTP(pTrunk) ? 0 : 1, buf, pMes->Size); - if (ret) - return ret; - - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - Q931SetState(pTrunk, callIndex, Q931_U1); - } - /* incoming call */ - else { - /* Locate free CRV entry and store info */ - ret = Q931AllocateCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) { - /* Not possible to allocate CRV entry, so must reject call */ - Q931Disconnect(pTrunk, iFrom, pMes->CRV, 42); - return ret; - } - - /* store TEI in call */ - pTrunk->call[callIndex].Tei = pMes->Tei; - - /* Send setup indication to user */ - ret = Q931Tx34(pTrunk, (L3UCHAR*)pMes, pMes->Size); - if (ret != Q931E_NO_ERROR) { - return ret; - } else { - /* Must be full queue, meaning we can't process the call */ - /* so we must disconnect */ - Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); - return ret; - } -#if 0 - /* TODO: Unreachable code??? */ - /* Set state U6 */ - Q931SetState(pTrunk, callIndex, Q931_U6); - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); -#endif - } - - return rc; -} - -/***************************************************************************** - - Function: Q931ProcSetupAckNT - - Description: Used to acknowedge a SETUP. Usually the first initial - response recevide back used to buy some time. - - Note that ChanID (B Channel Assignment) might come here from - NT side. - -*****************************************************************************/ -L3INT Q931ProcSetupAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcResumeNT - -*****************************************************************************/ -L3INT Q931ProcResumeNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcResumeAckNT - -*****************************************************************************/ -L3INT Q931ProcResumeAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcResumeRejectNT - -*****************************************************************************/ -L3INT Q931ProcResumeRejectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSuspendNT - -*****************************************************************************/ -L3INT Q931ProcSuspendNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSuspendAckNT - -*****************************************************************************/ -L3INT Q931ProcSuspendAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSuspendRejectNT - -*****************************************************************************/ -L3INT Q931ProcSuspendRejectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcInformationNT - -*****************************************************************************/ -L3INT Q931ProcUserInformationNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcDisconnectNT - -*****************************************************************************/ -L3INT Q931ProcDisconnectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcReleaseNT - -*****************************************************************************/ -L3INT Q931ProcReleaseNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcReleaseCompleteNT - -*****************************************************************************/ -L3INT Q931ProcReleaseCompleteNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRestartNT - -*****************************************************************************/ -L3INT Q931ProcRestartNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRestartAckNT - -*****************************************************************************/ -L3INT Q931ProcRestartAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcCongestionControlNT - -*****************************************************************************/ -L3INT Q931ProcCongestionControlNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcInformationNT - -*****************************************************************************/ -L3INT Q931ProcInformationNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcNotifyNT - -*****************************************************************************/ -L3INT Q931ProcNotifyNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcStatusNT - -*****************************************************************************/ -L3INT Q931ProcStatusNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcStatusEnquiryNT - -*****************************************************************************/ -L3INT Q931ProcStatusEnquiryNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSegmentNT - -*****************************************************************************/ -L3INT Q931ProcSegmentNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/****************************************************************************/ -/******************* Q.932 - Supplementary Services *************************/ -/****************************************************************************/ - -/***************************************************************************** - - Function: Q932ProcFacilityNT - -*****************************************************************************/ -L3INT Q932ProcFacilityNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcHoldNT - -*****************************************************************************/ -L3INT Q932ProcHoldNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcHoldAckNT - -*****************************************************************************/ -L3INT Q932ProcHoldAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcHoldRejectNT - -*****************************************************************************/ -L3INT Q932ProcHoldRejectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcRegisterTE - -*****************************************************************************/ -L3INT Q932ProcRegisterNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcRetrieveNT - -*****************************************************************************/ -L3INT Q932ProcRetrieveNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRetrieveAckNT - -*****************************************************************************/ -L3INT Q932ProcRetrieveAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRetrieveRejectNT - -*****************************************************************************/ -L3INT Q932ProcRetrieveRejectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here*/ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} diff --git a/libs/freetdm/src/isdn/Q931StateTE.c b/libs/freetdm/src/isdn/Q931StateTE.c deleted file mode 100644 index 562dd0b458..0000000000 --- a/libs/freetdm/src/isdn/Q931StateTE.c +++ /dev/null @@ -1,1310 +0,0 @@ -/***************************************************************************** - - FileName: q931StateTE.c - - Contents: Q.931 State Engine for TE (User Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - This reference implementation uses a process per message, - meaning that each message must check call states. This - is easier for dialect maintenance as each message proc - can be replaced individually. A new TE variant only - need to copy the Q931CreateTE and replace those procs or - need to override. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q931.h" - -extern L3INT Q931L4HeaderSpace; - -/***************************************************************************** - Function: Q931CreateTE - - Description: Will create the Q931 TE as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void Q931CreateTE(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingTE, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingTE, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, Q931ProcConnectTE, Q931Umes_Connect, Q931Pmes_Connect); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, Q931ProcConnectAckTE, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressTE, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupTE, Q931Umes_Setup, Q931Pmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckTE, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeTE, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckTE, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectTE, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendTE, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckTE, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectTE, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationTE, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectTE, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseTE, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteTE, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartTE, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckTE, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlTE, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationTE, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyTE, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusTE, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryTE, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentTE, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityTE, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldTE, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckTE, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectTE, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterTE, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveTE, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckTE, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectTE, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - - Q931SetIEProc(Q931ie_CONNECTED_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_FACILITY, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_REDIRECTING_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - - /* The following define a state machine. The point is that the Message - * procs can when search this to find out if the message/state - * combination is legale. If not, the proc for unexpected message apply. - */ - - /* State 0 Idle */ - Q931AddStateEntry(i, Q931_U0, Q931mes_RESUME, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_STATUS, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE_COMPLETE, 4); - - /* State 1 Call Initiating */ - Q931AddStateEntry(i, Q931_U1, Q931mes_DISCONNECT, 2); - Q931AddStateEntry(i, Q931_U1, Q931mes_SETUP_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_RELEASE_COMPLETE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CONNECT, 4); - - /* State 2 Overlap Sending */ - Q931AddStateEntry(i, Q931_U2, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U2, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_RELEASE, 2); - - /* State 3 Outgoing Call Proceeding */ - Q931AddStateEntry(i, Q931_U3, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_RELEASE, 2); - - /* State 4 Call Delivered */ - Q931AddStateEntry(i, Q931_U4, Q931mes_CONNECT, 4); - - /* State 6 Call Precent */ - Q931AddStateEntry(i, Q931_U6, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CALL_PROCEEDING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE_COMPLETE, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U6, Q931mes_DISCONNECT, 4); - - /* State 7 Call Received */ - Q931AddStateEntry(i, Q931_U7, Q931mes_CONNECT, 2); - - /* State 8 Connect request */ - Q931AddStateEntry(i, Q931_U8, Q931mes_CONNECT_ACKNOWLEDGE, 4); - - /* State 9 Incoming Call Proceeding */ - Q931AddStateEntry(i, Q931_U9, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_PROGRESS, 2); - - /* State 10 Active */ - Q931AddStateEntry(i, Q931_U10, Q931mes_SUSPEND, 2); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 4); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 2); - - /* State 11 Disconnect Request */ - Q931AddStateEntry(i, Q931_U11, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_NOTIFY, 4); - - /* State 12 Disconnect Ind */ - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 2); - - /* State 15 Suspend Request */ - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_REJECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_RELEASE, 4); - -/* TODO - Q931AddStateEntry(i, Q931_U17, - Q931AddStateEntry(i, Q931_U19, - Q931AddStateEntry(i, Q931_U25, -*/ - - /* Timer default values */ - Q931SetTimerDefault(i, Q931_TIMER_T301, 180000); /* T301: 180s */ - Q931SetTimerDefault(i, Q931_TIMER_T302, 15000); /* T302: 15s */ - Q931SetTimerDefault(i, Q931_TIMER_T303, 4000); /* T303: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T304, 30000); /* T304: 30s */ - Q931SetTimerDefault(i, Q931_TIMER_T305, 30000); /* T305: 30s */ - Q931SetTimerDefault(i, Q931_TIMER_T308, 4000); /* T308: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T309, 60000); /* T309: 60s */ - Q931SetTimerDefault(i, Q931_TIMER_T310, 60000); /* T310: 60s */ - Q931SetTimerDefault(i, Q931_TIMER_T313, 4000); /* T313: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T314, 4000); /* T314: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T316, 120000); /* T316: 120s */ - Q931SetTimerDefault(i, Q931_TIMER_T317, 90000); /* T317: 90s */ - Q931SetTimerDefault(i, Q931_TIMER_T318, 4000); /* T318: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T319, 4000); /* T319: 4s */ - Q931SetTimerDefault(i, Q931_TIMER_T321, 30000); /* T321: 30s */ - Q931SetTimerDefault(i, Q931_TIMER_T322, 4000); /* T322: 4s */ -} - -/***************************************************************************** - - Function: Q931ProcAlertingTE - -*****************************************************************************/ -L3INT Q931ProcAlertingTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* Reset 4 sec timer. */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcCallProceedingTE - -*****************************************************************************/ -L3INT Q931ProcCallProceedingTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcConnectTE - -*****************************************************************************/ -L3INT Q931ProcConnectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - if (pTrunk->autoConnectAck) { - Q931AckConnect(pTrunk, buf); - } - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcConnectAckTE - -*****************************************************************************/ -L3INT Q931ProcConnectAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcProgressTE - -*****************************************************************************/ -L3INT Q931ProcProgressTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSetupTE - -*****************************************************************************/ -L3INT Q931ProcSetupTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)&buf[Q931L4HeaderSpace]; - L3INT rc = 0; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Reject SETUP on existing calls */ - if (Q931GetCallState(pTrunk, pMes->CRV) != Q931_U0) { - Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); - return Q931E_UNEXPECTED_MESSAGE; - } - - /* outgoing call */ - if (iFrom == 4) { - ret = Q931CreateCRV(pTrunk, &callIndex); - if (ret) - return ret; - pMes->CRV = pTrunk->call[callIndex].CRV; - - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - if (ret) - return ret; - - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - - /* TODO: Add this back when we get the state stuff more filled out */ - /*Q931SetState(pTrunk, callIndex, Q931_U1);*/ - } - /* incoming call */ - else { - /* Locate free CRV entry and store info */ - ret = Q931AllocateCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) { - /* Not possible to allocate CRV entry, so must reject call */ - Q931Disconnect(pTrunk, iFrom, pMes->CRV, 42); - return ret; - } - - /* Send setup indication to user */ - ret = Q931Tx34(pTrunk, (L3UCHAR*)pMes, pMes->Size); - if (ret != Q931E_NO_ERROR) { - if (pTrunk->autoSetupAck) { - Q931AckSetup(pTrunk, buf); - } - return ret; - } else { - /* Must be full queue, meaning we can't process the call */ - /* so we must disconnect */ - Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); - return ret; - } -#if 0 - /* TODO: Unreachable code??? */ - /* Set state U6 */ - Q931SetState(pTrunk, callIndex, Q931_U6); - - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); -#endif - } - return rc; -} - -/***************************************************************************** - - Function: Q931ProcSetupAckTE - - Description: Used to acknowedge a SETUP. Usually the first initial - response recevide back used to buy some time. L4 sending this - should only be passed on. L2 sending this means that we set - a new timer (and pass it to L4). - - Note that ChanID (B Channel Assignment) might come here from - NT side. - -*****************************************************************************/ -L3INT Q931ProcSetupAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcResumeTE - -*****************************************************************************/ -L3INT Q931ProcResumeTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Generic * pMes = (Q931mes_Generic *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (Q931GetCallState(pTrunk, pMes->CRV) == Q931_U0 && iFrom ==4) { - /* Call reference selection */ - ret = Q931CreateCRV(pTrunk, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - pMes->CRV = pTrunk->call[callIndex].CRV; - - /* Send RESUME to network */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - if (ret != Q931E_NO_ERROR) - return ret; - - /* Start timer T318 */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T318); - - /* set state U17 */ - Q931SetState(pTrunk, callIndex, Q931_U17); - } else { - return Q931E_ILLEGAL_MESSAGE; - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcResumeAckTE - -*****************************************************************************/ -L3INT Q931ProcResumeAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcResumeRejectTE - -*****************************************************************************/ -L3INT Q931ProcResumeRejectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSuspendTE - -*****************************************************************************/ -L3INT Q931ProcSuspendTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSuspendAckTE - -*****************************************************************************/ -L3INT Q931ProcSuspendAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSuspendRejectTE - -*****************************************************************************/ -L3INT Q931ProcSuspendRejectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcInformationTE - -*****************************************************************************/ -L3INT Q931ProcUserInformationTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcDisconnectTE - -*****************************************************************************/ -L3INT Q931ProcDisconnectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Processing DISCONNECT message from %s for CRV: %d (%#hx)\n", - iFrom == 4 ? "Local" : "Remote", pMes->CRV, pMes->CRV); - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcReleaseTE - -*****************************************************************************/ -L3INT Q931ProcReleaseTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT state = Q931GetCallState(pTrunk, pMes->CRV); - L3INT ret = Q931E_NO_ERROR; - - if (iFrom == 4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (state == Q931_U0 && iFrom == 2) { - Q931Tx34(pTrunk, buf, pMes->Size); - ret = Q931ReleaseComplete(pTrunk, buf); - } else { - ret = Q931ProcUnexpectedMessage(pTrunk, buf, iFrom); - } - if (pMes->CRV && iFrom == 2) { - /* Find the call using CRV */ - if ((Q931FindCRV(pTrunk, pMes->CRV, &callIndex)) != Q931E_NO_ERROR) - return ret; - pTrunk->call[callIndex].InUse = 0; - } - - return ret; -} - -/***************************************************************************** - - Function: Q931ProcReleaseCompleteTE - -*****************************************************************************/ -L3INT Q931ProcReleaseCompleteTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } else { - if (pMes->CRV) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - pTrunk->call[callIndex].InUse = 0; - - /* TODO: experimental, send RELEASE_COMPLETE message */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRestartTE - -*****************************************************************************/ -L3INT Q931ProcRestartTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (pMes->CRV) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - } - - /* TODO chack against state table for illegal or unexpected message here */ - - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - - if (pTrunk->autoRestartAck) { - Q931AckRestart(pTrunk, buf); - } - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRestartAckTE - -*****************************************************************************/ -L3INT Q931ProcRestartAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - if (pMes->CRV) { - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - } - - /* TODO chack against state table for illegal or unexpected message here */ - - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcCongestionControlTE - -*****************************************************************************/ -L3INT Q931ProcCongestionControlTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcInformationTE - -*****************************************************************************/ -L3INT Q931ProcInformationTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcNotifyTE - -*****************************************************************************/ -L3INT Q931ProcNotifyTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcStatusTE - -*****************************************************************************/ -L3INT Q931ProcStatusTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcStatusEnquiryTE - -*****************************************************************************/ -L3INT Q931ProcStatusEnquiryTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcSegmentTE - -*****************************************************************************/ -L3INT Q931ProcSegmentTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/****************************************************************************/ -/******************* Q.932 - Supplementary Services *************************/ -/****************************************************************************/ - -/***************************************************************************** - - Function: Q932ProcRetrieveTE - -*****************************************************************************/ -L3INT Q932ProcFacilityTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcRetrieveTE - -*****************************************************************************/ -L3INT Q932ProcHoldTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcRetrieveTE - -*****************************************************************************/ -L3INT Q932ProcHoldAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcRetrieveTE - -*****************************************************************************/ -L3INT Q932ProcHoldRejectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcRegisterTE - -*****************************************************************************/ -L3INT Q932ProcRegisterTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q932ProcRetrieveTE - -*****************************************************************************/ -L3INT Q932ProcRetrieveTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRetrieveAckTE - -*****************************************************************************/ -L3INT Q932ProcRetrieveAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} - -/***************************************************************************** - - Function: Q931ProcRetrieveRejectTE - -*****************************************************************************/ -L3INT Q932ProcRetrieveRejectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom) -{ - Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; - L3INT callIndex; - L3INT ret = Q931E_NO_ERROR; - - /* Find the call using CRV */ - ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); - if (ret != Q931E_NO_ERROR) - return ret; - - /* TODO chack against state table for illegal or unexpected message here */ - - /* TODO - Set correct timer here */ - Q931StartTimer(pTrunk, callIndex, Q931_TIMER_T303); - if (iFrom ==4) { - /* TODO Add proc here */ - ret = Q931Tx32Data(pTrunk, 0, buf, pMes->Size); - } - else if (iFrom == 2) { - /* TODO Add proc here */ - ret = Q931Tx34(pTrunk, buf, pMes->Size); - } - return ret; -} diff --git a/libs/freetdm/src/isdn/Q931api.c b/libs/freetdm/src/isdn/Q931api.c deleted file mode 100644 index ed0d13836b..0000000000 --- a/libs/freetdm/src/isdn/Q931api.c +++ /dev/null @@ -1,598 +0,0 @@ -/***************************************************************************** - - FileName: Q931api.c - - Contents: api (Application Programming Interface) functions. - See q931.h for description. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q931.h" -#include "memory.h" - -extern L3INT Q931L4HeaderSpace; - -/* -L3INT Q931CreateMesIndex(L3INT mc) -{ - if(mc < 0 || mc > 127 ) - return Q931E_INTERNAL; - - if(Q931MesCount >127) - return Q931E_INTERNAL; - - Q931MesIndex[mc] = Q931MesCount ++; - - return Q931E_NO_ERROR; -} -*/ -/* -L3INT Q931CreateIEIndex(L3INT iec) -{ - if(iec < 0 || iec > 127 ) - return Q931E_INTERNAL; - - if(Q931IECount > 127) - return Q931E_INTERNAL; - - Q931IEIndex[iec] = Q931IECount ++; - - return Q931E_NO_ERROR; -} -*/ - -L3INT Q931Api_InitTrunk(Q931_TrunkInfo_t *pTrunk, - Q931Dialect_t Dialect, - Q931NetUser_t NetUser, - Q931_TrunkType_t TrunkType, - Q931Tx34CB_t Q931Tx34CBProc, - Q931Tx32CB_t Q931Tx32CBProc, - Q931ErrorCB_t Q931ErrorCBProc, - void *PrivateData32, - void *PrivateData34) -{ - int y, dchannel, maxchans, has_sync = 0; - - switch(TrunkType) - { - case Q931_TrType_E1: - dchannel = 16; - maxchans = 31; - has_sync = 1; - break; - - case Q931_TrType_T1: - case Q931_TrType_J1: - dchannel = 24; - maxchans = 24; - break; - - case Q931_TrType_BRI: - case Q931_TrType_BRI_PTMP: - dchannel = 3; - maxchans = 3; - break; - - default: - return 0; - } - - pTrunk->Q931Tx34CBProc = Q931Tx34CBProc; - pTrunk->Q931Tx32CBProc = Q931Tx32CBProc; - pTrunk->Q931ErrorCBProc = Q931ErrorCBProc; - pTrunk->PrivateData32 = PrivateData32; - pTrunk->PrivateData34 = PrivateData34; - - pTrunk->LastCRV = 0; - pTrunk->Dialect = Dialect + NetUser; - pTrunk->Enabled = 0; - pTrunk->TrunkType = TrunkType; - pTrunk->NetUser = NetUser; - pTrunk->TrunkState = 0; - pTrunk->autoRestartAck = 0; - for(y=0; y < Q931MAXCHPERTRUNK; y++) - { - pTrunk->ch[y].Available = 1; - - if(has_sync && y == 0) - { - pTrunk->ch[y].ChanType = Q931_ChType_Sync; - } - else if(y == dchannel) - { - pTrunk->ch[y].ChanType = Q931_ChType_D; - } - else if(y > maxchans) - { - pTrunk->ch[y].ChanType = Q931_ChType_NotUsed; - } - else - { - pTrunk->ch[y].ChanType = Q931_ChType_B; - } - } - - for(y=0; y < Q931MAXCALLPERTRUNK; y++) - { - pTrunk->call[y].InUse = 0; - - } - return 1; -} - -void Q931SetMesProc(L3UCHAR mes, L3UCHAR dialect, q931proc_func_t *Q931ProcFunc, q931umes_func_t *Q931UmesFunc, q931pmes_func_t *Q931PmesFunc) -{ - if(Q931ProcFunc != NULL) - Q931Proc[dialect][mes] = Q931ProcFunc; - if(Q931UmesFunc != NULL) - Q931Umes[dialect][mes] = Q931UmesFunc; - if(Q931PmesFunc != NULL) - Q931Pmes[dialect][mes] = Q931PmesFunc; -} - -void Q931SetIEProc(L3UCHAR iec, L3UCHAR dialect, q931pie_func_t *Q931PieProc, q931uie_func_t *Q931UieProc) -{ - if(Q931PieProc != NULL) - Q931Pie[dialect][iec] = Q931PieProc; - if(Q931UieProc != NULL) - Q931Uie[dialect][iec] = Q931UieProc; -} - -void Q931SetTimeoutProc(L3UCHAR dialect, L3UCHAR timer, q931timeout_func_t *Q931TimeoutProc) -{ - if(Q931Timeout != NULL) - Q931Timeout[dialect][timer] = Q931TimeoutProc; -} - -void Q931SetTimerDefault(L3UCHAR dialect, L3UCHAR timer, q931timer_t timeout) -{ - Q931Timer[dialect][timer] = timeout; -} - -L3INT Q931GetMesSize(Q931mes_Generic *pMes) -{ - - L3UCHAR *p = &pMes->buf[0]; - L3INT Size = (L3INT)(p - (L3UCHAR *)pMes); - return Size; -} - -/***************************************************************************** - - Function: q931AppendIE - - Description: Append IE to the message. - - Parameters: pm Ptr to message. - pi Ptr to information element - - Return Value ie setting - -*****************************************************************************/ - -ie Q931AppendIE( L3UCHAR *pm, L3UCHAR *pi) -{ - ie IE = 0; - Q931mes_Generic * pMes= (Q931mes_Generic *)pm; - Q931ie_BearerCap * pIE= (Q931ie_BearerCap *)pi; - L3INT iISize = pIE->Size; - - L3UCHAR *pBuf = &pMes->buf[0]; - L3INT Off = (L3INT)(pMes->Size - (pBuf - pm)); - IE = (ie)(Off | 0x8000); - - memcpy(&pm[pMes->Size], pi, iISize); - - pMes->Size += iISize; - - return IE; -} - -/***************************************************************************** -*****************************************************************************/ -static L3INT crv={1}; - -L3INT Q931GetUniqueCRV(Q931_TrunkInfo_t *pTrunk) -{ - L3INT max = (Q931_IS_BRI(pTrunk)) ? Q931_BRI_MAX_CRV : Q931_PRI_MAX_CRV; - - crv++; - crv = (crv <= max) ? crv : 1; - - return crv; -} - -L3INT Q931InitMesGeneric(Q931mes_Generic *pMes) -{ - memset(pMes, 0, sizeof(*pMes)); - pMes->ProtDisc = 0x08; - pMes->Size = Q931GetMesSize(pMes); - - return 0; -} - -L3INT Q931InitMesResume(Q931mes_Generic * pMes) -{ - pMes->ProtDisc = 0x08; - pMes->CRV = 0; /* CRV to be allocated, might be receive*/ - pMes->MesType = Q931mes_RESUME; - - pMes->Size = Q931GetMesSize(pMes); - pMes->CallID = 0; /* Channel Identification */ - return 0; -} - -L3INT Q931InitMesRestartAck(Q931mes_Generic * pMes) -{ - pMes->ProtDisc = 0x08; - pMes->CRV = 0; /* CRV to be allocated, might be receive*/ - pMes->MesType = Q931mes_RESTART_ACKNOWLEDGE; - - pMes->Size = Q931GetMesSize(pMes); - pMes->ChanID = 0; /* Channel Identification */ - pMes->Display = 0; - pMes->RestartInd = 0; - pMes->RestartWin = 0; - return 0; -} - -L3INT Q931InitIEBearerCap(Q931ie_BearerCap *pIE) -{ - pIE->IEId = Q931ie_BEARER_CAPABILITY; - pIE->Size = sizeof(Q931ie_BearerCap); - pIE->CodStand = 0; - pIE->ITC = 0; - pIE->TransMode = 0; - pIE->ITR = 0x10; - pIE->RateMul = 0; - - pIE->Layer1Ident = 0; - pIE->UIL1Prot = 0; /* User Information Layer 1 Protocol */ - pIE->SyncAsync = 0; /* Sync/Async */ - pIE->Negot = 0; - pIE->UserRate = 0; - pIE->InterRate = 0; /* Intermediate Rate */ - pIE->NIConTx = 0; - pIE->NIConRx = 0; - pIE->FlowCtlTx = 0; /* Flow control on Tx */ - pIE->FlowCtlRx = 0; /* Flow control on Rx */ - pIE->HDR = 0; - pIE->MultiFrame = 0; /* Multi frame support */ - pIE->Mode = 0; - pIE->LLInegot = 0; - pIE->Assignor = 0; /* Assignor/assignee */ - pIE->InBandNeg = 0; /* In-band/out-band negot. */ - pIE->NumStopBits = 0; /* Number of stop bits */ - pIE->NumDataBits = 0; /* Number of data bits. */ - pIE->Parity = 0; - pIE->DuplexMode = 0; - pIE->ModemType = 0; - pIE->Layer2Ident = 0; - pIE->UIL2Prot = 0; /* User Information Layer 2 Protocol */ - pIE->Layer3Ident = 0; - pIE->UIL3Prot = 0; /* User Information Layer 3 Protocol */ - pIE->AL3Info1 = 0; - pIE->AL3Info2 = 0; - - return 0; -} - -L3INT Q931InitIEChanID(Q931ie_ChanID *pIE) -{ - pIE->IEId = Q931ie_CHANNEL_IDENTIFICATION; - pIE->Size = sizeof(Q931ie_ChanID); - pIE->IntIDPresent = 0; /* Int. id. present */ - pIE->IntType = 0; /* Int. type */ - pIE->PrefExcl = 0; /* Pref./Excl. */ - pIE->DChanInd = 0; /* D-channel ind. */ - pIE->InfoChanSel = 0; /* Info. channel selection */ - pIE->InterfaceID = 0; /* Interface identifier */ - pIE->CodStand = 0; /* Code standard */ - pIE->NumMap = 0; /* Number/Map */ - pIE->ChanMapType = 0; /* Channel type/Map element type */ - pIE->ChanSlot = 0; /* Channel number/Slot map */ - - return 0; -} - -L3INT Q931InitIEProgInd(Q931ie_ProgInd * pIE) -{ - pIE->IEId = Q931ie_PROGRESS_INDICATOR; - pIE->Size = sizeof(Q931ie_ProgInd); - pIE->CodStand = 0; /* Coding standard */ - pIE->Location = 0; /* Location */ - pIE->ProgDesc = 0; /* Progress description */ - - return 0; -} - -L3INT Q931InitIENetFac(Q931ie_NetFac * pIE) -{ - pIE->IEId = Q931ie_NETWORK_SPECIFIC_FACILITIES; - pIE->Size = sizeof(Q931ie_NetFac); - pIE->LenNetID = 0; /* Length of network facilities id. */ - pIE->TypeNetID = 0; /* Type of network identification */ - pIE->NetIDPlan = 0; /* Network identification plan. */ - pIE->NetFac = 0; /* Network specific facility spec. */ - pIE->NetID[0] = 0; - return 0; -} - -L3INT Q931InitIEDisplay(Q931ie_Display * pIE) -{ - pIE->IEId = Q931ie_DISPLAY; - pIE->Size = sizeof(Q931ie_Display); - pIE->Display[0] = 0; - return 0; -} - -L3INT Q931InitIEDateTime(Q931ie_DateTime * pIE) -{ - pIE->IEId = Q931ie_DATETIME; - pIE->Size = sizeof(Q931ie_DateTime); - pIE->Year = 0; /* Year */ - pIE->Month = 0; /* Month */ - pIE->Day = 0; /* Day */ - pIE->Hour = 0; /* Hour */ - pIE->Minute = 0; /* Minute */ - pIE->Second = 0; /* Second */ - - return 0; -} - -L3INT Q931InitIEKeypadFac(Q931ie_KeypadFac * pIE) -{ - pIE->IEId = Q931ie_KEYPAD_FACILITY; - pIE->Size = sizeof(Q931ie_KeypadFac); - pIE->KeypadFac[0] = 0; - return 0; -} - -L3INT Q931InitIESignal(Q931ie_Signal * pIE) -{ - pIE->IEId = Q931ie_SIGNAL; - pIE->Size = sizeof(Q931ie_Signal); - pIE->Signal = 0; - return 0; -} - -L3INT Q931InitIECallingNum(Q931ie_CallingNum * pIE) -{ - pIE->IEId = Q931ie_CALLING_PARTY_NUMBER; - pIE->Size = sizeof(Q931ie_CallingNum); - pIE->TypNum = 0; /* Type of number */ - pIE->NumPlanID = 0; /* Numbering plan identification */ - pIE->PresInd = 0; /* Presentation indicator */ - pIE->ScreenInd = 0; /* Screening indicator */ - pIE->Digit[0] = 0; /* Number digits (IA5) */ - - return 0; -} - -L3INT Q931InitIECallingSub(Q931ie_CallingSub * pIE) -{ - pIE->IEId = Q931ie_CALLING_PARTY_SUBADDRESS; - pIE->Size = sizeof(Q931ie_CallingSub); - pIE->TypNum = 0; /* Type of subaddress */ - pIE->OddEvenInd = 0; /* Odd/Even indicator */ - pIE->Digit[0] = 0; /* Digits */ - - return 0; -} - -L3INT Q931InitIECalledNum(Q931ie_CalledNum * pIE) -{ - pIE->IEId = Q931ie_CALLED_PARTY_NUMBER; - pIE->Size = sizeof(Q931ie_CalledNum); - pIE->TypNum = 0; /* Type of Number */ - pIE->NumPlanID = 0; /* Numbering plan identification */ - pIE->Digit[0] = 0; /* Digit (IA5) */ - - return 0; -} - -L3INT Q931InitIECalledSub(Q931ie_CalledSub * pIE) -{ - pIE->IEId = Q931ie_CALLED_PARTY_SUBADDRESS; - pIE->Size = sizeof(Q931ie_CalledSub); - pIE->TypNum = 0; /* Type of subaddress */ - pIE->OddEvenInd = 0; /* Odd/Even indicator */ - pIE->Digit[0] = 0; /* Digits */ - - return 0; -} - -L3INT Q931InitIETransNetSel(Q931ie_TransNetSel * pIE) -{ - pIE->IEId = Q931ie_TRANSIT_NETWORK_SELECTION; - pIE->Size = sizeof(Q931ie_TransNetSel); - pIE->Type = 0; /* Type of network identifier */ - pIE->NetIDPlan = 0; /* Network idetification plan */ - pIE->NetID[0] = 0; /* Network identification(IA5) */ - - return 0; -} - -L3INT Q931InitIELLComp(Q931ie_LLComp * pIE) -{ - pIE->IEId = Q931ie_LOW_LAYER_COMPATIBILITY; - pIE->Size = sizeof(Q931ie_LLComp); - - pIE->CodStand = 0; /* Coding standard */ - pIE->ITransCap = 0; /* Information transfer capability */ - pIE->NegotInd = 0; /* Negot indic. */ - pIE->TransMode = 0; /* Transfer Mode */ - pIE->InfoRate = 0; /* Information transfer rate */ - pIE->RateMul = 0; /* Rate multiplier */ - pIE->Layer1Ident = 0; /* Layer 1 ident. */ - pIE->UIL1Prot = 0; /* User information layer 1 protocol */ - pIE->SyncAsync = 0; /* Synch/asynch */ - pIE->Negot = 0; /* Negot */ - pIE->UserRate = 0; /* User rate */ - pIE->InterRate = 0; /* Intermediate rate */ - pIE->NIConTx = 0; /* NIC on Tx */ - pIE->NIConRx = 0; /* NIC on Rx */ - pIE->FlowCtlTx = 0; /* Flow control on Tx */ - pIE->FlowCtlRx = 0; /* Flow control on Rx */ - pIE->HDR = 0; /* Hdr/no hdr */ - pIE->MultiFrame = 0; /* Multiframe */ - pIE->ModeL1 = 0; /* Mode L1 */ - pIE->NegotLLI = 0; /* Negot. LLI */ - pIE->Assignor = 0; /* Assignor/Assignor ee */ - pIE->InBandNeg = 0; /* In-band negot. */ - pIE->NumStopBits = 0; /* Number of stop bits */ - pIE->NumDataBits = 0; /* Number of data bits */ - pIE->Parity = 0; /* Parity */ - pIE->DuplexMode = 0; /* Duplex Mode */ - pIE->ModemType = 0; /* Modem type */ - pIE->Layer2Ident = 0; /* Layer 2 ident. */ - pIE->UIL2Prot = 0; /* User information layer 2 protocol */ - pIE->ModeL2 = 0; /* ModeL2 */ - pIE->Q933use = 0; /* Q.9333 use */ - pIE->UsrSpcL2Prot = 0; /* User specified layer 2 protocol info */ - pIE->WindowSize = 0; /* Window size (k) */ - pIE->Layer3Ident = 0; /* Layer 3 ident */ - pIE->OptL3Info = 0; /* Optional layer 3 protocol info. */ - pIE->ModeL3 = 0; /* Mode of operation */ -#if 0 - pIE->ModeX25op = 0; /* Mode of operation X.25 */ -#endif - pIE->DefPackSize = 0; /* Default packet size */ - pIE->PackWinSize = 0; /* Packet window size */ - pIE->AddL3Info = 0; /* Additional Layer 3 protocol info */ - - return 0; -} - -L3INT Q931InitIEHLComp(Q931ie_HLComp * pIE) -{ - pIE->IEId = Q931ie_HIGH_LAYER_COMPATIBILITY; - pIE->Size = sizeof(Q931ie_HLComp); - - return 0; -} - -L3INT Q931ProcUnknownMessage(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom) -{ - /* TODO: Unhandled paramaters */ - (void)pTrunk; - (void)b; - (void)iFrom; - - return 0; -} - -L3INT Q931ProcUnexpectedMessage(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom) -{ - /* TODO: Unhandled paramaters */ - (void)pTrunk; - (void)b; - (void)iFrom; - - return 0; -} - -L3INT Q931Disconnect(Q931_TrunkInfo_t *pTrunk, L3INT iTo, L3INT iCRV, L3INT iCause) -{ - /* TODO: Unhandled paramaters */ - (void)pTrunk; - (void)iTo; - (void)iCRV; - (void)iCause; - - return 0; -} - -L3INT Q931ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf) -{ - Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; - ptr->MesType = Q931mes_RELEASE_COMPLETE; - ptr->CRVFlag = !(ptr->CRVFlag); - return Q931Tx32Data(pTrunk,0,buf,ptr->Size); -} - -L3INT Q931AckRestart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf) -{ - L3INT RetCode; - - Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; - ptr->MesType = Q931mes_RESTART_ACKNOWLEDGE; - //if (ptr->CRV) { - ptr->CRVFlag = !(ptr->CRVFlag); - //} - - RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4); - - return RetCode; -} - -L3INT Q931AckSetup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf) -{ - L3INT RetCode; - - Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; - ptr->MesType = Q931mes_SETUP_ACKNOWLEDGE; - - RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4); - - return RetCode; -} - -L3INT Q931AckConnect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf) -{ - L3INT RetCode; - - Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; - ptr->MesType = Q931mes_CONNECT_ACKNOWLEDGE; - - RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4); - - return RetCode; -} - -L3INT Q931AckService(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf) -{ - L3INT RetCode; - - Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; - ptr->MesType = Q931mes_SERVICE_ACKNOWLEDGE; - if (ptr->CRV) { - ptr->CRVFlag = !(ptr->CRVFlag); - } - - RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4); - - return RetCode; -} - -Q931_ENUM_NAMES(DIALECT_TYPE_NAMES, DIALECT_STRINGS) -Q931_STR2ENUM(q931_str2Q931Dialect_type, q931_Q931Dialect_type2str, Q931Dialect_t, DIALECT_TYPE_NAMES, Q931_Dialect_Count) diff --git a/libs/freetdm/src/isdn/Q931ie.c b/libs/freetdm/src/isdn/Q931ie.c deleted file mode 100644 index 62312ee654..0000000000 --- a/libs/freetdm/src/isdn/Q931ie.c +++ /dev/null @@ -1,3074 +0,0 @@ -/***************************************************************************** - - FileName: Q931ie.c - - Contents: Information Element Pack/Unpack functions. - - These functions will pack out a Q931 message from the bit - packed original format into structs that are easier to process - and pack the same structs back into bit fields when sending - messages out. - - The messages contains a short for each possible IE. The MSB - bit flags the precense of an IE, while the remaining bits - are the offset into a buffer to find the actual IE. - - Each IE are supported by 3 functions: - - Q931Pie_XXX Pack struct into Q.931 IE - Q931Uie_XXX Unpack Q.931 IE into struct - Q931InitIEXXX Initialize IE (see Q931api.c). - - Dialect Note: This file will only contain standard DSS1 IE. Other IE as - used in QSIG, NI2, Q.932 etc are located in separate files. - - See q931.h for description. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q931.h" - -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif -#if (_MSC_VER >= 1400) /* VC8+ */ -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE -#endif -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE -#endif -#endif -#ifndef strcasecmp -#define strcasecmp(s1, s2) _stricmp(s1, s2) -#endif -#ifndef strncasecmp -#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) -#endif -#ifndef snprintf -#define snprintf _snprintf -#endif -#endif - -/***************************************************************************** - - Macro: Q931MoreIE - - Description: Local helper macro detecting if there is more IE space left - based on the 3 standard parameters Octet, Off and IESpace. - This can be used to test if the IE is completed to avoid - that the header of the next IE is interpreted as a part of - the current IE. - -*****************************************************************************/ -#define Q931MoreIE() (Octet + Off - 2 < IESize) - -#define Q931IESizeTest(x) {\ - if (Octet + Off - 2 != IESize) {\ - Q931SetError(pTrunk, x, Octet, Off);\ - return x;\ - }\ -} - -/***************************************************************************** - - Function: Q931ReadExt - - Description: Many of the octets in the standard have an MSB 'ext.1'. This - means that the octet usually is the latest octet, but that a - futhure standard may extend the octet. A stack must be able - to handle such extensions by skipping the extension octets. - - This function will increase the offset counter with 1 for - each octet with an MSB of zero. This will allow the stack to - skip extensions wihout knowing anything about them. - - Parameters: IBuf ptr to octet array. - Off Starting offset counter - - Return Value: New offset value. - -*****************************************************************************/ - -L3INT Q931ReadExt(L3UCHAR * IBuf, L3INT Off) -{ - L3INT c = 0; - while ((IBuf[c] & 0x80) == 0) { - c++; - } - return Off + c; -} - -/***************************************************************************** - - Function: Q931Uie_BearerCap - - Description: Unpack a bearer capability ie. - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ - -L3INT Q931Uie_BearerCap(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_BearerCap *pie = (Q931ie_BearerCap*)OBuf; - ie *pIE = &pMsg->BearerCap; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->CodStand = ieGetOctet((IBuf[Octet] & 0x60) >> 5); - pie->ITC = ieGetOctet(IBuf[Octet] & 0x1f); - Off = Q931ReadExt(&IBuf[Octet], Off); - Octet++; - - /* Octet 4 */ - pie->TransMode = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5); - pie->ITR = ieGetOctet(IBuf[Octet + Off] & 0x1f); - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - Octet++; - - /* Octet 4.1. Rate multiplier is only present if ITR = Multirate */ - if (pie->ITR == 0x18) { - pie->RateMul = ieGetOctet(IBuf[Octet + Off] & 0x7f); - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - Off ++; - } - - /* Octet 5 */ - if ((IBuf[Octet + Off] & 0x60) == 0x20 && Q931MoreIE()) { - pie->Layer1Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5); - pie->UIL1Prot = ieGetOctet(IBuf[Octet + Off] & 0x1f); - Octet++; - - /* Octet 5a. The octet may be present if ITC is unrestrictd digital info - * and UIL1Prot is either V.110, I.460 and X.30 or V.120. It may also - * be present if ITC = 3.1 kHz audio and UIL1Prot is G.711. - * Bit 8 of Octet 5 = 0 indicates that 5a is present. - */ - - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - if (((pie->ITC == 0x08) && (pie->UIL1Prot == 0x01 || pie->UIL1Prot == 0x08)) - || ((pie->ITC == 0x10) && (pie->UIL1Prot == 0x02 || pie->UIL1Prot == 0x03))) { - pie->SyncAsync = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6); - pie->Negot = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5); - pie->UserRate = ieGetOctet(IBuf[Octet + Off] & 0x1f); - Off ++; - } - else { - /* We have detected bit 8 = 0, but no setting that require the */ - /* additional octets ??? */ - Q931SetError(pTrunk, Q931E_BEARERCAP, 5,Off); - return Q931E_BEARERCAP; - } - - /* Octet 5b. Two different structures used. */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - if (pie->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30 */ - pie->InterRate = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5); - pie->NIConTx = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4); - pie->NIConRx = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3); - pie->FlowCtlTx = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2); - pie->FlowCtlRx = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 1); - Off++; - } - else if (pie->UIL1Prot == 0x08) { /* ITU V.120 */ - pie->HDR = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6); - pie->MultiFrame = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5); - pie->Mode = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4); - pie->LLInegot = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3); - pie->Assignor = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2); - pie->InBandNeg = ieGetOctet((IBuf[Octet + Off] & 0x02) >> 1); - Off++; - } - else { - Q931SetError(pTrunk,Q931E_BEARERCAP, 5,Off); - return Q931E_BEARERCAP; - } - - /* Octet 5c */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->NumStopBits = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5); - pie->NumDataBits = ieGetOctet((IBuf[Octet + Off] & 0x18) >> 3); - pie->Parity = ieGetOctet(IBuf[Octet + Off] & 0x07); - Off++; - - /* Octet 5d */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->DuplexMode = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6); - pie->ModemType = ieGetOctet(IBuf[Octet + Off] & 0x3f); - Off ++; - } - } - } - } - } - - /* Octet 6 */ - if ((IBuf[Octet + Off] & 0x60) == 0x40 && Q931MoreIE()) { - pie->Layer2Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5); - pie->UIL2Prot = ieGetOctet(IBuf[Octet + Off] & 0x1f); - - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - Octet ++; - } - - /* Octet 7 */ - if ((IBuf[Octet + Off] & 0x60) == 0x60 && Q931MoreIE()) { - pie->Layer3Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5); - pie->UIL3Prot = ieGetOctet(IBuf[Octet + Off] & 0x1f); - Octet++; - - /* Octet 7a */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - if (pie->UIL3Prot == 0x0c) { - pie->AL3Info1 = ieGetOctet(IBuf[Octet + Off] & 0x0f); - Off++; - - /* Octet 7b */ - if (IsQ931Ext(IBuf[Octet + Off])) { - pie->AL3Info2 = ieGetOctet(IBuf[Octet + Off] & 0x0f); - Off++; - } - } - else { - Q931SetError(pTrunk,Q931E_BEARERCAP, 7, Off); - return Q931E_BEARERCAP; - - } - } - } - - Q931IESizeTest(Q931E_BEARERCAP); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_BearerCap); - pie->Size = sizeof(Q931ie_BearerCap); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_BearerCap - - Description: Packing a Q.931 Bearer Capability element from a generic - struct into a packed octet structure in accordance with the - standard. - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ - -L3INT Q931Pie_BearerCap(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_BearerCap *pIE = (Q931ie_BearerCap*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; /* remember current offset */ - L3INT li; - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Encoding Bearer Capability IE\n"); - - OBuf[(*Octet)++] = Q931ie_BEARER_CAPABILITY ; - li = (*Octet)++; /* remember length position */ - - /* Octet 3 - Coding standard / Information transfer capability */ - OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | (pIE->ITC & 0x1f); - - /* Octet 4 - Transfer mode / Information transfer rate */ - OBuf[(*Octet)++] = 0x80 | ((pIE->TransMode << 5) & 0x60) | (pIE->ITR & 0x1f); - - if (pIE->ITR == 0x18) { - /* Octet 4.1 - Rate Multiplier */ - OBuf[(*Octet)++] = 0x80 | (pIE->RateMul & 0x7f); - } - - /* Octet 5 - Layer 1 Ident / User information layer 1 protocol */ - if (pIE->Layer1Ident == 0x01) { - if (((pIE->ITC == 0x08) && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) || - ((pIE->ITC == 0x10) && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) { - OBuf[(*Octet)++] = 0x00 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x15); - - /* Octet 5a - SyncAsync/Negot/UserRate */ - OBuf[(*Octet)++] = 0x00 | ((pIE->SyncAsync << 6) & 0x40) | ((pIE->Negot << 5) & 0x20) | (pIE->UserRate & 0x1f); - - /* Octet 5b - one of two types */ - if (pIE->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30 */ - /* Octet 5b - Intermed rate/ Nic on Tx/Nix on Rx/FlowCtlTx/FlowCtlRx */ - OBuf[(*Octet)++] = 0x00 - | ((pIE->InterRate << 6) & 0x60) - | ((pIE->NIConTx << 4) & 0x10) - | ((pIE->NIConRx << 3) & 0x08) - | ((pIE->FlowCtlTx << 2) & 0x04) - | ((pIE->FlowCtlRx << 1) & 0x02); - } - else if (pIE->UIL1Prot == 0x08) { /* ITU V.120 */ - /* Octet 5b - HDR/Multiframe/Mode/LLINegot/Assignor/Inbandneg*/ - OBuf[(*Octet)++] = 0x00 - | ((pIE->InterRate << 6) & 0x60) - | ((pIE->MultiFrame << 5) & 0x20) - | ((pIE->Mode << 4) & 0x10) - | ((pIE->LLInegot << 3) & 0x08) - | ((pIE->Assignor << 2) & 0x04) - | ((pIE->InBandNeg << 1) & 0x02); - } - - /* Octet 5c - NumStopBits/NumStartBits/Parity */ - OBuf[(*Octet)++] = 0x00 - | ((pIE->NumStopBits << 5) & 0x60) - | ((pIE->NumDataBits << 3) & 0x18) - | (pIE->Parity & 0x07); - - /* Octet 5d - Duplex Mode/Modem Type */ - OBuf[(*Octet)++] = 0x80 | ((pIE->DuplexMode << 6) & 0x40) | (pIE->ModemType & 0x3f); - } - else { - OBuf[(*Octet)++] = 0x80 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x1f); - } - } - - /* Octet 6 - Layer2Ident/User information layer 2 prtocol */ - if (pIE->Layer2Ident == 0x02) { - OBuf[(*Octet)++] = 0x80 | ((pIE->Layer2Ident << 5) & 0x60) | (pIE->UIL2Prot & 0x1f); - } - - /* Octet 7 - Layer 3 Ident/ User information layer 3 protocol */ - if (pIE->Layer3Ident == 0x03) { - if (pIE->UIL3Prot == 0x0c) { - OBuf[(*Octet)++] = 0x00 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f); - - /* Octet 7a - Additional information layer 3 msb */ - OBuf[(*Octet)++] = 0x00 | (pIE->AL3Info1 & 0x0f); - - /* Octet 7b - Additional information layer 3 lsb */ - OBuf[(*Octet)++] = 0x80 | (pIE->AL3Info2 & 0x0f); - } - else { - OBuf[(*Octet)++] = 0x80 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f); - } - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_CallID - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_CallID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_CallID *pie = (Q931ie_CallID*)OBuf; - ie *pIE = &pMsg->CallID; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x = 0; - L3INT IESize; - - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - do { - pie->CallId[x] = IBuf[Octet + Off] & 0x7f; - Off++; - x++; - } while (Q931MoreIE()); - - Q931IESizeTest(Q931E_CALLID); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CallID) + x - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_CallID) + x - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_CallID - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ - -L3INT Q931Pie_CallID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_CallID *pIE = (Q931ie_CallID*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet;/* remember current offset */ - L3INT li; - L3INT sCI = pIE->Size - sizeof(Q931ie_CallID) + 1; - L3INT x; - - OBuf[(*Octet)++] = Q931ie_CALL_IDENTITY ; - li = (*Octet)++; /* remember length position */ - - for (x = 0; x < sCI; x++) { - OBuf[(*Octet)++] = pIE->CallId[x]; - } - - OBuf[(*Octet) - 1] |= 0x80; /* set complete flag at last octet*/ - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_CallState - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_CallState(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_CallState *pie = (Q931ie_CallState*)OBuf; - ie *pIE = &pMsg->CallState; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->CodStand = (IBuf[Octet + Off] >> 6) & 0x03; - pie->CallState = IBuf[Octet + Off] & 0x3f; - Octet++; - - Q931IESizeTest(Q931E_CALLSTATE); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CallState); - pie->Size = sizeof(Q931ie_CallState); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_CallState - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_CallState(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_CallState *pIE = (Q931ie_CallState*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; /* remember current offset */ - L3INT li; - - OBuf[(*Octet)++] = Q931ie_CALL_STATE; - li = (*Octet)++; /* remember length position */ - - OBuf[(*Octet)++] = (pIE->CodStand << 6) | (pIE->CallState & 0x3f); - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_CalledSub - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_CalledSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_CalledSub *pie = (Q931ie_CalledSub*)OBuf; - ie *pIE = &pMsg->CalledSub; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x; - L3INT IESize; - - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07; - pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01; - Octet++; - - /* Octet 4 */ - x = 0; - do { - pie->Digit[x] = IBuf[Octet + Off] & 0x7f; - Off++; - x++; - } while (Q931MoreIE() && x < 20); - - Q931IESizeTest(Q931E_CALLEDSUB); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CalledSub) + x - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledSub) + x - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_CalledSub - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_CalledSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_CalledSub *pIE = (Q931ie_CalledSub*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1; - L3INT x; - - /* Octet 1 */ - OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_SUBADDRESS; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3); - - /* Octet 4 */ - for (x = 0; xDigit[x]; - } - - OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */ - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_CalledNum - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_CalledNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_CalledNum *pie = (Q931ie_CalledNum*)OBuf; - ie *pIE = &pMsg->CalledNum; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x; - L3INT IESize; /* # digits in this case */ - - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07; - pie->NumPlanID = IBuf[Octet + Off] & 0x0f; - Octet++; - - /* Octet 4*/ - x = 0; - do { - pie->Digit[x] = IBuf[Octet + Off] & 0x7f; - Off++; - x++; - } while ((IBuf[Octet + Off]&0x80) == 0 && Q931MoreIE()); - - pie->Digit[x] = '\0'; - - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x; - pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_CalledNum - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_CalledNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_CalledNum *pIE = (Q931ie_CalledNum*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - L3INT sN = pIE->Size - sizeof(Q931ie_CalledNum); - L3INT x; - - /* Octet 1 */ - OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_NUMBER; - - /* Octet 2 */ - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->NumPlanID); - - /* Octet 4 */ - for (x = 0; xDigit[x]; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_CallingNum - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_CallingNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_CallingNum *pie = (Q931ie_CallingNum*)OBuf; - ie *pIE = &pMsg->CallingNum; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x; - L3INT IESize; - - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07; - pie->NumPlanID = IBuf[Octet + Off] & 0x0f; - - /* Octet 3a */ - if ((IBuf[Octet + Off] & 0x80) == 0) { - Off++; - pie->PresInd = (IBuf[Octet + Off] >> 5) & 0x03; - pie->ScreenInd = IBuf[Octet + Off] & 0x03; - } - Octet++; - - /* Octet 4 */ - x = 0; - while (Q931MoreIE()) { - pie->Digit[x++] = IBuf[Octet + Off] & 0x7f; - - if ((IBuf[Octet + Off] & 0x80) != 0) { - break; - } - Off++; - } - pie->Digit[x] = '\0'; - - Q931IESizeTest(Q931E_CALLINGNUM); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x; - pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_CallingNum - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_CallingNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_CallingNum *pIE = (Q931ie_CallingNum*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - L3INT sN = pIE->Size - sizeof(Q931ie_CallingNum); - L3INT x; - - /* Octet 1 */ - OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_NUMBER; - - /* Octet 2 */ - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x00 | (pIE->TypNum << 4) | (pIE->NumPlanID); - - /* Octet 4 */ - OBuf[(*Octet)++] = 0x80; - - /* Octet 5 */ - for (x = 0; xDigit[x]; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_CallingSub - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_CallingSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_CallingSub *pie = (Q931ie_CallingSub*)OBuf; - ie *pIE = &pMsg->CallingSub; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x; - L3INT IESize; - - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07; - pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01; - Octet++; - - /* Octet 4*/ - x = 0; - do { - pie->Digit[x] = IBuf[Octet + Off] & 0x7f; - Off++; - x++; - } while (Q931MoreIE() && x < 20); - - Q931IESizeTest(Q931E_CALLINGSUB); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x -1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x -1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_CallingSub - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_CallingSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_CallingSub *pIE = (Q931ie_CallingSub*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - L3INT sN = pIE->Size - sizeof(Q931ie_CallingSub) + 1; - L3INT x; - - /* Octet 1 */ - OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_SUBADDRESS; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3); - - /* Octet 4 */ - for (x = 0; xDigit[x]; - } - - OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */ - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_Cause - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_Cause(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_Cause *pie = (Q931ie_Cause*)OBuf; - ie *pIE = &pMsg->Cause; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2*/ - IESize = IBuf[Octet++]; - - /* Octet 3*/ - pie->CodStand = (IBuf[Octet + Off]>>5) & 0x03; - pie->Location = IBuf[Octet + Off] & 0x0f; - - /* Octet 3a */ - if ((IBuf[Octet + Off] & 0x80) == 0) { - Off++; - pie->Recom = IBuf[Octet + Off] & 0x7f; - } - Octet++; - - /* Octet 4 */ - pie->Value = IBuf[Octet + Off] & 0x7f; - Octet++; - - /* Consume optional Diagnostic bytes */ - while (Q931MoreIE()) { - Off++; - }; - - Q931IESizeTest(Q931E_CAUSE); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_Cause); - pie->Size = sizeof(Q931ie_Cause); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_Cause - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_Cause(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_Cause *pIE = (Q931ie_Cause*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_CAUSE; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<5) | pIE->Location; - - /* Octet 3a - currently not supported in send */ - - /* Octet 4 */ - OBuf[(*Octet)++] = 0x80 | pIE->Value; - - /* Octet 5 - diagnostics not supported in send */ - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_CongLevel - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_CongLevel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_CongLevel *pie = (Q931ie_CongLevel*)OBuf; - ie *pIE = &pMsg->CongestionLevel; - L3INT Off = 0; - L3INT Octet = 0; - - *pIE = 0; - - pie->IEId = IBuf[Octet] & 0xf0; - pie->CongLevel = IBuf[Octet] & 0x0f; - Octet ++; - - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CongLevel); - pie->Size = sizeof(Q931ie_CongLevel); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_CongLevel - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_CongLevel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_CongLevel *pIE = (Q931ie_CongLevel*)IBuf; - L3INT rc = 0; - /* L3INT Beg = *Octet; */ - - OBuf[(*Octet)++] = Q931ie_CONGESTION_LEVEL | pIE->CongLevel; - - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_ChanID - - Parameters: IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Uie_ChanID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_ChanID *pie = (Q931ie_ChanID*)OBuf; - ie *pIE = &pMsg->ChanID; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; -//18 04 e1 80 83 01 - *pIE = 0; - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Decoding ChanID IE\n"); - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->IntIDPresent = (IBuf[Octet] >> 6) & 0x01; - pie->IntType = (IBuf[Octet] >> 5) & 0x01; - pie->PrefExcl = (IBuf[Octet] >> 3) & 0x01; - pie->DChanInd = (IBuf[Octet] >> 2) & 0x01; - pie->InfoChanSel = IBuf[Octet] & 0x03; - - Off = Q931ReadExt(&IBuf[Octet++], Off); - - /* Octet 3.1 */ - if (pie->IntIDPresent) { - pie->InterfaceID = IBuf[Octet + Off] & 0x7f; - - /* Temp fix. Interface id can be extended using the extension bit */ - /* this will read the octets, but do nothing with them. this is done */ - /* because the usage of this field is a little unclear */ - /* 30.jan.2001/JVB */ - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - Off++; - } - - if ((Octet + Off - 2) != IESize) { - /* Octet 3.2 */ - if (pie->IntType == 1) { /* PRI etc */ - pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03; - pie->NumMap = (IBuf[Octet + Off] >> 4) & 0x01; - pie->ChanMapType = IBuf[Octet + Off] & 0x0f; - Off++; - - /* Octet 3.3 */ - /* Temp fix. Assume B channel. H channels not supported */ - pie->ChanSlot = IBuf[Octet + Off] & 0x7f; - - /* Some dialects don't follow the extension coding properly for this, but this should be safe for all */ - if ((Octet + Off - 1) != IESize) { - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - } - Off++; - } - } - - Q931IESizeTest(Q931E_CHANID); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_ChanID); - pie->Size = sizeof(Q931ie_ChanID); - - if (pTrunk->loglevel == Q931_LOG_DEBUG) { - const char *iface; - char tmp[100] = ""; - - if (!pie->IntType) { - switch (pie->InfoChanSel) { - case 0x0: - iface = "None"; - break; - case 0x1: - iface = "B1"; - break; - case 0x2: - iface = "B2"; - break; - default: - iface = "Any Channel"; - } - - snprintf(tmp, sizeof(tmp)-1, "InfoChanSel: %d (%s)", pie->InfoChanSel, iface); - } - - Q931Log(pTrunk, Q931_LOG_DEBUG, - "\n-------------------------- Q.931 Channel ID ------------------------\n" - " Pref/Excl: %s, Interface Type: %s\n" - " %s\n" - "--------------------------------------------------------------------\n\n", - ((pie->PrefExcl) ? "Preferred" : "Exclusive"), - ((pie->IntType) ? "PRI/Other" : "BRI"), - tmp); - } - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_ChanID - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_ChanID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_ChanID *pIE = (Q931ie_ChanID*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; /* remember current offset */ - L3INT li; - - OBuf[(*Octet)++] = Q931ie_CHANNEL_IDENTIFICATION; - li = (*Octet)++; /* remember length position */ - - /* Octet 3 flags & BRI chan # */ - OBuf[(*Octet)++] = 0x80 - | ((pIE->IntIDPresent << 6) & 0x40) - | ((pIE->IntType << 5) & 0x20) - | ((pIE->PrefExcl << 3) & 0x08) - | (pIE->InfoChanSel & 0x03); - - /* Octet 3.1 - Interface Identifier */ - if (pIE->IntIDPresent) { - OBuf[(*Octet)++] = 0x80 | (pIE->InterfaceID & 0x7f); - } - - /* Octet 3.2 & 3.3 - PRI */ - if (pIE->IntType) { - OBuf[(*Octet)++] = 0x80 - | ((pIE->CodStand << 5) & 0x60) - | ((pIE->NumMap << 4) & 0x10) - | (pIE->ChanMapType & 0x0f); /* TODO: support all possible channel map types */ - - /* Octet 3.3 Channel number */ - switch (pIE->ChanMapType) { - case 0x6: /* Slot map: H0 Channel Units */ /* unsupported, Octets 3.3.1 - 3.3.3 */ - return Q931E_CHANID; - - case 0x8: /* Slot map: H11 Channel Units */ - case 0x9: /* Slot map: H12 Channel Units */ - default: /* Channel number */ - OBuf[(*Octet)++] = 0x80 | (pIE->ChanSlot & 0x7f); - break; - } - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - - -/***************************************************************************** - - Function: Q931Uie_CRV - - Description: Reading CRV. - - The CRV is currently returned in the return value that - Q921Rx23 will assign to the CRV field in the unpacked - message. CRV is basically 2 bytes etc, but the spec allows - the use of longer CRV values. - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: CRV - -*****************************************************************************/ -L3USHORT Q931Uie_CRV(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff) -{ - L3USHORT CRV = 0; - L3INT Octet = *IOff; - L3INT l = IBuf[Octet++]; - - if (l == 1) { /* One octet CRV */ - CRV = IBuf[Octet++] & 0x7F; - } - else if (l == 2) { /* two octet CRV */ - CRV = (IBuf[Octet++] & 0x7f) << 8; - CRV |= IBuf[Octet++]; - } - else { - /* Long CRV is not used, so we skip this */ - /* TODO: is it right to set to 0 here? */ - CRV = 0; - Octet += l; - } - - *IOff = Octet; - return CRV; -} - -/***************************************************************************** - - Function: Q931Uie_DateTime - - Parameters: pTrunk [IN] Ptr to trunk information. - pIE [OUT] ptr to Information Element id. - IBuf [IN] ptr to a packed ie. - OBuf [OUT] ptr to buffer for Unpacked ie. - IOff [IN\OUT] Input buffer offset - OOff [IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_DateTime(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_DateTime * pie = (Q931ie_DateTime*)OBuf; - ie *pIE = &pMsg->DateTime; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize = 0; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 - Year */ - pie->Year = IBuf[Octet++]; - - /* Octet 4 - Month */ - pie->Month = IBuf[Octet++]; - - /* Octet 5 - Day */ - pie->Day = IBuf[Octet++]; - - /******************************************************************* - The remaining part of the IE are optioinal, but only the length - can now tell us wherever these fields are present or not - (always remember: IESize does not include ID and Size octet) - ********************************************************************/ - pie->Format = 0; - - /* Octet 6 - Hour (optional)*/ - if (IESize >= 4) { - pie->Format = 1; - pie->Hour = IBuf[Octet++]; - - /* Octet 7 - Minute (optional)*/ - if (IESize >= 5) { - pie->Format = 2; - pie->Minute = IBuf[Octet++]; - - /* Octet 8 - Second (optional)*/ - if (IESize >= 6) { - pie->Format = 3; - pie->Second = IBuf[Octet++]; - } - } - } - - Q931IESizeTest(Q931E_DATETIME); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_DateTime); - pie->Size = sizeof(Q931ie_DateTime); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_DateTime - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_DateTime(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_DateTime *pIE = (Q931ie_DateTime*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_DATETIME; - li = (*Octet)++; - - OBuf[(*Octet)++] = pIE->Year; - OBuf[(*Octet)++] = pIE->Month; - OBuf[(*Octet)++] = pIE->Day; - if (pIE->Format >= 1) { - OBuf[(*Octet)++] = pIE->Hour; - - if (pIE->Format >= 2) { - OBuf[(*Octet)++] = pIE->Minute; - - if (pIE->Format >= 3) { - OBuf[(*Octet)++] = pIE->Second; - } - } - } - - OBuf[li] = (L3UCHAR)((*Octet)-Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_Display - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_Display(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_Display *pie = (Q931ie_Display*)OBuf; - ie *pIE = &pMsg->Display; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - L3INT x; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - IESize = IBuf[Octet++]; - - for (x = 0; xDisplay[x] = IBuf[Octet + Off] & 0x7f; - Off++; - } - - Q931IESizeTest(Q931E_DISPLAY); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_Display) + x - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_Display) + x - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_Display - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_Display(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_Display *pIE = (Q931ie_Display*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - L3INT DSize; - L3INT x; - - OBuf[(*Octet)++] = Q931ie_DISPLAY; - li = (*Octet)++; - - DSize = pIE->Size - sizeof(Q931ie_Display); - - for (x = 0; x< DSize; x++) { - - OBuf[(*Octet)++] = pIE->Display[x]; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_HLComp - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_HLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_HLComp * pie = (Q931ie_HLComp*)OBuf; - ie *pIE = &pMsg->HLComp; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet */ - IESize = IBuf[Octet++]; - - /* Octet 3*/ - pie->CodStand = (IBuf[Octet + Off] >>5) & 0x03; - pie->Interpret = (IBuf[Octet + Off] >>2) & 0x07; - pie->PresMeth = IBuf[Octet + Off] & 0x03; - Octet++; - - /* Octet 4 */ - pie->HLCharID = IBuf[Octet + Off] & 0x7f; - Octet++; - - /* Octet 4a*/ - if ((IBuf[Octet + Off - 1] & 0x80) == 0 && Q931MoreIE()) { - if (pie->HLCharID == 0x5e || pie->HLCharID == 0x5f) { - pie->EHLCharID = IBuf[Octet + Off] & 0x7f; - Off++; - } - else if ( pie->HLCharID >= 0xc3 && pie->HLCharID <= 0xcf) { - pie->EVideoTlfCharID = IBuf[Octet + Off] & 0x7f; - Off++; - } - else { - /* error Octet 4a indicated, but invalid value in Octet 4. */ - Q931SetError(pTrunk,Q931E_HLCOMP, 4, Off); - return Q931E_HLCOMP; - } - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - } - - Q931IESizeTest(Q931E_HLCOMP); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_HLComp); - pie->Size = sizeof(Q931ie_HLComp); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_HLComp - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_HLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_HLComp *pIE = (Q931ie_HLComp*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_HIGH_LAYER_COMPATIBILITY; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | ((pIE->Interpret << 2) & 0x1c) | (pIE->PresMeth & 0x03); - - /* Octet 4 */ - OBuf[(*Octet)++] = pIE->HLCharID; - - /* Octet 4a */ - if (pIE->HLCharID == 0x5e || pIE->HLCharID == 0x5f) { - OBuf[(*Octet)++] = 0x80 | (pIE->EHLCharID & 0x7f); - } - else if ( pIE->HLCharID >= 0xc3 && pIE->HLCharID <= 0xcf) { - OBuf[(*Octet)++] = 0x80 | (pIE->EVideoTlfCharID & 0x7f); - } - else { - OBuf[(*Octet) - 1] |= 0x80; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_KeypadFac - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_KeypadFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_KeypadFac *pie = (Q931ie_KeypadFac*)OBuf; - ie *pIE = &pMsg->KeypadFac; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - L3INT x; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - IESize = IBuf[Octet++]; - - for (x = 0; xKeypadFac[x] = IBuf[Octet + Off] & 0x7f; - Off++; - } - - Q931IESizeTest(Q931E_KEYPADFAC); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_KeypadFac) + x - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_KeypadFac) + x - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_KeypadFac - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_KeypadFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_KeypadFac *pIE = (Q931ie_KeypadFac*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - L3INT DSize; - L3INT x; - - OBuf[(*Octet)++] = Q931ie_KEYPAD_FACILITY; - li = (*Octet)++; - - DSize = pIE->Size - sizeof(Q931ie_KeypadFac) + 1; - - for (x = 0; x< DSize; x++) { - OBuf[(*Octet)++] = pIE->KeypadFac[x]; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_LLComp - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_LLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_LLComp *pie = (Q931ie_LLComp*)OBuf; - ie *pIE = &pMsg->LLComp; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03; - pie->ITransCap = IBuf[Octet + Off] & 0x1f; - Octet++; - - /* Octet 3a*/ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->NegotInd = (IBuf[Octet + Off] >> 6) & 0x01; - Off++; - } - - /* Octet 4 */ - pie->TransMode = (IBuf[Octet + Off] >> 5) & 0x03; - pie->InfoRate = IBuf[Octet + Off] & 0x1f; - - Octet++; - - /* Octet 4.1 */ - if (pie->InfoRate == 0x14) { /* Mutirate */ - pie->RateMul = IBuf[Octet + Off] & 0x7f; - Off++; - } - - /* Octet 5 - Layer 1 Ident */ - if ((IBuf[Octet + Off] & 0x60) == 0x20) { /* Layer 1 Ident ? */ - pie->Layer1Ident = (IBuf[Octet + Off] >> 5) & 0x03; - pie->UIL1Prot = IBuf[Octet + Off] & 0x1f; - Octet++; - - /* Octet 5a */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->SyncAsync = (IBuf[Octet + Off] >> 6) & 0x01; - pie->Negot = (IBuf[Octet + Off] >> 5) & 0x01; - pie->UserRate = IBuf[Octet + Off] & 0x1f; - Off++; - - /* Octet 5b - 2 options */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - if (pie->UIL1Prot == 0x01) { /* V.110, I.460 and X.30*/ - pie->InterRate = (IBuf[Octet + Off] >> 5) & 0x03; - pie->NIConTx = (IBuf[Octet + Off] >> 4) & 0x01; - pie->NIConRx = (IBuf[Octet + Off] >> 3) & 0x01; - pie->FlowCtlTx = (IBuf[Octet + Off] >> 2) & 0x01; - pie->FlowCtlRx = (IBuf[Octet + Off] >> 1) & 0x01; - Off++; - } - else if (pie->UIL1Prot == 0x80) { /* V.120 */ - pie->HDR = (IBuf[Octet + Off] >> 6) & 0x01; - pie->MultiFrame = (IBuf[Octet + Off] >> 5) & 0x01; - pie->ModeL1 = (IBuf[Octet + Off] >> 4) & 0x01; - pie->NegotLLI = (IBuf[Octet + Off] >> 3) & 0x01; - pie->Assignor = (IBuf[Octet + Off] >> 2) & 0x01; - pie->InBandNeg = (IBuf[Octet + Off] >> 1) & 0x01; - Off++; - } - else if (pie->UIL1Prot == 0x07) { /* non standard */ - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - Off++; - } - else { - Q931SetError(pTrunk,Q931E_LLCOMP, 5,2); - return Q931E_LLCOMP; - } - - /* Octet 5c */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->NumStopBits = (IBuf[Octet + Off] >> 5) & 0x03; - pie->NumDataBits = (IBuf[Octet + Off] >> 3) & 0x03; - pie->Parity = IBuf[Octet + Off] & 0x07; - Off++; - - /* Octet 5d */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->DuplexMode = (IBuf[Octet + Off] >> 6) & 0x01; - pie->ModemType = IBuf[Octet + Off] & 0x3f; - Off = Q931ReadExt(&IBuf[Octet + Off], Off); - Off++; - } - } - } - } - } - - /* Octet 6 - Layer 2 Ident */ - if ((IBuf[Octet + Off] & 0x60) == 0x40) { /* Layer 1 Ident ? */ - pie->Layer2Ident = (IBuf[Octet + Off] >>5) & 0x03; - pie->UIL2Prot = IBuf[Octet + Off] & 0x1f; - Octet++; - - /* Octet 6a */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - if (pie->UIL2Prot == 0x10) { /* 2nd 6a */ - pie->UsrSpcL2Prot = IBuf[Octet + Off] & 0x7f; - Off++; - } - else { /* assume 1st 6a */ - pie->ModeL2 = (IBuf[Octet + Off] >> 5) & 0x03; - pie->Q933use = IBuf[Octet + Off] & 0x03; - Off++; - } - /* Octet 6b */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->WindowSize = IBuf[Octet + Off] & 0x7f; - Off++; - } - } - } - - /* Octet 7 - layer 3 Ident */ - if ((IBuf[Octet + Off] & 0x60) == 0x60) { /* Layer 3 Ident ? */ - pie->Layer3Ident = (IBuf[Octet + Off] >> 5) & 0x03; - pie->UIL3Prot = IBuf[Octet + Off] & 0x1f; - Octet++; - - /* Octet 7a */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - if (pie->UIL3Prot == 0x0b) { - /* Octet 7a + 7b AddL3Info */ - pie->AddL3Info = ((IBuf[Octet + Off] << 4) & 0xf0) - | (IBuf[Octet + Off + 1] & 0x0f); - Off += 2; - } - else { - if (pie->UIL3Prot == 0x1f) { - pie->ModeL3 = (IBuf[Octet + Off] >> 5) & 0x03; - Off++; - } - else { - pie->OptL3Info = IBuf[Octet + Off] & 0x7f; - Off++; - } - - /* Octet 7b*/ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->DefPackSize = IBuf[Octet + Off] & 0x0f; - Off++; - - /* Octet 7c */ - if (IsQ931Ext(IBuf[Octet + Off - 1])) { - pie->PackWinSize= IBuf[Octet + Off] & 0x7f; - } - } - } - } - } - - Q931IESizeTest(Q931E_LLCOMP); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_LLComp); - pie->Size = sizeof(Q931ie_LLComp); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_LLComp - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_LLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_LLComp *pIE = (Q931ie_LLComp*)IBuf; - L3INT rc = 0; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_LOW_LAYER_COMPATIBILITY; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = (pIE->CodStand << 6) | pIE->ITransCap; - - /* Octet 3a */ - OBuf[(*Octet)++] = 0x80 | (pIE->NegotInd << 6); - - /* Octet 4 */ - OBuf[(*Octet)++] = 0x80 | (pIE->TransMode << 5) | pIE->InfoRate; - - /* Octet 4.1 */ - if (pIE->InfoRate == 0x18) { - OBuf[(*Octet)++] = 0x80 | pIE->RateMul; - } - - /* Octet 5 */ - if (pIE->Layer1Ident == 0x01) { - OBuf[(*Octet)++] = (pIE->Layer1Ident << 5) | pIE->UIL1Prot; - - /* Octet 5a */ - if ((pIE->ITransCap == 0x08 && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) - || (pIE->ITransCap == 0x10 && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) { - OBuf[(*Octet)++] = (pIE->SyncAsync<<6) | (pIE->Negot<<5) | pIE->UserRate; - - /* Octet 5b*/ - if (pIE->UIL1Prot == 0x01) { - OBuf[(*Octet)++] = (pIE->InterRate << 5) - | (pIE->NIConTx << 4) - | (pIE->NIConTx << 3) - | (pIE->FlowCtlTx << 2) - | (pIE->FlowCtlRx << 1); - } - else if (pIE->UIL1Prot == 0x08) { - OBuf[(*Octet)++] = (pIE->HDR << 6) - | (pIE->MultiFrame << 5) - | (pIE->ModeL1 << 4) - | (pIE->NegotLLI << 3) - | (pIE->Assignor << 2) - | (pIE->InBandNeg << 1); - } - else { - OBuf[(*Octet) - 1] |= 0x80; - } - - /* How to detect wherever 5c and 5d is to present is not clear - * but they have been inculded as 'standard' - * Octet 5c - */ - if (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08) { - OBuf[(*Octet)++] = (pIE->NumStopBits << 5) | (pIE->NumDataBits << 3) | pIE->Parity ; - - /* Octet 5d */ - OBuf[(*Octet)++] = 0x80 | (pIE->DuplexMode << 6) | pIE->ModemType; - } - } - else { - OBuf[(*Octet) - 1] |= 0x80; - } - } - - /* Octet 6 */ - if (pIE->Layer2Ident == 0x02) { - OBuf[(*Octet)++] = (pIE->Layer2Ident << 5) | pIE->UIL2Prot; - - /* Octet 6a*/ - if (pIE->UIL2Prot == 0x02 /* Q.921/I.441 */ - || pIE->UIL2Prot == 0x06 /* X.25 link layer */ - || pIE->UIL2Prot == 0x07 /* X.25 multilink */ - || pIE->UIL2Prot == 0x09 /* HDLC ARM */ - || pIE->UIL2Prot == 0x0a /* HDLC NRM */ - || pIE->UIL2Prot == 0x0b /* HDLC ABM */ - || pIE->UIL2Prot == 0x0d /* X.75 SLP */ - || pIE->UIL2Prot == 0x0e /* Q.922 */ - || pIE->UIL2Prot == 0x11) { /* ISO/ECE 7776 DTE-DCE */ - OBuf[(*Octet)++] = (pIE->ModeL2 << 5) | pIE->Q933use; - - /* Octet 6b */ - OBuf[(*Octet)++] = 0x80 | pIE->WindowSize; - } - else if (pIE->UIL2Prot == 0x10) { /* User Specific */ - OBuf[(*Octet)++] = 0x80 | pIE->UsrSpcL2Prot; - } - else { - OBuf[(*Octet) - 1] |= 0x80; - } - } - - /* Octet 7 */ - if (pIE->Layer3Ident == 0x03) { - OBuf[(*Octet)++] = (pIE->Layer3Ident << 5) | pIE->UIL3Prot; - - /* Octet 7a - 3 different ones */ - if (pIE->UIL3Prot == 0x10) { - OBuf[(*Octet++)] = 0x80 | pIE->OptL3Info; - } - else if (pIE->UIL3Prot == 0x06 - || pIE->UIL3Prot == 0x07 - || pIE->UIL3Prot == 0x08) { - OBuf[(*Octet)++] = pIE->ModeL3 << 5; - - /* Octet 7b note 7 */ - OBuf[(*Octet)++] = pIE->DefPackSize; - - /* Octet 7c note 7 */ - OBuf[(*Octet)++] = 0x80 | pIE->PackWinSize; - } - else if (pIE->UIL3Prot == 0x0b) { - OBuf[(*Octet)++] = (pIE->AddL3Info >> 4) & 0x0f; - OBuf[(*Octet)++] = 0x80 | (pIE->AddL3Info & 0x0f); - } - else { - OBuf[(*Octet) - 1] |= 0x80; - } - } - else { - Q931SetError(pTrunk,Q931E_LLCOMP, 7,0); - rc = Q931E_LLCOMP; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_NetFac - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_NetFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_NetFac *pie = (Q931ie_NetFac*)OBuf; - ie *pIE = &pMsg->NetFac; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - pie->LenNetID = IBuf[Octet + Off]; /* full octet is used */ - Octet++; - - if (pie->LenNetID > 0) { - /* Octet 3.1 */ - pie->TypeNetID = (IBuf[Octet + Off] >> 4) & 0x0f; - pie->NetIDPlan = IBuf[Octet + Off] & 0x0f; - Off = Q931ReadExt(&IBuf[Octet], Off); - Off++; - - /* Octet 3.2*/ - for (x = 0; x < pie->LenNetID; x++) { - pie->NetID[x] = IBuf[Octet + Off] & 0x7f; - Off++; - } - } - - /* Octet 4*/ - pie->NetFac = IBuf[Octet + Off]; /* Full Octet is used */ - Octet++; - - Q931IESizeTest(Q931E_NETFAC); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_NetFac) + x - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_NetFac) + x - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_NetFac - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_NetFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_NetFac *pIE = (Q931ie_NetFac*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - L3INT x; - - OBuf[(*Octet)++] = Q931ie_NETWORK_SPECIFIC_FACILITIES; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = pIE->LenNetID; - - if (pIE->LenNetID > 0) { - /* Octet 3.1 */ - OBuf[(*Octet)++] = 0x80 | (pIE->TypeNetID << 4) | pIE->NetIDPlan; - - /* Octet 3.2 */ - for (x = 0; x LenNetID; x++) { - OBuf[(*Octet)++] = pIE->NetID[x]; - } - } - - /* Octet 4 */ - OBuf[(*Octet)++] = pIE->NetFac; - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_NotifInd - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_NotifInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_NotifInd *pie = (Q931ie_NotifInd*)OBuf; - ie *pIE = &pMsg->NotifInd; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2*/ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->Notification = IBuf[Octet + Off] & 0x7f; - - Off = Q931ReadExt(&IBuf[Octet], Off); - Octet++; - - Q931IESizeTest(Q931E_NOTIFIND); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_NotifInd); - pie->Size = sizeof(Q931ie_NotifInd); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_NotifInd - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_NotifInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_NotifInd *pIE = (Q931ie_NotifInd*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_NOTIFICATION_INDICATOR; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = pIE->Notification; - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_ProgInd - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_ProgInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_ProgInd *pie = (Q931ie_ProgInd*)OBuf; - ie *pIE = &pMsg->ProgInd; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03; - pie->Location = IBuf[Octet + Off] & 0x0f; - - Off = Q931ReadExt(&IBuf[Octet], Off); - Octet++; - - /* Octet 4 */ - pie->ProgDesc = IBuf[Octet + Off] & 0x7f; - Off = Q931ReadExt(&IBuf[Octet], Off); - Octet++; - - Q931IESizeTest(Q931E_PROGIND); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_ProgInd); - pie->Size = sizeof(Q931ie_ProgInd); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_ProgInd - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset L3INTo OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_ProgInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_ProgInd *pIE = (Q931ie_ProgInd*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_PROGRESS_INDICATOR; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | (pIE->CodStand << 5) | pIE->Location; - - /* Octet 4 */ - OBuf[(*Octet)++] = 0x80 | pIE->ProgDesc; - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_RepeatInd - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_RepeatInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_RepeatInd *pie = (Q931ie_RepeatInd*)OBuf; - ie *pIE = &pMsg->RepeatInd; - L3INT Off = 0; - L3INT Octet = 0; - - *pIE = 0; - - pie->IEId = IBuf[Octet] & 0xf0; - pie->RepeatInd = IBuf[Octet] & 0x0f; - Octet ++; - - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_RepeatInd); - pie->Size = sizeof(Q931ie_RepeatInd); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_RepeatInd - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_RepeatInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_RepeatInd *pIE = (Q931ie_RepeatInd*)IBuf; - L3INT rc = 0; - /* L3INT Beg = *Octet; */ - - OBuf[(*Octet)++] = Q931ie_REPEAT_INDICATOR | pIE->RepeatInd; - - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_RevChargeInd - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - ie iE; - /* ie *pIE = &pMsg->RevChargeInd; */ - Q931SetIE(iE, *OOff); - - return iE; -} - -/***************************************************************************** - - Function: Q931Pie_RevChargeInd - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q931Uie_RestartInd - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_RestartInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_RestartInd *pie = (Q931ie_RestartInd*)OBuf; - ie *pIE = &pMsg->RestartInd; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->Class = IBuf[Octet + Off] & 0x07; - pie->Spare = IBuf[Octet + Off] & 0x78; - - Off = Q931ReadExt(&IBuf[Octet], Off); - Octet++; - - Q931IESizeTest(Q931E_RESTARTIND); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_RestartInd); - pie->Size = sizeof(Q931ie_RestartInd); - - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_RestartInd - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_RestartInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_RestartInd *pIE = (Q931ie_RestartInd*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_RESTART_INDICATOR; - li = (*Octet)++; - - /* Octet 3*/ - OBuf[(*Octet)++] = 0x80 | pIE->Class ; - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_Segment - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_Segment *pie = (Q931ie_Segment*)OBuf; - ie *pIE = &pMsg->Segment; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - Octet++; - - /* Octet 2*/ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->FSI = (IBuf[Octet + Off] & 0x80) >> 7; - pie->NumSegRem = IBuf[Octet + Off] & 0x7f; - Octet++; - - /* Octet 4 */ - pie->SegType = IBuf[Octet + Off] & 0x7f; - Octet++; - - Q931IESizeTest(Q931E_SEGMENT); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_Segment); - pie->Size = sizeof(Q931ie_Segment); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_Segment - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_Segment *pIE = (Q931ie_Segment*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_SEGMENTED_MESSAGE; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = (pIE->FSI << 7) | pIE->NumSegRem; - - /* Octet 4 */ - OBuf[(*Octet)++] = pIE->SegType; - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_SendComplete - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_SendComplete(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_SendComplete *pie = (Q931ie_SendComplete*)OBuf; - ie *pIE = &pMsg->SendComplete; - L3INT Off = 0; - L3INT Octet = 0; - - *pIE = 0; - Octet++; - - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_SendComplete); - pie->Size = sizeof(Q931ie_SendComplete); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_ProgInd - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_SendComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - /* Q931ie_SendComplete * pIE = (Q931ie_SendComplete*)IBuf; */ - L3INT rc = Q931E_NO_ERROR; - /* L3INT Beg = *Octet; */ - - OBuf[(*Octet)++] = 0x80 | (L3UCHAR)Q931ie_SENDING_COMPLETE; - - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_Signal - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_Signal(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_Signal *pie = (Q931ie_Signal*)OBuf; - ie *pIE = &pMsg->Signal; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->Signal = IBuf[Octet + Off]; - Octet++; - - Q931IESizeTest(Q931E_SIGNAL); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_Signal); - pie->Size = sizeof(Q931ie_Signal); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_Signal - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_Signal(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_Signal *pIE = (Q931ie_Signal*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_SIGNAL; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = pIE->Signal; - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_TransNetSel - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_TransNetSel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_TransNetSel *pie = (Q931ie_TransNetSel*)OBuf; - ie *pIE = &pMsg->TransNetSel; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x = 0; - L3INT l; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - l = IBuf[Octet++] - 3; - - /* Octet 3 */ - pie->Type = (IBuf[Octet + Off] >> 4) & 0x07; - - Off = Q931ReadExt(&IBuf[Octet], Off); - Octet++; - - for (x = 0; x < l; x++) { - pie->NetID[x] = IBuf[Octet + Off] & 0x7f; - Off++; - } - - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_TransNetSel) + x - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_TransNetSel) + x - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_TransNetSel - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_TransNetSel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_TransNetSel *pIE = (Q931ie_TransNetSel*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - L3INT x; - L3INT l; - - OBuf[(*Octet)++] = Q931ie_TRANSIT_NETWORK_SELECTION; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | (pIE->Type << 4) | pIE->NetIDPlan; - - /* Octet 4 */ - l = pIE->Size - sizeof(Q931ie_TransNetSel) + 1; - for (x = 0; x < l; x++) { - OBuf[(*Octet)++] = pIE->NetID[x]; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_UserUser - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_UserUser(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_UserUser *pie = (Q931ie_UserUser*)OBuf; - ie *pIE = &pMsg->UserUser; - L3INT Off = 0; - L3INT Octet = 0; - L3INT l; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - l = IBuf[Octet++] - 1; - - /* Octet 3 */ - pie->ProtDisc = IBuf[Octet++]; - - for (Off = 0; Off < l; Off++) { - pie->User[Off] = IBuf[Octet + Off]; - } - - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_UserUser) + Off - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_UserUser) + Off - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_UserUser - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_UserUser(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_UserUser *pIE = (Q931ie_UserUser*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - L3INT x; - L3INT l; - - OBuf[(*Octet)++] = Q931ie_USER_USER; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = pIE->ProtDisc; - - /* Octet 4 */ - l = pIE->Size - sizeof(Q931ie_UserUser) + 1; - for (x = 0; x < l; x++) { - OBuf[(*Octet)++] = pIE->User[x]; - } - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - -/***************************************************************************** - - Function: Q931Uie_GenericDigits - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_GenericDigits(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_GenericDigits *pie = (Q931ie_GenericDigits*)OBuf; - ie *pIE = &pMsg->GenericDigits; - L3INT Off = 0; - L3INT Octet = 0; - L3INT x; - L3INT IESize; - - *pIE = 0; - - /* Octet 1 */ - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->Type = (IBuf[Octet]) & 0x1F; - pie->Encoding = (IBuf[Octet] >> 5) & 0x07; - Octet++; - - /* Octet 4*/ - if (pie->Encoding == 0) { /* BCD Even */ - x = 0; - do { - pie->Digit[x++] = IBuf[Octet + Off] & 0x0f; - pie->Digit[x++] = (IBuf[Octet + Off] >> 4) & 0x0f; - Off++; - } while (Q931MoreIE()); - } else if (pie->Encoding == 1) { /* BCD Odd */ - x = 0; - do { - pie->Digit[x++] = IBuf[Octet + Off] & 0x0f; - if (Q931MoreIE()) { - pie->Digit[x] = (IBuf[Octet + Off] >> 4) & 0x0f; - } - x++; - Off++; - } while (Q931MoreIE()); - } else if (pie->Encoding == 2) { /* IA5 */ - x = 0; - do { - pie->Digit[x++] = IBuf[Octet + Off] & 0x7f; - Off++; - } while (Q931MoreIE()); - } else { - /* Binary encoding type unkown */ - Q931SetError(pTrunk, Q931E_GENERIC_DIGITS, Octet, Off); - return Q931E_GENERIC_DIGITS; - } - - Q931IESizeTest(Q931E_GENERIC_DIGITS); - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x - 1; - pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x - 1); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_GenericDigits - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ - -L3INT Q931Pie_GenericDigits(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - OBuf[(*Octet)++] = (Q931ie_GENERIC_DIGITS & 0xFF); - OBuf[(*Octet)++] = 0; - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Uie_ChangeStatus - - Parameters: pIE[OUT] ptr to Information Element id. - IBuf[IN] ptr to a packed ie. - OBuf[OUT] ptr to buffer for Unpacked ie. - IOff[IN\OUT] Input buffer offset - OOff[IN\OUT] Output buffer offset - - Ibuf and OBuf points directly to buffers. The IOff and OOff - must be updated, but are otherwise not used in the ie unpack. - - Return Value: Error Message - -*****************************************************************************/ -L3INT Q931Uie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) -{ - Q931ie_ChangeStatus *pie = (Q931ie_ChangeStatus*)OBuf; - ie *pIE = &pMsg->ChangeStatus; - L3INT Off = 0; - L3INT Octet = 0; - L3INT IESize; - - *pIE = 0; - - pie->IEId = IBuf[Octet++]; - - /* Octet 2 */ - IESize = IBuf[Octet++]; - - /* Octet 3 */ - pie->Preference = (IBuf[Octet + Off] >> 6) & 0x01; - pie->Spare = IBuf[Octet + Off] & 0x38; - pie->NewStatus = IBuf[Octet + Off] & 0x07; - Octet++; - - Q931SetIE(*pIE, *OOff); - - *IOff = (*IOff) + Octet + Off; - *OOff = (*OOff) + sizeof(Q931ie_ChangeStatus); - pie->Size = sizeof(Q931ie_ChangeStatus); - - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pie_ChangeStatus - - Parameters: IBuf[IN] Ptr to struct. - OBuf[OUT] Ptr tp packed output buffer. - Octet[IN/OUT] Offset into OBuf. - - Return Value: Error code, 0 = OK - -*****************************************************************************/ -L3INT Q931Pie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - Q931ie_ChangeStatus *pIE = (Q931ie_ChangeStatus*)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Beg = *Octet; - L3INT li; - - OBuf[(*Octet)++] = Q931ie_CHANGE_STATUS; - li = (*Octet)++; - - /* Octet 3 */ - OBuf[(*Octet)++] = 0x80 | pIE->NewStatus | ((pIE->Preference & 0x01) << 6); - - OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2; - return rc; -} - - - -L3INT Q931Uie_Generic(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff) -{ - L3INT Octet = 0; - L3UCHAR id = 0; - - /* id */ - id = IBuf[Octet++]; - - /* Length */ - Octet += IBuf[Octet]; - Octet++; - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Discarding IE %#hhx with length %d\n", id, Octet - 2); - - *IOff += Octet; - return Q931E_NO_ERROR; -} - -L3INT Q931Pie_Generic(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) -{ - /* do nothing */ - return Q931E_NO_ERROR; -} diff --git a/libs/freetdm/src/isdn/Q931mes.c b/libs/freetdm/src/isdn/Q931mes.c deleted file mode 100644 index 8e34a170e1..0000000000 --- a/libs/freetdm/src/isdn/Q931mes.c +++ /dev/null @@ -1,1870 +0,0 @@ -/***************************************************************************** - - FileName: Q931mes.c - - Contents: Pack/Unpack functions. These functions will unpack a Q931 - message from the bit packed original format into structs - that contains variables sized by the user. It will also pack - the struct back into a Q.931 message as required. - - See q931.h for description. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*****************************************************************************/ - -#include "Q931.h" - -/** - * Q931MesgHeader - * \brief Create Q.931 Message header - */ -L3INT Q931MesgHeader(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *mes, L3UCHAR *OBuf, L3INT Size, L3INT *IOff) -{ - L3INT Octet = *IOff; - - Q931Log(pTrunk, Q931_LOG_DEBUG, "Creating Q.931 Message Header:\n ProtDisc %d (%#x), CRV %d (%#x), CRVflag: %d (%#x), MesType: %d (%#x)\n", - mes->ProtDisc, mes->ProtDisc, mes->CRV, mes->CRV, mes->CRVFlag, mes->CRVFlag, mes->MesType, mes->MesType); - - OBuf[Octet++] = mes->ProtDisc; /* Protocol discriminator */ - if (!Q931_IS_BRI(pTrunk)) { - OBuf[Octet++] = 2; /* length is 2 octets */ - OBuf[Octet++] = (L3UCHAR)((mes->CRV >> 8) & 0x7f) | ((mes->CRVFlag << 7) & 0x80); /* msb */ - OBuf[Octet++] = (L3UCHAR) (mes->CRV & 0xff); /* lsb */ - } else { - OBuf[Octet++] = 1; /* length is 1 octet */ - OBuf[Octet++] = (L3UCHAR) (mes->CRV & 0x7f) | ((mes->CRVFlag << 7) & 0x80); /* CRV & flag */ - } - OBuf[Octet++] = mes->MesType; /* message header */ - - *IOff = Octet; - return 0; -} - - -/***************************************************************************** - - Function: Q931Umes_Alerting - -*****************************************************************************/ - -L3INT Q931Umes_Alerting(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_DISPLAY: - case Q931ie_SIGNAL: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - case Q931ie_USER_USER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Alerting - -*****************************************************************************/ -L3INT Q931Pmes_Alerting(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_CallProceeding - -*****************************************************************************/ -L3INT Q931Umes_CallProceeding(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_DISPLAY: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_CallProceeding - -*****************************************************************************/ -L3INT Q931Pmes_CallProceeding(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_CongestionControl - -*****************************************************************************/ -L3INT Q931Umes_CongestionControl(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(mes); - NoWarning(IBuf); - - return RetCode; -} - - -/***************************************************************************** - - Function: Q931Pmes_CongestionControl - -*****************************************************************************/ -L3INT Q931Pmes_CongestionControl(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - *OSize = 0; - return RetCode; -} - -/***************************************************************************** - - Function: Q931Umes_Connect - -*****************************************************************************/ -L3INT Q931Umes_Connect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_DISPLAY: - case Q931ie_DATETIME: - case Q931ie_SIGNAL: - case Q931ie_LOW_LAYER_COMPATIBILITY: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - case Q931ie_CONNECTED_NUMBER: /* not actually used, seen while testing BRI PTMP TE */ - case Q931ie_USER_USER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - - default: - Q931Log(pTrunk, Q931_LOG_ERROR, "Illegal IE %#hhx in Connect Message\n", IBuf[IOff]); - - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Connect - -*****************************************************************************/ -L3INT Q931Pmes_Connect(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Date/Time */ - if (Q931IsIEPresent(pMes->DateTime)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DATETIME](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Low Layer Compatibility */ - if (Q931IsIEPresent(pMes->LLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_LOW_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_ConnectAck - -*****************************************************************************/ -L3INT Q931Umes_ConnectAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_DISPLAY: - case Q931ie_SIGNAL: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - - -/***************************************************************************** - - Function: Q931Pmes_ConnectAck - -*****************************************************************************/ -L3INT Q931Pmes_ConnectAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Disconnect - -*****************************************************************************/ -L3INT Q931Umes_Disconnect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CAUSE: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_DISPLAY: - case Q931ie_SIGNAL: - case Q931ie_FACILITY: - case Q931ie_USER_USER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Disconnect - -*****************************************************************************/ -L3INT Q931Pmes_Disconnect(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Cause */ - if (Q931IsIEPresent(pMes->Cause)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CAUSE](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Information - -*****************************************************************************/ -L3INT Q931Umes_Information(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_SENDING_COMPLETE: - case Q931ie_DISPLAY: - case Q931ie_KEYPAD_FACILITY: - case Q931ie_CALLED_PARTY_NUMBER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Information - -*****************************************************************************/ -L3INT Q931Pmes_Information(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Sending Complete */ - if (Q931IsIEPresent(pMes->SendComplete)) { - OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff); - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Keypad Facility */ - if (Q931IsIEPresent(pMes->KeypadFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_KEYPAD_FACILITY](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Called Party number */ - if (Q931IsIEPresent(pMes->CalledNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Notify - -*****************************************************************************/ -L3INT Q931Umes_Notify(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_BEARER_CAPABILITY: - case Q931ie_NOTIFICATION_INDICATOR: - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Notify - -*****************************************************************************/ -L3INT Q931Pmes_Notify(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Progress - -*****************************************************************************/ -L3INT Q931Umes_Progress(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CAUSE: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_DISPLAY: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Progress - -*****************************************************************************/ -L3INT Q931Pmes_Progress(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Cause */ - if (Q931IsIEPresent(pMes->Cause)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CAUSE](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Release - -*****************************************************************************/ -L3INT Q931Umes_Release(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CAUSE: - case Q931ie_DISPLAY: - case Q931ie_SIGNAL: - case Q931ie_USER_USER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Release - -*****************************************************************************/ -L3INT Q931Pmes_Release(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Cause */ - if (Q931IsIEPresent(pMes->Cause)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CAUSE](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_ReleaseComplete - -*****************************************************************************/ -L3INT Q931Umes_ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CAUSE: - case Q931ie_DISPLAY: - case Q931ie_SIGNAL: - case Q931ie_USER_USER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_ReleaseComplete - -*****************************************************************************/ -L3INT Q931Pmes_ReleaseComplete(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Cause */ - if (Q931IsIEPresent(pMes->Cause)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CAUSE](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Restart - -*****************************************************************************/ -L3INT Q931Umes_Restart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_DISPLAY: - case Q931ie_RESTART_INDICATOR: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Restart - -*****************************************************************************/ -L3INT Q931Pmes_Restart(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* ChanID */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* RestartInd */ - if (Q931IsIEPresent(pMes->RestartInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_RESTART_INDICATOR](pTrunk, Q931GetIEPtr(pMes->RestartInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_RestartAck - -*****************************************************************************/ -L3INT Q931Umes_RestartAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size) -{ - Q931mes_Generic *mes = (Q931mes_Generic*)OBuf; - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_DISPLAY: - case Q931ie_RESTART_INDICATOR: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_RestartAck - -*****************************************************************************/ -L3INT Q931Pmes_RestartAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* ChanID */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* RestartInd */ - if (Q931IsIEPresent(pMes->RestartInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_RESTART_INDICATOR](pTrunk, Q931GetIEPtr(pMes->RestartInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Resume - -*****************************************************************************/ -L3INT Q931Umes_Resume(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CALL_IDENTITY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Resume - -*****************************************************************************/ -L3INT Q931Pmes_Resume(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Call Identity */ - if (Q931IsIEPresent(pMes->CallID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALL_IDENTITY](pTrunk, Q931GetIEPtr(pMes->CallID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_ResumeAck - -*****************************************************************************/ -L3INT Q931Umes_ResumeAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - - -/***************************************************************************** - - Function: Q931Pmes_ResumeAck - -*****************************************************************************/ -L3INT Q931Pmes_ResumeAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_ResumeReject - -*****************************************************************************/ -L3INT Q931Umes_ResumeReject(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CAUSE: - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - - -/***************************************************************************** - - Function: Q931Pmes_ResumeReject - -*****************************************************************************/ -L3INT Q931Pmes_ResumeReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Cause */ - if (Q931IsIEPresent(pMes->Cause)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CAUSE](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -L3INT Q931Umes_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT OOff) -{ - L3INT i = IOff; - - return IOff - i; -} - -L3INT Q931Pmes_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - *OSize = 0; - return RetCode; -} - -/***************************************************************************** - - Function: Q931Umes_Setup - -*****************************************************************************/ -L3INT Q931Umes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT ir = 0; - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_SENDING_COMPLETE: - IOff++; - break; - - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_NETWORK_SPECIFIC_FACILITIES: - case Q931ie_DISPLAY: - case Q931ie_DATETIME: - case Q931ie_KEYPAD_FACILITY: - case Q931ie_SIGNAL: - case Q931ie_CALLING_PARTY_NUMBER: - case Q931ie_CALLING_PARTY_SUBADDRESS: - case Q931ie_CALLED_PARTY_NUMBER: - case Q931ie_CALLED_PARTY_SUBADDRESS: - case Q931ie_TRANSIT_NETWORK_SELECTION: - case Q931ie_LOW_LAYER_COMPATIBILITY: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - case Q931ie_FACILITY: - case Q931ie_USER_USER: - case Q931ie_REDIRECTING_NUMBER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - - case Q931ie_REPEAT_INDICATOR: - if (ir < 2) { - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - ir++; - } else { - return Q931E_ILLEGAL_IE; - } - break; - - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Setup - - Decription: Pack a Q931mes_Generic into a real Q.931 message. The user will - set up a SETUP message and issue this to the stack where it - is processed by Q931ProcSetup that processes and validates - it before it actually sends it out. This function is called - to compute the real Q.931 message. - - Parameters: IBuf[IN] Ptr to un-packed struct - ISize[IN] Size of input buffer (unpacked message). - OBuf[OUT] Ptr to packed 'octet' wise message. - OSize[OUT] Size of packed message. - - Called By: Q931ProcSetup - -*****************************************************************************/ -L3INT Q931Pmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Sending Complete */ - if (Q931IsIEPresent(pMes->SendComplete)) { - OBuf[Octet++] = (L3UCHAR)Q931ie_SENDING_COMPLETE & 0xff; - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->RepeatInd)) { - OBuf[Octet++] = (L3UCHAR)Q931ie_REPEAT_INDICATOR & 0xff; - } - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } else { - rc = Q931E_BEARERCAP; - } - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Network spesific facilities */ - if (Q931IsIEPresent(pMes->NetFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_NETWORK_SPECIFIC_FACILITIES](pTrunk, Q931GetIEPtr(pMes->NetFac,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Date/Time */ - if (Q931IsIEPresent(pMes->DateTime)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DATETIME](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Keypad Facility */ - if (Q931IsIEPresent(pMes->KeypadFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_KEYPAD_FACILITY](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Calling Party Number */ - if (Q931IsIEPresent(pMes->CallingNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CallingNum,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Calling Party Subaddress */ - if (Q931IsIEPresent(pMes->CallingSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CallingSub,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Called Party number */ - if (Q931IsIEPresent(pMes->CalledNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Called party subaddress */ - if (Q931IsIEPresent(pMes->CalledSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CalledSub,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Transit network selection */ - if (Q931IsIEPresent(pMes->TransNetSel)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_TRANSIT_NETWORK_SELECTION](pTrunk, Q931GetIEPtr(pMes->TransNetSel,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->LLRepeatInd)) { - rc = Q931E_UNKNOWN_IE;/* TODO */ - } - - /* Low Layer Compatibility */ - if (Q931IsIEPresent(pMes->LLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_LOW_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_SetupAck - -*****************************************************************************/ -L3INT Q931Umes_SetupAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_DISPLAY: - case Q931ie_SIGNAL: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_SetupAck - -*****************************************************************************/ -L3INT Q931Pmes_SetupAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Status - -*****************************************************************************/ -L3INT Q931Umes_Status(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CAUSE: - case Q931ie_CALL_STATE: - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - - -/***************************************************************************** - - Function: Q931Pmes_Status - -*****************************************************************************/ -L3INT Q931Pmes_Status(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Cause */ - if (Q931IsIEPresent(pMes->Cause)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CAUSE](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Call State */ - if (Q931IsIEPresent(pMes->CallState)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALL_STATE](pTrunk, Q931GetIEPtr(pMes->CallState,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_StatusEnquiry - -*****************************************************************************/ -L3INT Q931Umes_StatusEnquiry(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_StatusEnquiry - -*****************************************************************************/ -L3INT Q931Pmes_StatusEnquiry(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_Suspend - -*****************************************************************************/ -L3INT Q931Umes_Suspend(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CALL_IDENTITY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Suspend - -*****************************************************************************/ -L3INT Q931Pmes_Suspend(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Call Identity */ - if (Q931IsIEPresent(pMes->CallID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALL_IDENTITY](pTrunk, Q931GetIEPtr(pMes->CallID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_SuspendAck - -*****************************************************************************/ -L3INT Q931Umes_SuspendAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_SuspendAck - -*****************************************************************************/ -L3INT Q931Pmes_SuspendAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_SuspendReject - -*****************************************************************************/ -L3INT Q931Umes_SuspendReject(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CAUSE: - case Q931ie_DISPLAY: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_SuspendReject - -*****************************************************************************/ -L3INT Q931Pmes_SuspendReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Cause */ - if (Q931IsIEPresent(pMes->Cause)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CAUSE](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_UserInformation - -*****************************************************************************/ -L3INT Q931Umes_UserInformation(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT I, L3INT O) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(mes); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q931Pmes_UserInformation - -*****************************************************************************/ -L3INT Q931Pmes_UserInformation(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - *OSize = 0; - - return RetCode; -} - -/***************************************************************************** - - Function: Q931Umes_Service - -*****************************************************************************/ -L3INT Q931Umes_Service(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CHANNEL_IDENTIFICATION: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - case Q931ie_CHANGE_STATUS: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Service - -*****************************************************************************/ -L3INT Q931Pmes_Service(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Display */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - if (Q931IsIEPresent(pMes->ChangeStatus)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANGE_STATUS](pTrunk, Q931GetIEPtr(pMes->ChangeStatus,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} - -/***************************************************************************** - - Function: Q931Umes_ServiceAck - -*****************************************************************************/ -L3INT Q931Umes_ServiceAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - - while (IOff < Size) { - switch (IBuf[IOff]) { - case Q931ie_CHANNEL_IDENTIFICATION: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - case Q931ie_CHANGE_STATUS: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_ServiceAck - -*****************************************************************************/ -L3INT Q931Pmes_ServiceAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT rc = Q931E_NO_ERROR; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - if (Q931IsIEPresent(pMes->ChangeStatus)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANGE_STATUS](pTrunk, Q931GetIEPtr(pMes->ChangeStatus,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} diff --git a/libs/freetdm/src/isdn/Q932mes.c b/libs/freetdm/src/isdn/Q932mes.c deleted file mode 100644 index 574499a241..0000000000 --- a/libs/freetdm/src/isdn/Q932mes.c +++ /dev/null @@ -1,286 +0,0 @@ -/***************************************************************************** - - FileName: Q932mes.c - - Contents: Q.932 Message Encoders/Decoders - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "Q931.h" - -/***************************************************************************** - - Function: Q932Umes_Facility - -*****************************************************************************/ - -L3INT Q932Umes_Facility(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Facility - -*****************************************************************************/ -L3INT Q932Pmes_Facility(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q932Umes_Hold - -*****************************************************************************/ - -L3INT Q932Umes_Hold(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Hold - -*****************************************************************************/ -L3INT Q932Pmes_Hold(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q932Umes_HoldAck - -*****************************************************************************/ - -L3INT Q932Umes_HoldAck(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_HoldAck - -*****************************************************************************/ -L3INT Q932Pmes_HoldAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q932Umes_HoldReject - -*****************************************************************************/ - -L3INT Q932Umes_HoldReject(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_HoldReject - -*****************************************************************************/ -L3INT Q932Pmes_HoldReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q932Umes_Register - -*****************************************************************************/ - -L3INT Q932Umes_Register(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Register - -*****************************************************************************/ -L3INT Q932Pmes_Register(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q932Umes_Retrieve - -*****************************************************************************/ - -L3INT Q932Umes_Retrieve(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_Retrieve - -*****************************************************************************/ -L3INT Q932Pmes_Retrieve(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q932Umes_RetrieveAck - -*****************************************************************************/ - -L3INT Q932Umes_RetrieveAck(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_RetrieveAck - -*****************************************************************************/ -L3INT Q932Pmes_RetrieveAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} - -/***************************************************************************** - - Function: Q932Umes_RetrieveReject - -*****************************************************************************/ - -L3INT Q932Umes_RetrieveReject(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT OOff = 0; - - /* TODO */ - - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: Q931Pmes_RetrieveReject - -*****************************************************************************/ -L3INT Q932Pmes_RetrieveReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3BOOL RetCode = L3FALSE; - - NoWarning(OBuf); - NoWarning(IBuf); - - return RetCode; -} diff --git a/libs/freetdm/src/isdn/include/5ESS.h b/libs/freetdm/src/isdn/include/5ESS.h deleted file mode 100644 index 882b257395..0000000000 --- a/libs/freetdm/src/isdn/include/5ESS.h +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** - - FileName: 5ESS.h - - Contents: Header and definition for the AT&T 5ESS ISDN dialect. The - header contains the following parts: - - - Definition of codes - - Definition of information elements (5ESSie_). - - Definition of messages (5ESSmes_). - - Function prototypes. - - Description: The AT&T 5ESS ISDN dialect here covers ???? - - Related Files: 5ESS.h AT&T 5ESS ISDN Definitions - 5ESSie.c AT&T 5ESS ISDN IE encoders/coders (not extant yet) - See Q931ie.c for IE encoders/coders - 5ESSStateTE.c AT&T 5ESS ISDN TE State Engine - 5ESSStateNT.c AT&T 5ESS ISDN NT State Engine - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Copyright (c) 2007, Michael S. Collins, All rights reserved. - email:mcollins@fcnetwork.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -******************************************************************************/ - -#ifndef _5ESS_NL -#define _5ESS_NL - -#include "Q931.h" - -/***************************************************************************** - - Q.931 Message codes - Only 5ESS specific message and ie types - here the rest are inherited from Q931.h - -*****************************************************************************/ - - -/***************************************************************************** - - Q.931 Message Pack/Unpack functions. Implemented in 5ESSmes.c - Note: Because C variables may not begin with numeric digit, all identifiers - are prefixed with "ATT5ESS" instead of a bare "5ESS" - -*****************************************************************************/ -L3INT ATT5ESSUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); -L3INT ATT5ESSPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT ATT5ESSUmes_SetupAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); -L3INT ATT5ESSPmes_SetupAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); - -L3INT ATT5ESSUmes_0x07(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); -L3INT ATT5ESSPmes_0x07(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT ATT5ESSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); -L3INT ATT5ESSPmes_0x0f(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); - - - -/***************************************************************************** - - Q.931 Process Function Prototyping. Implemented in 5ESSStateTE.c - -*****************************************************************************/ -L3INT ATT5ESSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom); -L3INT ATT5ESSProc0x07TE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom); - - -void ATT5ESSCreateTE(L3UCHAR i); -void ATT5ESSCreateNT(L3UCHAR i); - -#endif /* _5ESS_NL */ diff --git a/libs/freetdm/src/isdn/include/DMS.h b/libs/freetdm/src/isdn/include/DMS.h deleted file mode 100644 index 605a61aa6e..0000000000 --- a/libs/freetdm/src/isdn/include/DMS.h +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************** - - FileName: national.h - - Contents: Header and definition for the National ISDN dialect. The - header contents the following parts: - - Definition of codes - - Definition of information elements (nationalie_). - - Definition of messages (nationalmes_). - - Function prototypes. - - Description: The National ISDN dialect here covers ???? - - Related Files: national.h National ISDN Definitions - nationalie.c National ISDN IE encoders/coders - nationalStateTE.c National ISDN TE State Engine - nationalStateNT.c National ISDN NT State Engine - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -******************************************************************************/ - -#ifndef _DMS_NL -#define _DMS_NL - -#include "Q931.h" - -/***************************************************************************** - - Q.931 Message codes - Only National specific message and ie types - here the rest are inherited from national.h - -*****************************************************************************/ - - -/***************************************************************************** - - Q.931 Message Pack/Unpack functions. Implemented in nationalmes.c - -*****************************************************************************/ -L3INT DMSUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); -L3INT DMSPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT DMSUmes_0x07(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); -L3INT DMSPmes_0x07(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT DMSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); -L3INT DMSPmes_0x0f(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); - -/***************************************************************************** - - Q.931 Process Function Prototyping. Implemented in nationalStateTE.c - -*****************************************************************************/ - -L3INT DMSProc0x0fTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom); -L3INT DMSProc0x07TE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * buf, L3INT iFrom); - -void DMSCreateTE(L3UCHAR i); -void DMSCreateNT(L3UCHAR i); - -#endif /* _DMS_NL */ diff --git a/libs/freetdm/src/isdn/include/Q921.h b/libs/freetdm/src/isdn/include/Q921.h deleted file mode 100644 index cb21a157ea..0000000000 --- a/libs/freetdm/src/isdn/include/Q921.h +++ /dev/null @@ -1,227 +0,0 @@ -/***************************************************************************** - - FileName: q921.h - - Description: Contains headers of a Q.921 protocol. - - Note: This header file is the only include file that should be - acessed by users of the Q.921 stack. - - Interface: The Q.921 stack contains 2 layers. - - - One interface layer. - - One driver layer. - - The interface layer contains the interface functions required - for a layer 2 stack to be able to send and receive messages. - - The driver layer will simply feed bytes into the ship as - required and queue messages received out from the ship. - - Q921TimeTick The Q.921 like any other blackbox - modules contains no thread by it's own - and must therefore be called regularly - by an external 'thread' to do maintenance - etc. - - Q921Rx32 Receive message from layer 3. Called by - the layer 3 stack to send a message. - - - NOTE: The following are not yet implemented - - OnQ921Error Function called every if an error is - detected. - - OnQ921Log Function called if logging is active. - - - Maintenance/Configuration interface - Logging - DL_ message passing to layer 3 - Timers - Api commands to tell 921 to stop and start for a trunk - - Created: 27.dec.2000/JVB - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*****************************************************************************/ - -/**************************************************************************** - * Changes: - * - * - June,July 2008: Stefan Knoblich : - * Add PTMP TEI management - * Add timers - * Add retransmit counters - * Add logging - * Various cleanups - * - ****************************************************************************/ - -#ifndef _Q921 -#define _Q921 - -#define Q921MAXHDLCSPACE 3000 -#define L2UCHAR unsigned char /* Min 8 bit */ -#define L2USHORT unsigned short /* 16 bit */ -#define L2INT int /* Min 16 bit signed */ -#define L2ULONG unsigned long /* Min 32 bit */ -#define L2TRUNK Q921Data_t * - -#define Q921_TEI_BCAST 127 -#define Q921_TEI_MAX Q921_TEI_BCAST - -#define Q921_TEI_DYN_MIN 64 -#define Q921_TEI_DYN_MAX 126 - - -typedef enum /* Network/User Mode */ -{ - Q921_TE=0, /* 0 : User Mode */ - Q921_NT=1 /* 1 : Network Mode */ -} Q921NetUser_t; - -typedef enum /* Type of connection */ -{ - Q921_PTP=0, /* 0 : Point-To-Point */ - Q921_PTMP=1 /* 1 : Point-To-Multipoint */ -} Q921NetType_t; - -typedef enum -{ - Q921_LOG_NONE = -1, - Q921_LOG_EMERG = 0, - Q921_LOG_ALERT, - Q921_LOG_CRIT, - Q921_LOG_ERROR, - Q921_LOG_WARNING, - Q921_LOG_NOTICE, - Q921_LOG_INFO, - Q921_LOG_DEBUG -} Q921LogLevel_t; - - -/* - * Messages for L2 <-> L3 communication - */ -typedef enum { - Q921_DL_ESTABLISH = 0, - Q921_DL_ESTABLISH_CONFIRM, - Q921_DL_RELEASE, - Q921_DL_RELEASE_CONFIRM, - Q921_DL_DATA, - Q921_DL_UNIT_DATA -} Q921DLMsg_t; - -typedef int (*Q921Tx21CB_t) (void *, L2UCHAR *, L2INT); -typedef int (*Q921Tx23CB_t) (void *, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *, L2INT); -typedef int (*Q921LogCB_t) (void *, Q921LogLevel_t, char *, L2INT); - -struct Q921_Link; - -typedef struct Q921Data -{ - L2INT initialized; - - L2UCHAR sapi; /*!< User assigned SAPI */ - L2UCHAR tei; /*!< User assigned TEI value */ - - L2INT Q921HeaderSpace; - Q921NetUser_t NetUser; - Q921NetType_t NetType; - - struct Q921_Link *context; /*!< per-TEI / link context space */ - - /* timers */ - L2ULONG T202; /*!< PTMP TE mode TEI retransmit timer */ - L2ULONG T200Timeout; - L2ULONG T201Timeout; - L2ULONG T202Timeout; - L2ULONG T203Timeout; - - L2ULONG TM01Timeout; - - /* counters */ - L2ULONG N200Limit; /*!< max retransmit */ - - L2ULONG N202; /*!< PTMP TE mode retransmit counter */ - L2ULONG N202Limit; /*!< PTMP TE mode max retransmit */ - - L2ULONG N201Limit; /*!< max number of octets */ - L2ULONG k; /*!< max number of unacknowledged I frames */ - - /* callbacks and callback data pointers */ - Q921Tx21CB_t Q921Tx21Proc; - Q921Tx23CB_t Q921Tx23Proc; - void *PrivateData21; - void *PrivateData23; - - /* logging */ - Q921LogLevel_t loglevel; /*!< trunk loglevel */ - Q921LogCB_t Q921LogProc; /*!< log callback procedure */ - void *PrivateDataLog; /*!< private data pointer for log proc */ - - /* tei mgmt */ - L2UCHAR tei_map[Q921_TEI_MAX]; /*!< */ - - L2UCHAR HDLCInQueue[Q921MAXHDLCSPACE]; /*!< HDLC input queue */ -} Q921Data_t; - -/* - * Public functions - */ -int Q921_InitTrunk(L2TRUNK trunk, - L2UCHAR sapi, - L2UCHAR tei, - Q921NetUser_t NetUser, - Q921NetType_t NetType, - L2INT hsize, - Q921Tx21CB_t cb21, - Q921Tx23CB_t cb23, - void *priv21, - void *priv23); -int Q921Start(L2TRUNK trunk); -int Q921Stop(L2TRUNK trunk); - -void Q921SetLogCB(L2TRUNK trunk, Q921LogCB_t func, void *priv); -void Q921SetLogLevel(L2TRUNK trunk, Q921LogLevel_t level); - -int Q921Rx12(L2TRUNK trunk); -int Q921Rx32(L2TRUNK trunk, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR * Mes, L2INT Size); - -int Q921QueueHDLCFrame(L2TRUNK trunk, L2UCHAR *b, L2INT size); - -void Q921SetGetTimeCB(L2ULONG (*callback)(void)); -void Q921TimerTick(L2TRUNK trunk); - -#endif diff --git a/libs/freetdm/src/isdn/include/Q921priv.h b/libs/freetdm/src/isdn/include/Q921priv.h deleted file mode 100644 index d2d838c399..0000000000 --- a/libs/freetdm/src/isdn/include/Q921priv.h +++ /dev/null @@ -1,321 +0,0 @@ -/***************************************************************************** - - FileName: Q921priv.h - - Description: Private declarations - - Created: 08.Aug.2008/STKN - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2008, Stefan Knoblich, axsentis GmbH. All rights reserved. - email:s.knoblich@axsentis.de - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*****************************************************************************/ -#ifndef _Q921_PRIV_H_ -#define _Q921_PRIV_H_ - -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif -#if (_MSC_VER >= 1400) /* VC8+ */ -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE -#endif -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE -#endif -#endif -#ifndef strcasecmp -#define strcasecmp(s1, s2) _stricmp(s1, s2) -#endif -#ifndef strncasecmp -#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) -#endif -#ifndef snprintf -#define snprintf _snprintf -#endif -#endif - -typedef enum /* Q.921 States */ -{ - Q921_STATE_STOPPED = 0, /* Trunk stopped */ - Q921_STATE_TEI_UNASSIGNED = 1, /* TEI unassigned */ - Q921_STATE_TEI_AWAITING, /* Assign awaiting TEI */ - Q921_STATE_TEI_ESTABLISH, /* Establish awaiting TEI */ - Q921_STATE_TEI_ASSIGNED, /* TEI assigned */ - Q921_STATE_AWAITING_ESTABLISHMENT, /* Awaiting establishment */ - Q921_STATE_AWAITING_RELEASE, /* Awaiting release */ - Q921_STATE_MULTIPLE_FRAME_ESTABLISHED, /* Multiple frame established */ - Q921_STATE_TIMER_RECOVERY /* Timer recovery */ -} Q921State_t; - -/* - * Flags - */ -enum Q921_Flags { - Q921_FLAG_L3_INITIATED = (1 << 0), - - Q921_FLAG_UI_FRAME_QUEUED = (1 << 1), - Q921_FLAG_I_FRAME_QUEUED = (1 << 2), - - Q921_FLAG_ACK_PENDING = (1 << 3), - Q921_FLAG_REJECT = (1 << 4), - - Q921_FLAG_RECV_BUSY = (1 << 5), - Q921_FLAG_PEER_RECV_BUSY = (1 << 6) -}; - -#define Q921_SET_FLAG(x, f) ((x)->flags |= f) -#define Q921_CHECK_FLAG(x, f) ((x)->flags & f) -#define Q921_CLEAR_FLAG(x, f) ((x)->flags &= ~f) - - -/* - * dynamic TEI handling - */ -#define Q921_SAPI_TEI 63 /* SAPI for all TEI Messages */ -#define Q921_LAYER_ENT_ID_TEI 0x0f /* UN Layer Management Entity ID for TEI Mgmt */ -#define Q921_LAYER_ENT_ID_Q931 0x08 /* Q.931 Layer Management Entity ID */ - - -typedef enum { - Q921_TEI_ID_REQUEST = 1, - Q921_TEI_ID_ASSIGNED, - Q921_TEI_ID_DENIED, - Q921_TEI_ID_CHECKREQ, - Q921_TEI_ID_CHECKRESP, - Q921_TEI_ID_REMOVE, - Q921_TEI_ID_VERIFY -} Q921TeiMessageType_t; - - -/** - * Per-Datalink context - */ -struct Q921_Link { - L2UCHAR tei; /*!< This endpoint's TEI */ - - L2UCHAR va; - L2UCHAR vs; - L2UCHAR vr; - - L2INT flags; - Q921State_t state; - - L2ULONG N202; /*!< PTMP TE mode retransmit counter */ - L2ULONG N200; /*!< retransmit counter (per-TEI in PTMP NT mode) */ - - L2ULONG TM01; /*!< Datalink inactivity disconnect timer */ - - L2ULONG T200; - L2ULONG T201; /*!< PTMP NT mode timer */ - L2ULONG T203; - - L2USHORT ri; /*!< random id for TEI request mgmt */ - - /* I + UI Frame queue */ - L2UCHAR UIFrameQueue[Q921MAXHDLCSPACE]; - L2UCHAR IFrameQueue[Q921MAXHDLCSPACE]; - L2UCHAR IFrameResendQueue[Q921MAXHDLCSPACE]; -}; - - -#define Q921_LINK_CONTEXT(tr, tei) \ - (Q921_IS_PTMP_NT(tr) && tei != Q921_TEI_BCAST) ? ((struct Q921_Link *)&(tr)->context[tei]) : (tr)->context - -#define Q921_TRUNK_CONTEXT(tr) \ - (tr)->context - -#define Q921_LOGBUFSIZE 2000 -#define INITIALIZED_MAGIC 42 - -/* - * Helper macros - */ -#define Q921_INC_COUNTER(x) (x = (x + 1) % 128) -#define Q921_DEC_COUNTER(x) (x = (x) ? (x - 1) : 127) - -#define Q921_UFRAME_HEADER_SIZE 3 -#define Q921_UFRAME_DATA_OFFSET(tr) ((tr)->Q921HeaderSpace + Q921_UFRAME_HEADER_SIZE) - -#define Q921_SFRAME_HEADER_SIZE 4 -#define Q921_SFRAME_DATA_OFFSET(tr) ((tr)->Q921HeaderSpace + Q921_SFRAME_HEADER_SIZE) - -#define Q921_IFRAME_HEADER_SIZE 4 -#define Q921_IFRAME_DATA_OFFSET(tr) ((tr)->Q921HeaderSpace + Q921_IFRAME_HEADER_SIZE) - -#define Q921_IS_TE(x) ((x)->NetUser == Q921_TE) -#define Q921_IS_NT(x) ((x)->NetUser == Q921_NT) - -#define Q921_IS_STOPPED(tr) ((tr)->state == Q921_STATE_STOPPED) - -/* TODO: rework this one */ -#define Q921_IS_READY(tr) ((tr)->state >= Q921_STATE_TEI_ASSIGNED) - -#define Q921_IS_PTMP(x) ((x)->NetType == Q921_PTMP) -#define Q921_IS_PTMP_TE(x) ((x)->NetType == Q921_PTMP && (x)->NetUser == Q921_TE) -#define Q921_IS_PTMP_NT(x) ((x)->NetType == Q921_PTMP && (x)->NetUser == Q921_NT) - -#define Q921_IS_PTP(x) ((x)->NetType == Q921_PTP) -#define Q921_IS_PTP_TE(x) ((x)->NetType == Q921_PTP && (x)->NetUser == Q921_TE) -#define Q921_IS_PTP_NT(x) ((x)->NetType == Q921_PTP && (x)->NetUser == Q921_NT) - -/* Make life a little easier */ -#define Q921_COMMAND(x) ((x)->NetUser == Q921_TE ? 0 : 1) -#define Q921_RESPONSE(x) ((x)->NetUser == Q921_TE ? 1 : 0) - -#define Q921_IS_COMMAND(tr, x) ((x) == (Q921_IS_TE(tr) ? 1 : 0)) -#define Q921_IS_RESPONSE(tr, x) ((x) == (Q921_IS_TE(tr) ? 0 : 1)) - - -/******************************************************************************* - * Private functions - *******************************************************************************/ - -/* - * L1 / L2 Interface - */ -static int Q921Tx21Proc(L2TRUNK trunk, L2UCHAR *Msg, L2INT size); -static int Q921Tx23Proc(L2TRUNK trunk, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *Msg, L2INT size); - - -/* - * Timers - */ -static L2ULONG Q921GetTime(void); - -static void Q921T200TimerStart(L2TRUNK trunk, L2UCHAR tei); -static void Q921T200TimerStop(L2TRUNK trunk, L2UCHAR tei); -static void Q921T200TimerReset(L2TRUNK trunk, L2UCHAR tei); -static void Q921T200TimerExpire(L2TRUNK trunk, L2UCHAR tei); - -static void Q921T201TimerStart(L2TRUNK trunk, L2UCHAR tei); -static void Q921T201TimerStop(L2TRUNK trunk, L2UCHAR tei); -/* static void Q921T201TimerReset(L2TRUNK trunk, L2UCHAR tei); - Unused for now */ -static void Q921T201TimerExpire(L2TRUNK trunk, L2UCHAR tei); - -static void Q921T202TimerStart(L2TRUNK trunk); -static void Q921T202TimerStop(L2TRUNK trunk); -static void Q921T202TimerReset(L2TRUNK trunk); -static void Q921T202TimerExpire(L2TRUNK trunk); - -static void Q921T203TimerStart(L2TRUNK trunk, L2UCHAR tei); -static void Q921T203TimerStop(L2TRUNK trunk, L2UCHAR tei); -static void Q921T203TimerReset(L2TRUNK trunk, L2UCHAR tei); -static void Q921T203TimerExpire(L2TRUNK trunk, L2UCHAR tei); - -static void Q921TM01TimerStart(L2TRUNK trunk, L2UCHAR tei); -/* static void Q921TM01TimerStop(L2TRUNK trunk, L2UCHAR tei); - Unused for now */ -static void Q921TM01TimerReset(L2TRUNK trunk, L2UCHAR tei); -/* static void Q921TM01TimerExpire(L2TRUNK trunk, L2UCHAR tei); - Unused for now */ - -/* - * Frame encoding - */ -static int Q921SendS(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR sv, L2UCHAR *mes, L2INT size); -static int Q921SendU(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR m, L2UCHAR *mes, L2INT size); - -static int Q921SendRNR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf); -static int Q921SendREJ(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf); -static int Q921SendSABME(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf); -static int Q921SendDM(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf); -static int Q921SendDISC(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf); -static int Q921SendUA(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf); -static int Q921SendUN(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf, L2UCHAR *mes, L2INT size); -static int Q921SendRR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf); - -/* - * Frame decoding - */ -static int Q921ProcIFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcSFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcUFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size); - -static int Q921ProcSABME(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcDM(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcUA(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcDISC(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcRR(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcRNR(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921ProcREJ(L2TRUNK trunk, L2UCHAR *mes, L2INT size); - - -/* - * (Common) procedures defined in the Q.921 SDL - */ -static int Q921SendEnquiry(L2TRUNK trunk, L2UCHAR tei); -static int Q921SendEnquiryResponse(L2TRUNK trunk, L2UCHAR tei); -static void Q921ResetExceptionConditions(L2TRUNK trunk, L2UCHAR tei); -static int Q921EstablishDataLink(L2TRUNK trunk, L2UCHAR tei); -static int Q921NrErrorRecovery(L2TRUNK trunk, L2UCHAR tei); -static int Q921InvokeRetransmission(L2TRUNK trunk, L2UCHAR tei, L2UCHAR nr); -static int Q921AcknowledgePending(L2TRUNK trunk, L2UCHAR tei); -/* -static int Q921SetReceiverBusy(L2TRUNK trunk); -static int Q921ClearReceiverBusy(L2TRUNK trunk); -*/ - -/* - * Queueing - */ -static int Q921SendQueuedIFrame(L2TRUNK trunk, L2UCHAR tei); -static int Q921EnqueueI(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR *mes, L2INT size); - -/* - * TEI management - */ -static int Q921TeiSendAssignRequest(L2TRUNK trunk); -static int Q921TeiProcAssignResponse(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921TeiSendVerifyRequest(L2TRUNK trunk); -static int Q921TeiProcCheckRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921TeiProcRemoveRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921TeiProcAssignRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921TeiProcCheckResponse(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921TeiProcVerifyRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size); -static int Q921TeiSendRemoveRequest(L2TRUNK trunk, L2UCHAR tei); -static int Q921TeiSendDenyResponse(L2TRUNK trunk, L2UCHAR tei, L2USHORT ri); -static int Q921TeiSendAssignedResponse(L2TRUNK trunk, L2UCHAR tei, L2USHORT ri); -static int Q921TeiSendCheckRequest(L2TRUNK trunk, L2UCHAR tei); - -/* - * Logging - */ -static int Q921Log(L2TRUNK trunk, Q921LogLevel_t level, const char *fmt, ...); -static int Q921LogMesg(L2TRUNK trunk, Q921LogLevel_t level, L2UCHAR received, L2UCHAR *mes, L2INT size, const char *fmt, ...); - -/* - * State handling - */ -static int Q921ChangeState(L2TRUNK trunk, Q921State_t state, L2UCHAR tei); - -#endif diff --git a/libs/freetdm/src/isdn/include/Q931.h b/libs/freetdm/src/isdn/include/Q931.h deleted file mode 100644 index 0dbafd9f11..0000000000 --- a/libs/freetdm/src/isdn/include/Q931.h +++ /dev/null @@ -1,1175 +0,0 @@ -/****************************************************************************** - - FileName: Q931.h - - Contents: Header and definition for the ITU-T Q.931 stack. The - header contents the following parts: - - - Definition of codes - - Definition of information elements (Q931ie_). - - Definition of messages (Q931mes_). - - Definitian of variables (var_). - - Function prototypes. - - Description: The Q.931 stack provided here covers ITU-T Q.931 w/Q.932 - supplementary services for both PRI, BRI and variants. - The stack is generic and designed to deal with variants as - needed. - - The stack uses the following interface functions: - - - Q931Initialize Initialize the Q.931 stack. - - Q931Rx23 Receive a message from layer 2 - - Q931Tx32 Send a message to layer 2 - - Q931Rx43 Receive a message from layer 4 or above. - - Q931Tx34 Send a message to layer 4 or above. - - Q931TimeTick Periodical timer processing. - - Q931ErrorProc Callback for stack error message. - - The protocol is a module with no external dependencies and - can easely be ported to any operating system like Windows, - Linux, rtos and others. - - Related Files: Q931.h Q.931 Definitions - Q931.c Q.931 Interface Functions. - Q931api.c Low level L4 API functions. - - Q932.h Q.932 Suplementary Services - Q932mes.c Q.932 encoders/coders - - Q931mes.c Q.931 Message encoders/coders - Q931ie.c Q.931 IE encoders/coders - Q931StateTE.c Generic Q.931 TE State Engine - Q931StateNT.c Generic Q.931 NT State Engine - - Design Note 1: For each variant please add separate files starting with - the variant short-name as follows: - - .h Spesific headers needed. - mes.c Message encoders/decores. - ie.c IE encoders/decoders. - StateTE.c TE side state engine. - StateNT.c NT side state engine. - - Design Note 2: The stack is deliberatly made non-threading. Use 1 - thread per Trunk, but lock access from the timertick - and rx, tx functions. And make sure the callbacks only - dump messages to a queue, no time-consuming processing - inside stack processing. - - All stack processing is async 'fire and forget', meaning - that there are not, and should not be any time-consuming - processing within the stack-time. The best way to thread - a stack is to use one single thread that signal 5 queues. - - - Incoming L2 queue. - - Incoming L4 queue. - - Outgoing L2 queue. - - Outgoing L4 queue. - - Error/Trace queue. - - Design Note 3: DSP optimization. The L3 (Rx23) can be called directly - from a HDLC receiver without usage of queues for optimized - processing. But keep in mind that Q.931 calls Tx34 or Tx32 - as part of receiving a message from Layer 2. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -******************************************************************************/ - -#ifndef _Q931_NL -#define _Q931_NL - -/* uncomment the #define below to add x.25 support to the Q.931 */ -/* #define Q931_X25_SUPPORT */ - -#include "stdio.h" - -#ifdef _MSC_VER -#pragma warning(disable:4100) -#ifndef strcasecmp -#define strcasecmp(s1, s2) _stricmp(s1, s2) -#endif -#endif -#include - - -/***************************************************************************** - - Enum helper macros - -*****************************************************************************/ -#define Q931_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL }; -#define Q931_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) _TYPE _FUNC1 (const char *name); const char * _FUNC2 (_TYPE type); -#define Q931_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \ - _TYPE _FUNC1 (const char *name) \ - { \ - int i; \ - _TYPE t = _MAX ; \ - \ - for (i = 0; i < _MAX ; i++) { \ - if (!strcasecmp(name, _STRINGS[i])) { \ - t = (_TYPE) i; \ - break; \ - } \ - } \ - \ - return t; \ - } \ - const char * _FUNC2 (_TYPE type) \ - { \ - if (type > _MAX) { \ - type = _MAX; \ - } \ - return _STRINGS[(int)type]; \ - } \ - -/***************************************************************************** - - Error Codes - -*****************************************************************************/ -typedef enum { - Q931E_NO_ERROR = 0, - - Q931E_UNKNOWN_MESSAGE = -3001, - Q931E_ILLEGAL_IE = -3002, - Q931E_UNKNOWN_IE = -3003, - Q931E_BEARERCAP = -3004, - Q931E_HLCOMP = -3005, - Q931E_LLCOMP = -3006, - Q931E_INTERNAL = -3007, - Q931E_MISSING_CB = -3008, - Q931E_UNEXPECTED_MESSAGE = -3009, - Q931E_ILLEGAL_MESSAGE = -3010, - Q931E_TOMANYCALLS = -3011, - Q931E_INVALID_CRV = -3012, - Q931E_CALLID = -3013, - Q931E_CALLSTATE = -3014, - Q931E_CALLEDSUB = -3015, - Q931E_CALLEDNUM = -3016, - Q931E_CALLINGNUM = -3017, - Q931E_CALLINGSUB = -3018, - Q931E_CAUSE = -3019, - Q931E_CHANID = -3020, - Q931E_DATETIME = -3021, - Q931E_DISPLAY = -3022, - Q931E_KEYPADFAC = -3023, - Q931E_NETFAC = -3024, - Q931E_NOTIFIND = -3025, - Q931E_PROGIND = -3026, - Q931E_RESTARTIND = -3027, - Q931E_SEGMENT = -3028, - Q931E_SIGNAL = -3029, - Q931E_GENERIC_DIGITS = -3030 -} q931_error_t; - -/* The q931_error_t enum should be kept in sync with the q931_error_names array in Q931.c */ - -const char *q931_error_to_name(q931_error_t error); - -/***************************************************************************** - - Some speed optimization can be achieved by changing all variables to the - word size of your processor. A 32 bit processor has to do a lot of extra - work to read a packed 8 bit integer. Changing all fields to 32 bit integer - will result in usage of some extra space, but will speed up the stack. - - The stack has been designed to allow L3UCHAR etc. to be any size of 8 bit - or larger. - -*****************************************************************************/ - -#define L3UCHAR unsigned char /* Min 8 bit */ -#define L3USHORT unsigned short /* Min 16 bit unsigned */ -#define L3UINT unsigned int /* Min 16 bit unsigned */ -#define L3INT int /* Min 16 bit signed */ -#define L3ULONG unsigned long /* Min 32 bit */ -#define L3BOOL char /* Min 1 bit, valuse 0 & 1 only */ - -#define L3TRUE 1 -#define L3FALSE 0 - -/***************************************************************************** - - Global defines. - -*****************************************************************************/ - -typedef L3USHORT ie; /* Special data type to hold a dynamic */ - /* or optional information element as */ - /* part of a message struct. MSB = 1 */ - /* indicate that the ie is present, the */ - /* last 15 bits is an offset ( or the */ - /* value for single octet ) to the */ - /* struct holding the ie. Offset = 0 */ - /* is buf[1] etc. */ - /* ie == 0xffff indicates error */ - -/***************************************************************************** - - MAXTRUNKS sets how many physical trunks this system might have. This - number should be keept at a minimum since it will use global space. - - It is recommended that you leave MAXCHPERTRUNK as is - -*****************************************************************************/ - -#define Q931_LOGBUFSIZE 1024 /* size of logging buffer */ - -#define Q931L4BUF 1000 /* size of message buffer */ - -#define Q931L2BUF 300 /* size of message buffer */ - -#define Q931MAXTRUNKS 4 /* Total number of trunks that will be */ - /* processed by this instance of the */ - /* stack */ - -#define Q931MAXCHPERTRUNK 32 /* Number of channels per trunk. The */ - /* stack uses a static set of 32 */ - /* channels regardless if it is E1, T1 */ - /* or BRI that actually is used. */ - -#define Q931MAXCALLPERTRUNK (Q931MAXCHPERTRUNK * 2) - /* Number of max active CRV per trunk. */ - /* Q.931 can have more calls than there */ - /* are channels. */ - - -#define Q931_IS_BRI(x) ((x)->TrunkType == Q931_TrType_BRI || (x)->TrunkType == Q931_TrType_BRI_PTMP) -#define Q931_IS_PRI(x) (!Q931_IS_BRI(x)) - -#define Q931_IS_PTP(x) ((x)->TrunkType != Q931_TrType_BRI_PTMP) -#define Q931_IS_PTMP(X) ((x)->TrunkType == Q931_TrType_BRI_PTMP) - -#define Q931_BRI_MAX_CRV 127 -#define Q931_PRI_MAX_CRV 32767 - -/***************************************************************************** - - The following defines control the dialect switch tables and should only be - changed when a new dialect needs to be inserted into the stack. - - This stack uses an array of functions to know which function to call as - it receives a SETUP message etc. A new dialect can when choose to use - the proc etc. for standard Q.931 or insert a modified proc. - - This technique has also been used to distinguish between user and network - mode to make the code as easy to read and maintainable as possible. - - A message and IE index have been used to save space. These indexes allowes - the message or IE code to be used directly and will give back a new index - into the table. - -*****************************************************************************/ - -/* WARNING! Initialize Q931CreateDialectCB[] will NULL when increasing the */ -/* Q931MAXDLCT value to avoid Q931Initialize from crashing if one entry is */ -/* not used. */ -#define Q931MAXDLCT 8 /* Max dialects included in this */ - /* compile. User and Network count as */ - /* one dialect each. */ - -#define Q931MAXMES 128 /* Number of messages */ -#define Q931MAXIE 255 /* Number of IE */ -#define Q931MAXUSEDIE 50 /* Maximum number of ie types per Dialect */ -#define Q931MAXCODESETS 7 /* Maximum number of codests (by spec, 0-7) */ -#define Q931MAXSTATE 100 /* Size of state tables */ -#define Q931MAXTIMER 25 /* Maximum number of timers */ - -/***************************************************************************** - - Call States for ITU-T Q.931 TE (User Mode) - -*****************************************************************************/ - -#define Q931_U0 0 -#define Q931_U1 1 -#define Q931_U2 2 -#define Q931_U3 3 -#define Q931_U4 4 -#define Q931_U6 6 -#define Q931_U7 7 -#define Q931_U8 8 -#define Q931_U9 9 -#define Q931_U10 10 -#define Q931_U11 11 -#define Q931_U12 12 -#define Q931_U15 15 -#define Q931_U17 17 -#define Q931_U19 19 -#define Q931_U25 25 - -/***************************************************************************** - - Call States for ITU-T Q.931 NT (Network Mode) - -*****************************************************************************/ -#define Q931_N0 (0x0100 | 0) -#define Q931_N1 (0x0100 | 1) -#define Q931_N2 (0x0100 | 2) -#define Q931_N3 (0x0100 | 3) -#define Q931_N4 (0x0100 | 4) -#define Q931_N6 (0x0100 | 6) -#define Q931_N7 (0x0100 | 7) -#define Q931_N8 (0x0100 | 8) -#define Q931_N9 (0x0100 | 9) -#define Q931_N10 (0x0100 | 11) -#define Q931_N11 (0x0100 | 11) -#define Q931_N12 (0x0100 | 12) -#define Q931_N15 (0x0100 | 15) -#define Q931_N17 (0x0100 | 17) -#define Q931_N19 (0x0100 | 19) -#define Q931_N22 (0x0100 | 22) -#define Q931_N25 (0x0100 | 25) - -/***************************************************************************** - - Q.931 Message codes - -*****************************************************************************/ - -#define Q931mes_ALERTING 0x01 /* 0000 0001 */ -#define Q931mes_CALL_PROCEEDING 0x02 /* 0000 0010 */ -#define Q931mes_CONNECT 0x07 /* 0000 0111 */ -#define Q931mes_CONNECT_ACKNOWLEDGE 0x0f /* 0000 1111 */ -#define Q931mes_PROGRESS 0x03 /* 0000 0011 */ -#define Q931mes_SETUP 0x05 /* 0000 0101 */ -#define Q931mes_SETUP_ACKNOWLEDGE 0x0d /* 0000 1101 */ -#define Q931mes_RESUME 0x26 /* 0010 0110 */ -#define Q931mes_RESUME_ACKNOWLEDGE 0x2e /* 0010 1110 */ -#define Q931mes_RESUME_REJECT 0x22 /* 0010 0010 */ -#define Q931mes_SUSPEND 0x25 /* 0010 0101 */ -#define Q931mes_SUSPEND_ACKNOWLEDGE 0x2d /* 0010 1101 */ -#define Q931mes_SUSPEND_REJECT 0x21 /* 0010 0001 */ -#define Q931mes_USER_INFORMATION 0x20 /* 0010 0000 */ -#define Q931mes_DISCONNECT 0x45 /* 0100 0101 */ -#define Q931mes_RELEASE 0x4d /* 0100 1101 */ -#define Q931mes_RELEASE_COMPLETE 0x5a /* 0101 1010 */ -#define Q931mes_RESTART 0x46 /* 0100 0110 */ -#define Q931mes_RESTART_ACKNOWLEDGE 0x4e /* 0100 1110 */ -#define Q931mes_CONGESTION_CONTROL 0x79 /* 0111 1001 */ -#define Q931mes_INFORMATION 0x7b /* 0111 1011 */ -#define Q931mes_NOTIFY 0x6e /* 0110 1110 */ -#define Q931mes_STATUS 0x7d /* 0111 1101 */ -#define Q931mes_STATUS_ENQUIRY 0x75 /* 0111 0101 */ -#define Q931mes_SEGMENT 0x60 /* 0110 0000 */ - -#define Q931mes_SERVICE 0x0f /* 0000 1111 */ -#define Q931mes_SERVICE_ACKNOWLEDGE 0x07 /* 0000 0111 */ - - -/** - * Generic Q.931 Timers - */ -enum { - Q931_TIMER_T300 = 1, /* */ - Q931_TIMER_T301, - Q931_TIMER_T302, - Q931_TIMER_T303, - Q931_TIMER_T304, - Q931_TIMER_T305, - Q931_TIMER_T306, - Q931_TIMER_T307, - Q931_TIMER_T308, - Q931_TIMER_T309, - Q931_TIMER_T310, - Q931_TIMER_T311, - Q931_TIMER_T312, - Q931_TIMER_T313, - Q931_TIMER_T314, - Q931_TIMER_T315, - Q931_TIMER_T316, - Q931_TIMER_T317, - Q931_TIMER_T318, - Q931_TIMER_T319, - Q931_TIMER_T320, - Q931_TIMER_T321, - Q931_TIMER_T322, -}; - -/** - * Q.931 ToN - */ -enum { - Q931_TON_UNKNOWN = 0x00, - Q931_TON_INTERNATIONAL = 0x01, - Q931_TON_NATIONAL = 0x02, - Q931_TON_NETWORK_SPECIFIC = 0x03, - Q931_TON_SUBSCRIBER_NUMBER = 0x04, - Q931_TON_ABBREVIATED_NUMBER = 0x06, - Q931_TON_RESERVED = 0x07 -}; - -/** - * Q.931 Numbering Plan - */ -enum { - Q931_NUMPLAN_UNKNOWN = 0x00, - Q931_NUMPLAN_E164 = 0x01, - Q931_NUMPLAN_X121 = 0x03, - Q931_NUMPLAN_F69 = 0x04, - Q931_NUMPLAN_NATIONAL = 0x08, - Q931_NUMPLAN_PRIVATE = 0x09, - Q931_NUMPLAN_RESERVED = 0x0e -}; - -/** - * Q.931 Presentation Indicator - */ -enum { - Q931_PRES_ALLOWED = 0x00, - Q931_PRES_RESTRICTED = 0x01, - Q931_PRES_NOT_AVAILABLE = 0x02, - Q931_PRES_RESERVED = 0x03 -}; - -/** - * Q.931 Screening Indicator - */ -enum { - Q931_SCREEN_USER_NOT_SCREENED = 0x00, - Q931_SCREEN_USER_VERIFIED_PASSED = 0x01, - Q931_SCREEN_USER_VERIFIED_FAILED = 0x02, - Q931_SCREEN_NETWORK = 0x03 -}; - -/** - * Q.931 Coding Standard - */ -enum { - Q931_CODING_ITU = 0x00, - Q931_CODING_ISO = 0x01, - Q931_CODING_NATIONAL = 0x02, - Q931_CODING_NETWORK = 0x03 -}; - -/** - * Q.931 High layer characteristik id - */ -enum { - Q931_HLCHAR_TELEPHONY = 0x01, - Q931_HLCHAR_FAX_G23 = 0x04, - Q931_HLCHAR_FAX_G4 = 0x21, - Q931_HLCHAR_FAX_G4II = 0x24, - Q931_HLCHAR_T102 = 0x32, - Q931_HLCHAR_T101 = 0x33, - Q931_HLCHAR_F60 = 0x35, - Q931_HLCHAR_X400 = 0x38, - Q931_HLCHAR_X200 = 0x41 -}; - -/** - * Q.931 User information layer 1 protocol - */ -enum { - Q931_UIL1P_V110 = 0x01, - Q931_UIL1P_I460 = 0x01, - Q931_UIL1P_X30 = 0x01, - - Q931_UIL1P_G711U = 0x02, - Q931_UIL1P_G711A = 0x03, - Q931_UIL1P_G721 = 0x04, - - Q931_UIL1P_H221 = 0x05, - Q931_UIL1P_H242 = 0x05, - - Q931_UIL1P_H223 = 0x06, - Q931_UIL1P_H245 = 0x06, - - Q931_UIL1P_RATE_ADAP = 0x07, - - Q931_UIL1P_V120 = 0x08, - Q931_UIL1P_X31 = 0x09 -}; - -/** - * Q.931 Information Transfer Capability - */ -enum { - Q931_ITC_SPEECH = 0x00, - Q931_ITC_UNRESTRICTED = 0x08, - Q931_ITC_RESTRICTED = 0x09, - Q931_ITC_3K1_AUDIO = 0x10, - Q931_ITC_UNRESTRICTED_TONES = 0x11, - Q931_ITC_VIDEO = 0x18 -}; - -/** - * Q.931 Information transfer rate - */ -enum { - Q931_ITR_PACKET = 0x00, - Q931_ITR_64K = 0x10, - Q931_ITR_128K = 0x11, - Q931_ITR_384K = 0x13, - Q931_ITR_1536K = 0x15, - Q931_ITR_1920K = 0x17, - Q931_ITR_MULTI = 0x18 -}; - -/***************************************************************************** - - Struct: Q931mes_Header - - Description: Used to read the header & message code. - -*****************************************************************************/ -typedef struct { - L3UINT Size; /* Size of message in bytes */ - L3UCHAR ProtDisc; /* Protocol Discriminator */ - L3UCHAR MesType; /* Message type */ - L3UCHAR CRVFlag; /* Call reference value flag */ - L3INT CRV; /* Call reference value */ - -} Q931mes_Header; - -/***************************************************************************** - - Struct: Q931mes_Generic - - Description: Generic header containing all IE's. This is not used, but is - provided in case a proprietary variant needs it. - -*****************************************************************************/ -typedef struct { - L3UINT Size; /* Size of message in bytes */ - L3UCHAR ProtDisc; /* Protocol Discriminator */ - L3UCHAR MesType; /* Message type */ - L3UCHAR CRVFlag; /* Call reference value flag */ - L3INT CRV; /* Call reference value */ - - /* WARNING: don't touch anything above this line (TODO: use Q931mes_Header directly to make sure it's the same) */ - - L3UCHAR Tei; /* TEI */ - - ie Shift; - ie MoreData; - ie SendComplete; - ie CongestionLevel; - ie RepeatInd; - - ie Segment; /* Segmented message */ - ie BearerCap; /* Bearer Capability */ - ie Cause; /* Cause */ - ie CallState; /* Call State */ - ie CallID; /* Call Identity */ - ie ChanID; /* Channel Identification */ - ie ChangeStatus; /* Change Staus */ - ie ProgInd; /* Progress Indicator */ - ie NetFac; /* Network Spesific Facilities */ - ie NotifInd; /* Notification Indicator */ - ie Display; /* Display */ - ie DateTime; /* Date/Time */ - ie KeypadFac; /* Keypad Facility */ - ie Signal; /* Signal */ - ie InfoRate; /* Information rate */ - ie EndEndTxDelay; /* End to End Transmit Delay */ - ie TransDelSelInd; /* Transmit Delay Sel. and Ind. */ - ie PackParam; /* Packed Layer Binary parameters */ - ie PackWinSize; /* Packet Layer Window Size */ - ie PackSize; /* Packed Size */ - ie ClosedUserGrp; /* Closed User Group */ - ie RevChargeInd; /* Reverse Charging Indicator */ - ie CalledNum; /* Called Party Number */ - ie CalledSub; /* Called Party subaddress */ - ie CallingNum; /* Calling Party Number */ - ie CallingSub; /* Calling Party Subaddress */ - ie RedirNum; /* Redirection Number */ - ie TransNetSel; /* Transmit Network Selection */ - ie LLRepeatInd; /* Repeat Indicator 2 LLComp */ - ie RestartWin; /* Restart Window */ - ie RestartInd; /* Restart Indicator */ - ie LLComp; /* Low Layer Compatibility */ - ie HLComp; /* High Layer Compatibility */ - ie UserUser; /* User-user */ - ie Escape; /* Escape for extension */ - ie Switchhook; - ie FeatAct; - ie FeatInd; - ie GenericDigits; - - L3UCHAR buf[1]; /* Buffer for IE's */ - -} Q931mes_Generic; - - -/***************************************************************************** - - Struct: Q931_TrunkInfo - - Description: TrunkInfo is the struct entry used to store Q.931 related - information and state for E1/T1/J1 trunks and associated - channels in the system. - - The user should store this information outside this stack - and needs to feed the interface functions with a pointer to - the TrunkInfo entry. - -*****************************************************************************/ -typedef struct Q931_TrunkInfo Q931_TrunkInfo_t; - -typedef enum { - Q931_LOG_NONE = -1, - Q931_LOG_EMERG, - Q931_LOG_ALERT, - Q931_LOG_CRIT, - Q931_LOG_ERROR, - Q931_LOG_WARNING, - Q931_LOG_NOTICE, - Q931_LOG_INFO, - Q931_LOG_DEBUG -} Q931LogLevel_t; - -typedef L3INT (*Q931Tx34CB_t) (void *,L3UCHAR *, L3INT); -typedef L3INT (*Q931Tx32CB_t) (void *, L3INT, L3UCHAR, L3UCHAR *, L3INT); -typedef L3INT (*Q931ErrorCB_t) (void *,L3INT,L3INT,L3INT); -typedef L3INT (*Q931LogCB_t) (void *, Q931LogLevel_t, char *, L3INT); - -typedef enum { /* Network/User Mode. */ - Q931_TE=0, /* 0 : User Mode */ - Q931_NT=1 /* 1 : Network Mode */ -} Q931NetUser_t; - -typedef enum { /* Dialect enum */ - Q931_Dialect_Q931 = 0, - Q931_Dialect_National = 2, - Q931_Dialect_DMS = 4, - Q931_Dialect_5ESS = 6, /* Coming soon to a PRI stack near you! */ - - Q931_Dialect_Count -} Q931Dialect_t; -#define DIALECT_STRINGS "q931", "", "national", "", "dms", "", "5ess", "" -Q931_STR2ENUM_P(q931_str2Q931Dialect_type, q931_Q931Dialect_type2str, Q931Dialect_t) - -typedef enum { /* Trunk Line Type. */ - Q931_TrType_E1 = 0, /* 0 : E1 Trunk */ - Q931_TrType_T1 = 1, /* 1 : T1 Trunk */ - Q931_TrType_J1 = 2, /* 2 : J1 Trunk */ - Q931_TrType_BRI = 3, /* 3 : BRI Trunk */ - Q931_TrType_BRI_PTMP = 4 /* 4 : BRI PTMP Trunk */ -} Q931_TrunkType_t; - -typedef enum { /* Trunk State */ - Q931_TrState_NoAlignment=0, /* Trunk not aligned */ - Q931_TrState_Aligning=1, /* Aligning in progress */ - Q931_TrState_Aligned=2 /* Trunk Aligned */ -} Q931_TrunkState_t; - -typedef enum { - Q931_ChType_NotUsed=0, /* Unused Channel */ - Q931_ChType_B=1, /* B Channel (Voice) */ - Q931_ChType_D=2, /* D Channel (Signalling) */ - Q931_ChType_Sync=3 /* Sync Channel */ -} Q931_ChanType_t; - -struct Q931_Call -{ - L3UCHAR InUse; /* Indicate if entry is in use. */ - /* 0 = Not in Use */ - /* 1 = Active Call. */ - - L3UCHAR Tei; /* Associated TEI */ - - L3UCHAR BChan; /* Associated B Channel. */ - /* 0 - 31 valid B chan */ - /* 255 = Not allocated */ - - L3INT CRV; /* Associated CRV. */ - - L3UINT State; /* Call State. */ - /* 0 is Idle, but other values are */ - /* defined per dialect. */ - /* Default usage is 1-99 for TE and */ - /* 101 - 199 for NT. */ - - L3ULONG Timer; /* Timer in ms. The TimeTick will check */ - /* if this has exceeded the timeout, and */ - /* if so call the timers timeout proc. */ - - L3USHORT TimerID; /* Timer Identification/State */ - /* actual values defined by dialect */ - /* 0 : No timer running */ - /* ITU-T Q.931:301 - 322 Timer running */ -}; - -struct Q931_TrunkInfo -{ - Q931NetUser_t NetUser; /* Network/User Mode. */ - Q931_TrunkType_t TrunkType; /* Trunk Line Type. */ - Q931Dialect_t Dialect; /* Q.931 Based dialect index. */ - - Q931Tx34CB_t Q931Tx34CBProc; - Q931Tx32CB_t Q931Tx32CBProc; - Q931ErrorCB_t Q931ErrorCBProc; - Q931LogCB_t Q931LogCBProc; - void *PrivateData32; - void *PrivateData34; - void *PrivateDataLog; - - Q931LogLevel_t loglevel; - - L3UCHAR Enabled; /* Enabled/Disabled */ - /* 0 = Disabled */ - /* 1 = Enabled */ - - Q931_TrunkState_t TrunkState; - - L3INT LastCRV; /* Last used crv for the trunk. */ - - L3UCHAR L3Buf[Q931L4BUF]; /* message buffer for messages to be */ - /* send from Q.931 L4. */ - - L3UCHAR L2Buf[Q931L2BUF]; /* buffer for messages send to L2. */ - - /* The auto flags below switch on/off automatic Ack messages. SETUP ACK */ - /* as an example can be sent by the stack in response to SETUP to buy */ - /* time in processing on L4. Setting this to true will cause the stack */ - /* to automatically send this. */ - - L3BOOL autoSetupAck; /* Indicate if the stack should send */ - /* SETUP ACK or not. 0=No, 1 = Yes. */ - - L3BOOL autoConnectAck; /* Indicate if the stack should send */ - /* CONNECT ACT or not. 0=No, 1=Yes. */ - - L3BOOL autoRestartAck; /* Indicate if the stack should send */ - /* RESTART ACK or not. 0=No, 1=Yes. */ - - L3BOOL autoServiceAck; /* Indicate if the stack should send */ - /* SERVICE ACK or not. 0=No, 1=Yes. */ - - /* channel array holding info per channel. Usually defined to 32 */ - /* channels to fit an E1 since T1/J1 and BRI will fit inside a E1. */ - struct _charray - { - Q931_ChanType_t ChanType; /* Unused, B, D, Sync */ - - L3UCHAR Available; /* Channel Available Flag */ - /* 0 : Avaiabled */ - /* 1 : Used */ - - L3INT CRV; /* Associated CRV */ - - } ch[Q931MAXCHPERTRUNK]; - - /* Active Call information indentified by CRV. See Q931AllocateCRV for */ - /* initialization of call table. */ - struct Q931_Call call[Q931MAXCALLPERTRUNK]; -}; - -/***************************************************************************** - - Struct: Q931State - - Description: Define a Q931 State, legal events and next state for each - event. Used to simplify the state engine logic. Each state - engine defines its own state table and the logic need only - call a helper function to check if the message is legal - at this stage. - -*****************************************************************************/ -typedef struct -{ - L3INT State; - L3INT Message; - L3UCHAR Direction; -} Q931State; - -/***************************************************************************** - - Proc table external references. - - The proc tables are defined in Q931.c and initialized in Q931Initialize. - -*****************************************************************************/ -typedef L3INT (q931proc_func_t) (Q931_TrunkInfo_t *pTrunk, L3UCHAR *, L3INT); - -typedef L3INT (q931umes_func_t) (Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); -typedef L3INT (q931pmes_func_t) (Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); - -typedef L3INT (q931uie_func_t) (Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); -typedef L3INT (q931pie_func_t) (Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); - -typedef L3INT (q931timeout_func_t) (Q931_TrunkInfo_t *pTrunk, L3INT callIndex); -typedef L3ULONG q931timer_t; - -extern q931proc_func_t *Q931Proc[Q931MAXDLCT][Q931MAXMES]; - -extern q931umes_func_t *Q931Umes[Q931MAXDLCT][Q931MAXMES]; -extern q931pmes_func_t *Q931Pmes[Q931MAXDLCT][Q931MAXMES]; - -extern q931uie_func_t *Q931Uie[Q931MAXDLCT][Q931MAXIE]; -extern q931pie_func_t *Q931Pie[Q931MAXDLCT][Q931MAXIE]; - -extern q931timeout_func_t *Q931Timeout[Q931MAXDLCT][Q931MAXTIMER]; -extern q931timer_t Q931Timer[Q931MAXDLCT][Q931MAXTIMER]; - - -/***************************************************************************** - - Macro: GetIETotoSize - - Syntax: L3INT GetIETotSize(InfoElem ie); - - Description: Compute the total size in bytes of an info element including - size of 'header'. - -*****************************************************************************/ -#define Q931GetIETotSize(ie) (((ie.InfoID & 0x80) != 0) ? 1 : ie.LenIE) + 2) - -/***************************************************************************** - - Macro: IsIEPresent - - Syntax: BOOL IsIEPresent(ie InfoElement); - - Description: Return TRUE if the Information Element is included. - -*****************************************************************************/ -#define Q931IsIEPresent(x) ((x & 0x8000) != 0) - -/***************************************************************************** - - Macro: GetIEOffset and GetIEValue - - Syntax: L3INT GetIEOffset(ie InfoElement) - L3INT GetIEValue(ie InfoElement) - - Description: Returns the offset (or the value )to the Information Element. - - Note: GetIEValue assumes that the 15 lsb bit is the value of a - single octet information element. This macro can not be used - on a variable information element. - -*****************************************************************************/ -#define Q931GetIEOffset(x) (x & 0x7fff) -#define Q931GetIEValue(x) (x & 0x7fff) - -/***************************************************************************** - - Macro: Q931GetIEPtr - - Syntax: void * Q931GetIEPtr(ie InfoElement, L3UCHAR * Buf); - - Description: Compute a Ptr to the information element. - -*****************************************************************************/ -#define Q931GetIEPtr(ie,buf) ((void *)&buf[Q931GetIEOffset(ie)]) - -/***************************************************************************** - - Macro: SetIE - - Syntax: void SetIE(ie InfoElement, L3INT Offset); - - Description: Set an information element. - -*****************************************************************************/ -#define Q931SetIE(x,o) { x = (ie)(o) | 0x8000; } - -/***************************************************************************** - - Macro: IsQ931Ext - - Syntax BOOL IsQ931Ext(L3UCHAR c) - - Description: Return true Check if the msb (bit 8) is 0. This indicate - that the octet is extended. - -*****************************************************************************/ -#define IsQ931Ext(x) ((x & 0x80) == 0) - -/***************************************************************************** - - Macro: ieGetOctet - - Syntax: unsigned L3UCHAR ieGetOctet(L3INT e) - - Description: Macro to fetch one byte from an integer. Mostly used to - avoid warnings. - -*****************************************************************************/ -#define ieGetOctet(x) ((L3UCHAR)(x)) - -/***************************************************************************** - - Macro: NoWarning - - Syntax: void NoWarning(x) - - Description: Macro to suppress unreferenced formal parameter warnings - - Used during creation of the stack since the stack is - developed for Warning Level 4 and this creates a lot of - warning for the initial empty functions. - -*****************************************************************************/ -#define NoWarning(x) (x = x) - -/***************************************************************************** - - External references. See Q931.c for details. - -*****************************************************************************/ - -#include "Q931ie.h" - -#include "Q932.h" - -/***************************************************************************** - - Q.931 Message Pack/Unpack functions. Implemented in Q931mes.c - -*****************************************************************************/ -L3INT Q931Pmes_Alerting(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_CallProceeding(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Connect(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_ConnectAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Progress(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_SetupAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Resume(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_ResumeAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_ResumeReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Suspend(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_SuspendAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_SuspendReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_UserInformation(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Disconnect(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Release(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_ReleaseComplete(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Restart(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_RestartAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_CongestionControl(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Information(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Notify(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Status(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_StatusEnquiry(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_Service(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931Pmes_ServiceAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); - - -L3INT Q931Umes_Alerting(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_CallProceeding(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Connect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_ConnectAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Progress(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_SetupAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Resume(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_ResumeAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_ResumeReject(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Suspend(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_SuspendAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_SuspendReject(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_UserInformation(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Disconnect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Release(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Restart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_RestartAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_CongestionControl(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Information(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Notify(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Status(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_StatusEnquiry(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT I, L3INT O); -L3INT Q931Umes_Service(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); -L3INT Q931Umes_ServiceAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size); - - -/***************************************************************************** - - Q.931 Process Function Prototyping. Implemented in Q931StateTE.c - -*****************************************************************************/ -L3INT Q931ProcAlertingTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcCallProceedingTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcConnectTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcConnectAckTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcProgressTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSetupTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSetupAckTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcResumeTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcResumeAckTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcResumeRejectTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSuspendTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSuspendAckTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSuspendRejectTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcUserInformationTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcDisconnectTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcReleaseTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcReleaseCompleteTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcRestartTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcRestartAckTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcCongestionControlTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcInformationTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcNotifyTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcStatusTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcStatusEnquiryTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSegmentTE(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); - -L3INT Q931ProcAlertingNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcCallProceedingNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcConnectNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcConnectAckNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcProgressNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSetupNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSetupAckNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcResumeNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcResumeAckNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcResumeRejectNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSuspendNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSuspendAckNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSuspendRejectNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcUserInformationNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcDisconnectNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcReleaseNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcReleaseCompleteNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcRestartNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcRestartAckNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcCongestionControlNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcInformationNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcNotifyNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcStatusNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcStatusEnquiryNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcSegmentNT(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); - -L3INT Q931ProcUnknownMessage(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); -L3INT Q931ProcUnexpectedMessage(Q931_TrunkInfo_t *pTrunk,L3UCHAR * b, L3INT iFrom); - -/***************************************************************************** - - Interface Function Prototypes. Implemented in Q931.c - -*****************************************************************************/ -void Q931TimerTick(Q931_TrunkInfo_t *pTrunk); -L3INT Q931Rx23(Q931_TrunkInfo_t *pTrunk, L3INT ind, L3UCHAR tei, L3UCHAR * Mes, L3INT Size); -L3INT Q931Tx32Data(Q931_TrunkInfo_t *pTrunk, L3UCHAR bcast, L3UCHAR * Mes, L3INT Size); -L3INT Q931Rx43(Q931_TrunkInfo_t *pTrunk, L3UCHAR * Mes, L3INT Size); -L3INT Q931Tx34(Q931_TrunkInfo_t *pTrunk, L3UCHAR * Mes, L3INT Size); -void Q931SetError(Q931_TrunkInfo_t *pTrunk,L3INT ErrID, L3INT ErrPar1, L3INT ErrPar2); - -void Q931SetDefaultErrorCB(Q931ErrorCB_t Q931ErrorPar); - -void Q931CreateTE(L3UCHAR i); -void Q931CreateNT(L3UCHAR i); -void Q931SetMesCreateCB(L3INT (*callback)(void)); -void Q931SetDialectCreateCB(L3INT (*callback)(L3INT)); -void Q931SetHeaderSpace(L3INT space); - -void Q931SetMesProc(L3UCHAR mes, L3UCHAR dialect, q931proc_func_t *Q931ProcFunc, q931umes_func_t *Q931UmesFunc, q931pmes_func_t *Q931PmesFunc); -void Q931SetIEProc(L3UCHAR iec, L3UCHAR dialect, q931pie_func_t *Q931PieProc, q931uie_func_t *Q931UieProc); -void Q931SetTimeoutProc(L3UCHAR dialect, L3UCHAR timer, q931timeout_func_t *Q931TimeoutProc); -void Q931SetTimerDefault(L3UCHAR dialect, L3UCHAR timer, q931timer_t timeout); - -void Q931Initialize(void); -void Q931AddDialect(L3UCHAR iDialect, void (*Q931CreateDialectCB)(L3UCHAR iDialect)); -L3INT Q931InitMesSetup(Q931mes_Generic *p); -L3INT Q931InitMesRestartAck(Q931mes_Generic * pMes); -L3INT Q931InitMesGeneric(Q931mes_Generic *pMes); - -L3INT Q931CreateCRV(Q931_TrunkInfo_t *pTrunk, L3INT * callIndex); -L3INT Q931ReleaseCRV(Q931_TrunkInfo_t *pTrunk, L3INT CRV); -L3INT Q931AllocateCRV(Q931_TrunkInfo_t *pTrunk, L3INT iCRV, L3INT * callIndex); -L3INT Q931FindCRV(Q931_TrunkInfo_t *pTrunk, L3INT crv, L3INT *callindex); -L3INT Q931GetCallState(Q931_TrunkInfo_t *pTrunk, L3INT iCRV); -L3INT Q931StartTimer(Q931_TrunkInfo_t *pTrunk, L3INT callIndex, L3USHORT iTimer); -L3INT Q931StopTimer(Q931_TrunkInfo_t *pTrunk, L3INT callindex, L3USHORT iTimer); -L3INT Q931SetState(Q931_TrunkInfo_t *pTrunk, L3INT callIndex, L3INT iState); -L3ULONG Q931GetTime(void); -void Q931SetGetTimeCB(L3ULONG (*callback)(void)); -void Q931AddStateEntry(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir); -L3BOOL Q931IsEventLegal(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir); - -/***************************************************************************** - - Q.931 Low Level API Function Prototyping. Implemented in Q931API.c - -*****************************************************************************/ -ie Q931AppendIE(L3UCHAR *pm, L3UCHAR *pi); -L3INT Q931GetUniqueCRV(Q931_TrunkInfo_t *pTrunk); - -L3INT Q931InitIEBearerCap(Q931ie_BearerCap *p); -L3INT Q931InitIEChanID(Q931ie_ChanID *p); -L3INT Q931InitIEProgInd(Q931ie_ProgInd *p); -L3INT Q931InitIENetFac(Q931ie_NetFac * pIE); -L3INT Q931InitIEDisplay(Q931ie_Display * pIE); -L3INT Q931InitIEDateTime(Q931ie_DateTime * pIE); -L3INT Q931InitIEKeypadFac(Q931ie_KeypadFac * pIE); -L3INT Q931InitIESignal(Q931ie_Signal * pIE); -L3INT Q931InitIECallingNum(Q931ie_CallingNum * pIE); -L3INT Q931InitIECallingSub(Q931ie_CallingSub * pIE); -L3INT Q931InitIECalledNum(Q931ie_CalledNum * pIE); -L3INT Q931InitIECalledSub(Q931ie_CalledSub * pIE); -L3INT Q931InitIETransNetSel(Q931ie_TransNetSel * pIE); -L3INT Q931InitIELLComp(Q931ie_LLComp * pIE); -L3INT Q931InitIEHLComp(Q931ie_HLComp * pIE); - -L3INT Q931Disconnect(Q931_TrunkInfo_t *pTrunk, L3INT iTo, L3INT iCRV, L3INT iCause); -L3INT Q931ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); -L3INT Q931AckRestart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); -L3INT Q931AckConnect(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); -L3INT Q931AckSetup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); -L3INT Q931AckService(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf); - -L3INT Q931Api_InitTrunk(Q931_TrunkInfo_t *pTrunk, - Q931Dialect_t Dialect, - Q931NetUser_t NetUser, - Q931_TrunkType_t TrunkType, - Q931Tx34CB_t Q931Tx34CBProc, - Q931Tx32CB_t Q931Tx32CBProc, - Q931ErrorCB_t Q931ErrorCBProc, - void *PrivateData32, - void *PrivateData34); - -L3INT Q931GetMesSize(Q931mes_Generic *pMes); -L3INT Q931InitMesResume(Q931mes_Generic * pMes); - -L3INT Q931Log(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level, const char *fmt, ...); -void Q931SetLogCB(Q931_TrunkInfo_t *trunk, Q931LogCB_t func, void *priv); -void Q931SetLogLevel(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level); - -void Q931SetL4HeaderSpace(L3INT space); -void Q931SetL2HeaderSpace(L3INT space); -L3INT Q931ProcDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b,L3INT c); -L3INT Q931UmesDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); -L3INT Q931UieDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); -L3INT Q931PmesDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q931PieDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); -L3INT Q931TxDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT n); -L3INT Q931ErrorDummy(void *priv, L3INT a, L3INT b, L3INT c); -L3INT Q931TimeoutDummy(Q931_TrunkInfo_t *pTrunk, L3INT callIndex); - -L3INT Q931MesgHeader(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *mes, L3UCHAR *OBuf, L3INT Size, L3INT *IOff); - -#endif /* _Q931_NL */ diff --git a/libs/freetdm/src/isdn/include/Q931ie.h b/libs/freetdm/src/isdn/include/Q931ie.h deleted file mode 100644 index 65dba4e261..0000000000 --- a/libs/freetdm/src/isdn/include/Q931ie.h +++ /dev/null @@ -1,1205 +0,0 @@ -/****************************************************************************** - - FileName: Q931ie.h - - Contents: Header and definition for the ITU-T Q.931 ie - structures and functions - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -******************************************************************************/ - -#ifndef _Q931IE_NL -#define _Q931IE_NL - -/* Codesets */ - -typedef enum { - - Q931_CODESET_0 = ( 0 ), - Q931_CODESET_1 = ( 1 << 8 ), - Q931_CODESET_2 = ( 2 << 8 ), - Q931_CODESET_3 = ( 3 << 8 ), - Q931_CODESET_4 = ( 4 << 8 ), - Q931_CODESET_5 = ( 5 << 8 ), - Q931_CODESET_6 = ( 6 << 8 ), - Q931_CODESET_7 = ( 7 << 8 ) - -} q931_codeset_t; - -/* Single octet information elements */ -#define Q931ie_SHIFT 0x90 /* 1001 ---- */ -#define Q931ie_MORE_DATA 0xa0 /* 1010 ---- */ -#define Q931ie_SENDING_COMPLETE 0xa1 /* 1010 0001 */ -#define Q931ie_CONGESTION_LEVEL 0xb0 /* 1011 ---- */ -#define Q931ie_REPEAT_INDICATOR 0xd0 /* 1101 ---- */ - -/* Variable Length Information Elements */ -#define Q931ie_SEGMENTED_MESSAGE 0x00 /* 0000 0000 */ -#define Q931ie_CHANGE_STATUS 0x01 /* 0000 0001 */ -#define Q931ie_BEARER_CAPABILITY 0x04 /* 0000 0100 */ -#define Q931ie_CAUSE 0x08 /* 0000 1000 */ -#define Q931ie_CALL_IDENTITY 0x10 /* 0001 0000 */ -#define Q931ie_CALL_STATE 0x14 /* 0001 0100 */ -#define Q931ie_CHANNEL_IDENTIFICATION 0x18 /* 0001 1000 */ -#define Q931ie_PROGRESS_INDICATOR 0x1e /* 0001 1110 */ -#define Q931ie_NETWORK_SPECIFIC_FACILITIES 0x20 /* 0010 0000 */ -#define Q931ie_NOTIFICATION_INDICATOR 0x27 /* 0010 0111 */ -#define Q931ie_DISPLAY 0x28 /* 0010 1000 */ -#define Q931ie_DATETIME 0x29 /* 0010 1001 */ -#define Q931ie_KEYPAD_FACILITY 0x2c /* 0010 1100 */ -#define Q931ie_SIGNAL 0x34 /* 0011 0100 */ -#define Q931ie_SWITCHOOK 0x36 /* 0011 0110 */ -#define Q931ie_FEATURE_ACTIVATION 0x38 /* 0011 1000 */ -#define Q931ie_FEATURE_INDICATION 0x39 /* 0011 1001 */ -#define Q931ie_INFORMATION_RATE 0x40 /* 0100 0000 */ -#define Q931ie_END_TO_END_TRANSIT_DELAY 0x42 /* 0100 0010 */ -#define Q931ie_TRANSIT_DELAY_SELECTION_AND_IND 0x43 /* 0100 0011 */ -#define Q931ie_PACKED_LAYER_BIMARY_PARAMETERS 0x44 /* 0100 0100 */ -#define Q931ie_PACKED_LAYER_WINDOW_SIZE 0x45 /* 0100 0101 */ -#define Q931ie_PACKED_SIZE 0x46 /* 0100 0110 */ -#define Q931ie_CALLING_PARTY_NUMBER 0x6c /* 0110 1100 */ -#define Q931ie_CALLING_PARTY_SUBADDRESS 0x6d /* 0110 1101 */ -#define Q931ie_CALLED_PARTY_NUMBER 0x70 /* 0111 0000 */ -#define Q931ie_CALLED_PARTY_SUBADDRESS 0x71 /* 0111 0001 */ -#define Q931ie_REDIRECTING_NUMBER 0x74 /* 0111 0100 */ -#define Q931ie_TRANSIT_NETWORK_SELECTION 0x78 /* 0111 1000 */ -#define Q931ie_RESTART_INDICATOR 0x79 /* 0111 1001 */ -#define Q931ie_LOW_LAYER_COMPATIBILITY 0x7c /* 0111 1100 */ -#define Q931ie_HIGH_LAYER_COMPATIBILITY 0x7d /* 0111 1101 */ -#define Q931ie_USER_USER 0x7e /* 0111 1110 */ -#define Q931ie_ESCAPE_FOR_EX 0x7f /* 0111 1111 */ - -/* Variable Length Codeset 6 Information Elements */ -#define Q931ie_GENERIC_DIGITS 0x37 /* 0011 0111 */ - -/* Variable Length Information Element to shut up BRI testing */ -#define Q931ie_CONNECTED_NUMBER 0x4c /* 0100 1101 */ -#define Q931ie_FACILITY 0x1c /* 0001 1101 */ - - -/***************************************************************************** - - Struct: Q931ie_BearerCap - - Description: Bearer Capability Information Element. - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00000100 for Bearer Capability */ - L3UCHAR Size; /* Length of Information Element */ - - L3UCHAR CodStand; /* Coding Standard. */ - /* 00 - ITU-T */ - /* 01 - ISO/IEC */ - /* 10 - National standard */ - /* 11 - Network side spesific */ - - L3UCHAR ITC; /* Information Transfer Capability */ - /* 00000 - Speech */ - /* 01000 - Unrestricted digital info */ - /* 01001 - Restricted digital info */ - /* 10000 - 3.1 kHz audio */ - /* 10001 - Unrestricted with tones */ - /* 11000 - Video */ - - L3UCHAR TransMode; /* Transfer Mode. */ - /* 00 - Circuit mode */ - /* 10 - Packet mode */ - - L3UCHAR ITR; /* Information Transfer Rate. */ - /* 00000 - Packed mode */ - /* 10000 - 64 kbit/s */ - /* 10001 - 2 x 64 kbit/s */ - /* 10011 - 384 kbit/s */ - /* 10101 - 1536 kbit/s */ - /* 10111 - 1920 kbit/s */ - /* 11000 - Multirat (64 kbit/s base) */ - - L3UCHAR RateMul; /* Rate Multiplier */ - - L3UCHAR Layer1Ident; /* Layer 1 Ident. */ - - L3UCHAR UIL1Prot; /* User Information Layer 1 Protocol */ - /* 00001 : ITU-T V.110, I.460 and X.30 */ - /* 00010 : G.711 my-law */ - /* 00011 : G.711 A-law */ - /* 00100 : G.721 */ - /* 00101 : H.221 and H.242 */ - /* 00110 : H.223 and H.245 */ - /* 00111 : Non ITU-T Standard */ - /* 01000 : ITU-T V.120 */ - /* 01001 : ITU-T X.31 HDLC flag stuff. */ - - L3UCHAR SyncAsync; /* Sync/Async */ - /* 0 : Syncronous data */ - /* 1 : Asyncronous data */ - - L3UCHAR Negot; /* Negotiation */ - /* 0 : In-band negotiation not possib. */ - /* 1 : In-band negotiation possible */ - - L3UCHAR UserRate; /* User rate */ - /* 00000 : I.460, V.110, X,30 */ - /* 00001 : 0.6 kbit/s x.1 */ - /* 00010 : 1.2 kbit/s */ - /* 00011 : 2.4 kbit/s */ - /* 00100 : 3.6 kbit/s */ - /* 00101 : 4.8 kbit/s */ - /* 00110 : 7.2 kbit/s */ - /* 00111 : 8 kbit/s I.460 */ - /* 01000 : 9.6 kbit/s */ - /* 01001 : 14.4 kbit/s */ - /* 01010 : 16 kbit/s */ - /* 01011 : 19.2 kbit/s */ - /* 01100 : 32 kbit/s */ - /* 01101 : 38.4 kbit/s */ - /* 01110 : 48 kbit/s */ - /* 01111 : 56 kbit/s */ - /* 10000 : 57.6 kbit/s */ - /* 10010 : 28.8 kbit/s */ - /* 10100 : 24 kbit/s */ - /* 10101 : 0.1345 kbit/s */ - /* 10110 : 0.100 kbit/s */ - /* 10111 : 0.075/1.2 kbit/s */ - /* 11000 : 1.2/0.075/kbit/s */ - /* 11001 : 0.050 kbit/s */ - /* 11010 : 0.075 kbit/s */ - /* 11011 : 0.110 kbit/s */ - /* 11100 : 0.150 kbit/s */ - /* 11101 : 0.200 kbit/s */ - /* 11110 : 0.300 kbit/s */ - /* 11111 : 12 kbit/s */ - - L3UCHAR InterRate; /* Intermediate Rate */ - /* 00 : Not used */ - /* 01 : 8 kbit/s */ - /* 10 : 16 kbit/s */ - /* 11 : 32 kbit/s */ - - L3UCHAR NIConTx; /* Network Indepentend Clock on transmit*/ - /* 0 : Not required to send data clc */ - /* 1 : Send data w/NIC clc */ - - L3UCHAR NIConRx; /* NIC on Rx */ - /* 0 : Cannot accept indep. clc */ - /* 1 : data with indep. clc accepted */ - - L3UCHAR FlowCtlTx; /* Flow control on Tx */ - /* 0 : Send Flow ctrl not required */ - /* 1 : Send flow ctrl required */ - - L3UCHAR FlowCtlRx; /* Flow control on Rx */ - /* 0 : cannot use receive flow ctrl */ - /* 1 : Receive flow ctrl accepted */ - L3UCHAR HDR; /* HDR/No HDR */ - L3UCHAR MultiFrame; /* Multi frame support */ - /* 0 : multiframe not supported */ - /* 1 : multiframe supported */ - - L3UCHAR Mode; /* Mode of operation */ - /* 0 : bit transparent mode of operat. */ - /* 1 : protocol sesitive mode of op. */ - - L3UCHAR LLInegot; /* Logical link id negotiation (oct. 5b)*/ - /* 0 : default LLI=256 only */ - /* 1 : Full protocol negotiation */ - - L3UCHAR Assignor; /* Assignor/assignee */ - /* 0 : Default Asignee */ - /* 1 : Assignor only */ - - L3UCHAR InBandNeg; /* In-band/out-band negot. */ - /* 0 : negot done w/ USER INFO mes */ - /* 1 : negot done in-band w/link zero */ - - L3UCHAR NumStopBits; /* Number of stop bits */ - /* 00 : Not used */ - /* 01 : 1 bit */ - /* 10 : 1.5 bits */ - /* 11 : 2 bits */ - - L3UCHAR NumDataBits; /* Number of data bits. */ - /* 00 : not used */ - /* 01 : 5 bits */ - /* 10 : 7 bits */ - /* 11 : 8 bits */ - - L3UCHAR Parity; /* Parity Information */ - /* 000 : Odd */ - /* 010 : Even */ - /* 011 : None */ - /* 100 : Forced to 0 */ - /* 101 : Forced to 1 */ - - L3UCHAR DuplexMode; /* Mode duplex */ - /* 0 : Half duplex */ - /* 1 : Full duplex */ - - L3UCHAR ModemType; /* Modem type, see Q.931 p 64 */ - - L3UCHAR Layer2Ident; /* Layer 2 Ident */ - - L3UCHAR UIL2Prot; /* User Information Layer 2 Protocol */ - /* 00010 : Q.921/I.441 */ - /* 00110 : X.25 */ - /* 01100 : LAN logical link */ - - L3UCHAR Layer3Ident; /* Layer 3 ident. */ - - L3UCHAR UIL3Prot; /* User Information Layer 3 Protocol */ - /* 00010 : Q.931 */ - /* 00110 : X.25 */ - /* 01011 : ISO/IEC TR 9577 */ - - L3UCHAR AL3Info1; /* additional layer 3 info 1 */ - - L3UCHAR AL3Info2; /* additional layer 3 info 2 */ - -} Q931ie_BearerCap; - -/***************************************************************************** - - Struct: Q931ie_CallID - - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00010000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CallId[1]; /* Call identity */ - -} Q931ie_CallID; - -/***************************************************************************** - - Struct: Q931ie_CallState - - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00010100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CodStand; /* Coding Standard */ - L3UCHAR CallState; /* Call State Value */ - -} Q931ie_CallState; - -/***************************************************************************** - - Struct: Q931ie_Cause - - Description: Cause IE as described in Q.850 - -*****************************************************************************/ -typedef struct { - - L3UCHAR IEId; /* 00010100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CodStand; /* Coding Standard */ - L3UCHAR Location; /* Location */ - L3UCHAR Recom; /* Recommendation */ - L3UCHAR Value; /* Cause Value */ - L3UCHAR Diag[1]; /* Optional Diagnostics Field */ - -} Q931ie_Cause; - -/***************************************************************************** - - Struct: Q931ie_CalledNum - -*****************************************************************************/ -typedef struct { - - L3UCHAR IEId; /* 01110000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR TypNum; /* Type of Number */ - L3UCHAR NumPlanID; /* Numbering plan identification */ - L3UCHAR Digit[1]; /* Digit (IA5) */ - -} Q931ie_CalledNum; - -/***************************************************************************** - - Struct: Q931ie_CalledSub - - Description: Called party subaddress - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 01110001 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR TypNum; /* Type of subaddress */ - L3UCHAR OddEvenInd; /* Odd/Even indicator */ - L3UCHAR Digit[1]; /* digits */ - -} Q931ie_CalledSub; - -/***************************************************************************** - - Struct: Q931ie_CallingNum - - Description: Calling party number - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 01101100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR TypNum; /* Type of number */ - L3UCHAR NumPlanID; /* Numbering plan identification */ - L3UCHAR PresInd; /* Presentation indicator */ - L3UCHAR ScreenInd; /* Screening indicator */ - L3UCHAR Digit[1]; /* Number digits (IA5) */ - -} Q931ie_CallingNum; - -/***************************************************************************** - - Struct: Q931ie_CallingSub - - Description: Calling party subaddress - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 01101101 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR TypNum; /* Type of subaddress */ - L3UCHAR OddEvenInd; /* Odd/Even indicator */ - L3UCHAR Digit[1]; /* digits */ - -} Q931ie_CallingSub; - -/***************************************************************************** - - Struct: Q931ie_ChanID - - Description: Channel identification - - Channel Identificationis one of the IE elements that differ - between BRI and PRI. IntType = 1 = BRI and ChanSlot is used - for channel number, while InfoChanSel is used for BRI. - - ChanID is one of the most important IE as it is passed - either though SETUP or CALL PROCEEDING to select the channel - to be used. - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00011000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR IntIDPresent; /* Int. id. present */ - L3UCHAR IntType; /* Interface Type */ - /* 0 : Basic Interface (BRI) */ - /* 1 : Other interfaces, PRI etc. */ - - L3UCHAR PrefExcl; /* Pref./Excl. */ - /* 0 : Indicated channel is preffered */ - /* 1 : Exclusive, no other accepted */ - - L3UCHAR DChanInd; /* D-channel ind. */ - /* 0 : chan is NOT D chan. */ - /* 1 : chan is D chan */ - - L3UCHAR InfoChanSel; /* Info. channel selection */ - /* 00 : No channel */ - /* 01 : B1 channel */ - /* 10 : B2 channel */ - /* 11 : Any channel */ - - L3UCHAR InterfaceID; /* Interface identifier */ - - L3UCHAR CodStand; /* Code standard */ - /* 00 : ITU-T standardization coding */ - /* 01 : ISO/IEC Standard */ - /* 10 : National Standard */ - /* 11 : Standard def. by network. */ - - L3UCHAR NumMap; /* Number/Map */ - /* 0 : chan is in following octet */ - /* 1 : chan is indicated by slot map */ - - L3UCHAR ChanMapType; /* Channel type/Map element type */ - /* 0011 : B Channel units */ - /* 0110 : H0 channel units */ - /* 1000 : H11 channel units */ - /* 1001 : H12 channel units */ - - L3UCHAR ChanSlot; /* Channel number */ - -} Q931ie_ChanID; - -/***************************************************************************** - - Struct: Q931ie_DateTime - - Description: Date/time - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00101001 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Year; /* Year */ - L3UCHAR Month; /* Month */ - L3UCHAR Day; /* Day */ - L3UCHAR Hour; /* Hour */ - L3UCHAR Minute; /* Minute */ - L3UCHAR Second; /* Second */ - L3UCHAR Format; /* Indicate presense of Hour, Min & sec */ - /* 0 : Only Date */ - /* 1 : Hour present */ - /* 2 : Hour and Minute present */ - /* 3 : Hour, Minute and Second present */ -} Q931ie_DateTime; - -/***************************************************************************** - - Struct: Q931ie_Display - - Description: Display - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00101000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Display[1]; /* Display information (IA5) */ - -} Q931ie_Display; - -/***************************************************************************** - - Struct: Q931ie_HLComp - - Description: High layer compatibility - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 01111101 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CodStand; /* Coding standard */ - L3UCHAR Interpret; /* Interpretation */ - L3UCHAR PresMeth; /* Presentation methor of prot. profile */ - L3UCHAR HLCharID; /* High layer characteristics id. */ - L3UCHAR EHLCharID; /* Extended high layer character. id. */ - L3UCHAR EVideoTlfCharID; /* Ext. videotelephony char. id. */ - -} Q931ie_HLComp; - -/***************************************************************************** - - Struct: Q931ie_KeypadFac - - Description: Keypad facility - -*****************************************************************************/ - -typedef struct { - L3UCHAR IEId; /* 00101100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR KeypadFac[1]; /* dynamic buffer */ - -} Q931ie_KeypadFac; - -/***************************************************************************** - - Struct: Q931ie_LLComp - - Description: Low layer compatibility - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 01111100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CodStand; /* Coding standard */ - /* 00 - ITU-T */ - /* 01 - ISO/IEC */ - /* 10 - National standard */ - /* 11 - Network side spesific */ - - L3UCHAR ITransCap; /* Information transfer capability */ - /* 00000 - Speech */ - /* 01000 - Unrestricted digital info */ - /* 01001 - Restricted digital info */ - /* 10000 - 3.1 kHz audio */ - /* 10001 - Unrestricted with tones */ - /* 11000 - Video */ - - L3UCHAR NegotInd; /* Negot indic. */ - /* 0 : Out-band neg. not possib. */ - /* 1 : Out-band neg. possible */ - - L3UCHAR TransMode; /* Transfer Mode */ - /* 00 : Circuit Mode */ - /* 10 : Packed Mode */ - - L3UCHAR InfoRate; /* Information transfer rate */ - /* 00000 - Packed mode */ - /* 10000 - 64 kbit/s */ - /* 10001 - 2 x 64 kbit/s */ - /* 10011 - 384 kbit/s */ - /* 10101 - 1536 kbit/s */ - /* 10111 - 1920 kbit/s */ - /* 11000 - Multirat (64 kbit/s base) */ - - L3UCHAR RateMul; /* Rate multiplier */ - L3UCHAR Layer1Ident; /* Layer 1 ident. */ - L3UCHAR UIL1Prot; /* User information layer 1 protocol */ - /* 00001 : ITU-T V.110, I.460 and X.30 */ - /* 00010 : G.711 my-law */ - /* 00011 : G.711 A-law */ - /* 00100 : G.721 */ - /* 00101 : H.221 and H.242 */ - /* 00110 : H.223 and H.245 */ - /* 00111 : Non ITU-T Standard */ - /* 01000 : ITU-T V.120 */ - /* 01001 : ITU-T X.31 HDLC flag stuff. */ - - L3UCHAR SyncAsync; /* Synch/asynch */ - /* 0 : Syncronous data */ - /* 1 : Asyncronous data */ - - L3UCHAR Negot; /* Negot */ - /* 0 : In-band negotiation not possib. */ - /* 1 : In-band negotiation possible */ - - L3UCHAR UserRate; /* User rate */ - /* 00000 : I.460, V.110, X,30 */ - /* 00001 : 0.6 kbit/s x.1 */ - /* 00010 : 1.2 kbit/s */ - /* 00011 : 2.4 kbit/s */ - /* 00100 : 3.6 kbit/s */ - /* 00101 : 4.8 kbit/s */ - /* 00110 : 7.2 kbit/s */ - /* 00111 : 8 kbit/s I.460 */ - /* 01000 : 9.6 kbit/s */ - /* 01001 : 14.4 kbit/s */ - /* 01010 : 16 kbit/s */ - /* 01011 : 19.2 kbit/s */ - /* 01100 : 32 kbit/s */ - /* 01101 : 38.4 kbit/s */ - /* 01110 : 48 kbit/s */ - /* 01111 : 56 kbit/s */ - /* 10000 : 57.6 kbit/s */ - /* 10010 : 28.8 kbit/s */ - /* 10100 : 24 kbit/s */ - /* 10101 : 0.1345 kbit/s */ - /* 10110 : 0.100 kbit/s */ - /* 10111 : 0.075/1.2 kbit/s */ - /* 11000 : 1.2/0.075/kbit/s */ - /* 11001 : 0.050 kbit/s */ - /* 11010 : 0.075 kbit/s */ - /* 11011 : 0.110 kbit/s */ - /* 11100 : 0.150 kbit/s */ - /* 11101 : 0.200 kbit/s */ - /* 11110 : 0.300 kbit/s */ - /* 11111 : 12 kbit/s */ - - L3UCHAR InterRate; /* Intermediate rate */ - /* 00 : Not used */ - /* 01 : 8 kbit/s */ - /* 10 : 16 kbit/s */ - /* 11 : 32 kbit/s */ - - L3UCHAR NIConTx; /* Network Indepentend Clock on transmit*/ - /* 0 : Not required to send data clc */ - /* 1 : Send data w/NIC clc */ - - L3UCHAR NIConRx; /* NIC on Rx */ - /* 0 : Cannot accept indep. clc */ - /* 1 : data with indep. clc accepted */ - - L3UCHAR FlowCtlTx; /* Flow control on Tx */ - /* 0 : Send Flow ctrl not required */ - /* 1 : Send flow ctrl required */ - - L3UCHAR FlowCtlRx; /* Flow control on Rx */ - /* 0 : cannot use receive flow ctrl */ - /* 1 : Receive flow ctrl accepted */ - L3UCHAR HDR; /* HDR/No HDR */ - L3UCHAR MultiFrame; /* Multi frame support */ - /* 0 : multiframe not supported */ - /* 1 : multiframe supported */ - - L3UCHAR ModeL1; /* Mode L1 */ - /* 0 : bit transparent mode of operat. */ - /* 1 : protocol sesitive mode of op. */ - - L3UCHAR NegotLLI; /* Negot. LLI */ - /* 0 : default LLI=256 only */ - /* 1 : Full protocol negotiation */ - - L3UCHAR Assignor; /* Assignor/Assignor ee */ - /* 0 : Default Asignee */ - /* 1 : Assignor only */ - - L3UCHAR InBandNeg; /* In-band negot. */ - /* 0 : negot done w/ USER INFO mes */ - /* 1 : negot done in-band w/link zero */ - - L3UCHAR NumStopBits; /* Number of stop bits */ - /* 00 : Not used */ - /* 01 : 1 bit */ - /* 10 : 1.5 bits */ - /* 11 : 2 bits */ - - L3UCHAR NumDataBits; /* Number of data bits. */ - /* 00 : not used */ - /* 01 : 5 bits */ - /* 10 : 7 bits */ - /* 11 : 8 bits */ - - L3UCHAR Parity; /* Parity Information */ - /* 000 : Odd */ - /* 010 : Even */ - /* 011 : None */ - /* 100 : Forced to 0 */ - /* 101 : Forced to 1 */ - - L3UCHAR DuplexMode; /* Mode duplex */ - /* 0 : Half duplex */ - /* 1 : Full duplex */ - - L3UCHAR ModemType; /* Modem type, see Q.931 p 89 */ - - L3UCHAR Layer2Ident; /* Layer 2 ident. */ - - L3UCHAR UIL2Prot; /* User information layer 2 protocol */ - /* 00001 : Basic mode ISO 1745 */ - /* 00010 : Q.921/I.441 */ - /* 00110 : X.25 single link */ - /* 00111 : X.25 multilink */ - /* 01000 : Extended LAPB T.71 */ - /* 01001 : HDLC ARM */ - /* 01010 : HDLC NRM */ - /* 01011 : HDLC ABM */ - /* 01100 : LAN logical link */ - /* 01101 : X.75 SLP */ - /* 01110 : Q.922 */ - /* 01111 : Q.922 core aspect */ - /* 10000 : User specified */ - /* 10001 : ISO/IEC 7776 DTE-DCE */ - - L3UCHAR ModeL2; /* Mode */ - /* 01 : Normal Mode of operation */ - /* 10 : Extended mode of operation */ - - L3UCHAR Q933use; /* Q.9333 use */ - - L3UCHAR UsrSpcL2Prot; /* User specified layer 2 protocol info */ - - L3UCHAR WindowSize; /* Window size (k) */ - - L3UCHAR Layer3Ident; /* Layer 3 ident */ - - L3UCHAR UIL3Prot; /* User Information Layer 3 protocol */ - /* 00010 : Q.931 */ - /* 00110 : X.25 */ - /* 00111 : 8208 */ - /* 01000 : X.233 ... */ - /* 01001 : 6473 */ - /* 01010 : T.70 */ - /* 01011 : ISO/IEC TR 9577 */ - /* 10000 : User specified */ - L3UCHAR OptL3Info; /* Optional Leyer 3 info */ - - L3UCHAR ModeL3; /* Mode of operation */ - /* 01 : Normal packed seq. numbering */ - /* 10 : Extended packed seq. numbering */ - - L3UCHAR DefPackSize; /* Default packet size */ - - L3UCHAR PackWinSize; /* Packet window size */ - - L3UCHAR AddL3Info; /* Additional Layer 3 protocol info */ - -} Q931ie_LLComp; - -/***************************************************************************** - - Struct: Q931ie_NetFac; - - Description: Network-specific facilities - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00100000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR LenNetID; /* Length of network facilities id. */ - L3UCHAR TypeNetID; /* Type of network identification */ - L3UCHAR NetIDPlan; /* Network identification plan. */ - L3UCHAR NetFac; /* Network specific facility spec. */ - L3UCHAR NetID[1]; /* Network id. (IA5) */ - -} Q931ie_NetFac; - -/***************************************************************************** - - Struct: Q931ie_NotifInd; - - Description: Notification Indicator - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00100000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Notification; /* Notification descriptor */ - -} Q931ie_NotifInd; - -/***************************************************************************** - - Struct: Q931ie_ProgInd - - Description: Progress indicator - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00011110 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CodStand; /* Coding standard */ - L3UCHAR Location; /* Location */ - L3UCHAR ProgDesc; /* Progress description */ - -} Q931ie_ProgInd; - -/***************************************************************************** - - Struct; Q931ie_Segment - - Description: Segmented message - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00000000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR FSI; /* First segment indicator */ - L3UCHAR NumSegRem; /* Number of segments remaining */ - L3UCHAR SegType; /* Segment message type */ - -} Q931ie_Segment; - - -typedef struct { - - L3UCHAR IEId; /* 00000000 */ - L3UCHAR Size; /* Length of Information Element */ - -} Q931ie_SendComplete; - -/***************************************************************************** - - Struct: Q931ie_Signal - - Description: Signal - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00000000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Signal; /* Signal value */ - /* 00000000 Dial tone on */ - /* 00000001 Ring back tone on */ - /* 00000010 Intercept tone on */ - /* 00000011 Network congestion on */ - /* 00000100 Busy tone on */ - /* 00000101 Confirm tone on */ - /* 00000110 Answer tone on */ - /* 00000111 Call waiting tone */ - /* 00001000 Off-hook warning tone */ - /* 00001001 Pre-emption tone on */ - /* 00111111 Tones off */ - /* 01000000 Alerting on - pattern 0 */ - /* 01000001 Alerting on - pattern 1 */ - /* 01000010 Alerting on - pattern 2 */ - /* 01000011 Alerting on - pattern 3 */ - /* 01000100 Alerting on - pattern 4 */ - /* 01000101 Alerting on - pattern 5 */ - /* 01000110 Alerting on - pattern 6 */ - /* 01000111 Alerting on - pattern 7 */ - /* 01001111 Alerting off */ -} Q931ie_Signal; - -/***************************************************************************** - - Struct: Q931ie_TransDelSelInd - - description: Transit delay selection and indication - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 00000000 */ - L3UCHAR Size; /* Length of Information Element */ - L3ULONG TxDSIValue; /* Trans. delay sel. & ind. value */ - -} Q931ie_TransDelSelInd; -#endif - -/***************************************************************************** - - Struct: Q931ie_TransNetSel - - Description: Transit network selection - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 01111000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Type; /* Type of network identifier */ - L3UCHAR NetIDPlan; /* Network idetification plan */ - L3UCHAR NetID[1]; /* Network identification(IA5) */ - -} Q931ie_TransNetSel; - -/***************************************************************************** - - Struct: Q931ie_UserUser - - Description: User-user - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 01111110 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR ProtDisc; /* Protocol discriminator */ - L3UCHAR User[1]; /* User information */ - -} Q931ie_UserUser; - -/***************************************************************************** - - Struct: Q931ie_ClosedUserGrp - - Description: Closed user group - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 01000111 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CUGInd; /* CUG indication */ - L3UCHAR CUG[1]; /* CUG index code (IA5) */ - -} Q931ie_ClosedUserGrp; -#endif - -/***************************************************************************** - - Struct: Q931ie_CongLevel - - Description: Congestion Level - -*****************************************************************************/ -typedef struct { - - L3UCHAR IEId; /* 01000111 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR CongLevel; /* Conguestion Level */ - -} Q931ie_CongLevel; - -/***************************************************************************** - - Struct: Q931ie_EndEndTxDelay - - Description: End to end transit delay - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 01000010 */ - L3UCHAR Size; /* Length of Information Element */ - L3ULONG CumTxDelay; /* Cumulative transit delay value */ - L3ULONG ReqTxDelay; /* Requested end to end transit delay */ - L3ULONG MaxTxDelay; /* Maximum transit delay */ - -} Q931ie_EndEndTxDelay; -#endif - -/***************************************************************************** - - Struct: Q931ie_InfoRate - - Description: Information Rate - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 01100000 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR InInfoRate; /* Incoming information rate */ - L3UCHAR OutInfoRate; /* Outgoing information rate */ - L3UCHAR MinInInfoRate; /* Minimum incoming information rate */ - L3UCHAR MinOutInfoRate; /* Minimum outgoing information rate */ - -} Q931ie_InfoRate; -#endif - -/***************************************************************************** - - Struct: Q931ie_PackParam - - Description: Packed layer binary parameters - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 01000100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR FastSel; /* Fast selected */ - L3UCHAR ExpData; /* Exp. data */ - L3UCHAR DelConf; /* Delivery conf */ - L3UCHAR Modulus; /* Modulus */ - -} Q931ie_PackParam; -#endif - -/***************************************************************************** - - Struct: Q931ie_PackWinSize - - Description: Packed window size - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 01000101 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR ForwardValue; /* Forward value */ - L3UCHAR BackwardValue; /* Backward value */ - -} Q931ie_PackWinSize; -#endif - -/***************************************************************************** - - Struct: Q931ie_PackSize - - Description: Packet size - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 01000110 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR ForwardValue; /* Forward value */ - L3UCHAR BackwardValue; /* Backward value */ - -} Q931ie_PackSize; -#endif - -/***************************************************************************** - - Struct: Q931ie_RedirNum - - Description: Redirecting number - -*****************************************************************************/ -#ifdef Q931_X25_SUPPORT -typedef struct { - - L3UCHAR IEId; /* 01110100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR TypeNum; /* Type of number */ - L3UCHAR NumPlanID; /* Number plan identification */ - L3UCHAR PresInd; /* Presentation indicator */ - L3UCHAR ScreenInd; /* Screening indicator */ - L3UCHAR Reason; /* Reason for redirection */ - L3UCHAR Digit[1]; /* Number digits (IA5) */ - -} Q931ie_RedirNum; -#endif - -typedef struct { - - L3UCHAR IEId; /* 01110100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR RepeatInd; /* 0010 Prioritized list for selecting */ - /* one possible. */ -} Q931ie_RepeatInd; - -typedef struct { - - L3UCHAR IEId; /* 01110100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Spare; /* Spare */ - L3UCHAR Class; /* Class */ - /* 000 Indicate channels */ - /* 110 Single interface */ - /* 111 All interfaces */ -} Q931ie_RestartInd; - -typedef struct { - - L3UCHAR IEId; /* 01110100 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Preference; /* Preference 0 = reserved, 1 = channel */ - L3UCHAR Spare; /* Spare */ - L3UCHAR NewStatus; /* NewStatus */ - /* 000 In service */ - /* 001 Maintenance */ - /* 010 Out of service */ -} Q931ie_ChangeStatus; - -/***************************************************************************** - - Struct: Q931ie_GenericDigits - - -*****************************************************************************/ - -typedef struct { - - L3UCHAR IEId; /* 00110111 */ - L3UCHAR Size; /* Length of Information Element */ - L3UCHAR Type; /* Type of number */ - L3UCHAR Encoding; /* Encoding of number */ - L3UCHAR Digit[1]; /* Number digits (IA5) */ - -} Q931ie_GenericDigits; - - -/***************************************************************************** - - Q.931 Information Element Pack/Unpack functions. Implemented in Q931ie.c - -*****************************************************************************/ -q931pie_func_t Q931Pie_ChangeStatus; -q931pie_func_t Q931Pie_BearerCap; -q931pie_func_t Q931Pie_ChanID; -q931pie_func_t Q931Pie_ProgInd; -q931pie_func_t Q931Pie_Display; -q931pie_func_t Q931Pie_Signal; -q931pie_func_t Q931Pie_HLComp; -q931pie_func_t Q931Pie_Segment; -q931pie_func_t Q931Pie_DateTime; -q931pie_func_t Q931Pie_Cause; -q931pie_func_t Q931Pie_SendComplete; -q931pie_func_t Q931Pie_KeypadFac; -q931pie_func_t Q931Pie_NotifInd; -q931pie_func_t Q931Pie_CallID; -q931pie_func_t Q931Pie_RepeatInd; -q931pie_func_t Q931Pie_NetFac; -q931pie_func_t Q931Pie_CallingNum; -q931pie_func_t Q931Pie_CallingSub; -q931pie_func_t Q931Pie_CalledNum; -q931pie_func_t Q931Pie_CalledSub; -q931pie_func_t Q931Pie_CalledNum; -q931pie_func_t Q931Pie_TransNetSel; -q931pie_func_t Q931Pie_LLComp; -q931pie_func_t Q931Pie_CallState; -q931pie_func_t Q931Pie_RestartInd; -q931pie_func_t Q931Pie_UserUser; - -q931pie_func_t Q931Pie_GenericDigits; - -L3USHORT Q931Uie_CRV(Q931_TrunkInfo_t *pTrunk,L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff); - -q931uie_func_t Q931Uie_ChangeStatus; -q931uie_func_t Q931Uie_BearerCap; -q931uie_func_t Q931Uie_ChanID; -q931uie_func_t Q931Uie_ProgInd; -q931uie_func_t Q931Uie_Display; -q931uie_func_t Q931Uie_Signal; -q931uie_func_t Q931Uie_HLComp; -q931uie_func_t Q931Uie_Segment; -q931uie_func_t Q931Uie_DateTime; -q931uie_func_t Q931Uie_Cause; -q931uie_func_t Q931Uie_SendComplete; -q931uie_func_t Q931Uie_KeypadFac; -q931uie_func_t Q931Uie_NotifInd; -q931uie_func_t Q931Uie_CallID; -q931uie_func_t Q931Uie_RepeatInd; -q931uie_func_t Q931Uie_NetFac; -q931uie_func_t Q931Uie_CallingNum; -q931uie_func_t Q931Uie_CallingSub; -q931uie_func_t Q931Uie_CalledNum; -q931uie_func_t Q931Uie_CalledSub; -q931uie_func_t Q931Uie_TransNetSel; -q931uie_func_t Q931Uie_LLComp; -q931uie_func_t Q931Uie_CallState; -q931uie_func_t Q931Uie_RestartInd; -q931uie_func_t Q931Uie_UserUser; - -q931uie_func_t Q931Uie_GenericDigits; - - -L3INT Q931ReadExt(L3UCHAR * IBuf, L3INT Off); -L3INT Q931Uie_CongLevel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); -L3INT Q931Pie_CongLevel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); -L3INT Q931Uie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); -L3INT Q931Pie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); - -L3INT Q931Uie_Generic(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff); -L3INT Q931Pie_Generic(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); - -#endif /* _Q931IE_NL */ diff --git a/libs/freetdm/src/isdn/include/Q932.h b/libs/freetdm/src/isdn/include/Q932.h deleted file mode 100644 index 9b69a34a02..0000000000 --- a/libs/freetdm/src/isdn/include/Q932.h +++ /dev/null @@ -1,95 +0,0 @@ -/***************************************************************************** - - FileName: Q932.h - - Contents: Header w/structs for Q932 Suplementary Services. - - NB: Do NOT include this header directly, include Q931.h - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -/***************************************************************************** - Q.932 Additional Message codes -*****************************************************************************/ - -#define Q932mes_HOLD 0x24 /* 0010 0100 */ -#define Q932mes_HOLD_ACKNOWLEDGE 0x28 /* 0010 1000 */ -#define Q932mes_HOLD_REJECT 0x30 /* 0011 0000 */ -#define Q932mes_RETRIEVE 0x31 /* 0011 0001 */ -#define Q932mes_RETRIEVE_ACKNOWLEDGE 0x33 /* 0011 0011 */ -#define Q932mes_RETRIEVE_REJECT 0x37 /* 0011 0111 */ -#define Q932mes_FACILITY 0x62 /* 0110 0010 */ -#define Q932mes_REGISTER 0x64 /* 0110 0100 */ - -/***************************************************************************** - Q.932 Additional EI Codes -*****************************************************************************/ -#define Q932ie_FACILITY 0x1c /* 0001 1100 */ - -/***************************************************************************** - Function Prototypes. -*****************************************************************************/ -L3INT Q932ProcFacilityTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcHoldTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcHoldAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcHoldRejectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRegisterTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRetrieveTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRetrieveAckTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRetrieveRejectTE(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); - -L3INT Q932ProcFacilityNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcHoldNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcHoldAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcHoldRejectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRegisterNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRetrieveNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRetrieveAckNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); -L3INT Q932ProcRetrieveRejectNT(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT iFrom); - -L3INT Q932Pmes_Facility(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q932Pmes_Hold(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q932Pmes_HoldAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q932Pmes_HoldReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q932Pmes_Register(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q932Pmes_Retrieve(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q932Pmes_RetrieveAck(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); -L3INT Q932Pmes_RetrieveReject(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); - -L3INT Q932Umes_Facility(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); -L3INT Q932Umes_Hold(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); -L3INT Q932Umes_HoldAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); -L3INT Q932Umes_HoldReject(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); -L3INT Q932Umes_Register(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); -L3INT Q932Umes_Retrieve(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); -L3INT Q932Umes_RetrieveAck(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); -L3INT Q932Umes_RetrieveReject(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic * OBuf, L3INT I, L3INT O); diff --git a/libs/freetdm/src/isdn/include/mfifo.h b/libs/freetdm/src/isdn/include/mfifo.h deleted file mode 100644 index 4c1d850d81..0000000000 --- a/libs/freetdm/src/isdn/include/mfifo.h +++ /dev/null @@ -1,85 +0,0 @@ -/***************************************************************************** - - Filename: mfifo.h - - Contents: header for MFIFO - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ -#ifndef _MFIFO -#define _MFIFO - -/***************************************************************************** - - Struct: MINDEX - - Description: Message Index used to index a dynamic size Message FIFO. - -*****************************************************************************/ -typedef struct _mindex { - int offset; /* offset to message in buf */ - int size; /* size of message in bytes */ -} MINDEX; - -/***************************************************************************** - - Struct: MFIFO - - Description: Message FIFO. Provides a dynamic sized message based FIFO - queue. - -*****************************************************************************/ -typedef struct { - int first; /* first out */ - int last; /* last in + 1 */ - int bsize; /* buffer size */ - unsigned char *buf; /* ptr to start of buffer */ - int ixsize; /* index size */ - MINDEX ix[1]; /* message index */ -} MFIFO; - -/***************************************************************************** - Function prototypes. -*****************************************************************************/ -int MFIFOCreate(unsigned char *buf, int size, int index); -void MFIFOClear(unsigned char * buf); -int MFIFOGetLBOffset(unsigned char *buf); -int MFIFOGetFBOffset(unsigned char *buf); -void MFIFOWriteIX(unsigned char *buf, unsigned char *mes, int size, int ix, int off); -int MFIFOWriteMes(unsigned char *buf, unsigned char *mes, int size); -unsigned char * MFIFOGetMesPtr(unsigned char *buf, int *size); -void MFIFOKillNext(unsigned char *buf); - -unsigned char * MFIFOGetMesPtrOffset(unsigned char *buf, int *size, const int pos); -int MFIFOGetMesCount(unsigned char *buf); -int MFIFOWriteMesOverwrite(unsigned char *buf, unsigned char *mes, int size); - -#endif diff --git a/libs/freetdm/src/isdn/include/national.h b/libs/freetdm/src/isdn/include/national.h deleted file mode 100644 index cff26aa4a4..0000000000 --- a/libs/freetdm/src/isdn/include/national.h +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************************************** - - FileName: national.h - - Contents: Header and definition for the National ISDN dialect. The - header contents the following parts: - - Definition of codes - - Definition of information elements (nationalie_). - - Definition of messages (nationalmes_). - - Function prototypes. - - Description: The National ISDN dialect here covers ???? - - Related Files: national.h National ISDN Definitions - nationalie.c National ISDN IE encoders/coders - nationalStateTE.c National ISDN TE State Engine - nationalStateNT.c National ISDN NT State Engine - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -******************************************************************************/ - -#ifndef _national_NATIONAL_NL -#define _national_NATIONAL_NL - -#include "Q931.h" - -/***************************************************************************** - - Q.931 Message codes - Only National specific message and ie types - here the rest are inherited from national.h - -*****************************************************************************/ - - -/***************************************************************************** - - Q.931 Message Pack/Unpack functions. Implemented in nationalmes.c - -*****************************************************************************/ -L3INT nationalUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size); -L3INT nationalPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); - -#include "DMS.h" - -/***************************************************************************** - - Q.931 Process Function Prototyping. Implemented in nationalStateTE.c - -*****************************************************************************/ - -void nationalCreateTE(L3UCHAR i); -void nationalCreateNT(L3UCHAR i); - -#endif /* _national_NATIONAL_NL */ diff --git a/libs/freetdm/src/isdn/mfifo.c b/libs/freetdm/src/isdn/mfifo.c deleted file mode 100644 index 28528f9b64..0000000000 --- a/libs/freetdm/src/isdn/mfifo.c +++ /dev/null @@ -1,399 +0,0 @@ -/***************************************************************************** - - Filename: mfifo.c - - Description: mfifo is a message orriented fifo system with support of - both message and byte per byte retriaval of messages. - - The fifo has been designed with two usages in mind: - - - Queueing of frames for hdlc and feeding out byte per byte - with the possibility of re-sending of frames etc. - - - fifo for messages of dynamic size. - - The fifo is allocated on top of any buffer and creates an - index of message in the queue. The user can write/read - messages or write messages and read the message one byte - at the time. - - Interface: - MFIFOCreate Create/reset/initialize fifo. - MFIFOClear Clear FIFO. - MFIFOWriteMes Write message into fifo - * MFIFOReadMes Read message from fifo. - MFIFOGetMesPtr Get ptr to next message. - MFIFOKillNext Kill next message. - - * currently not implemented. - - Note: The message will always be saved continuously. If there is not - sufficient space at the end of the buffer, the fifo will skip - the last bytes and save the message at the top of the buffer. - - This is required to allow direct ptr access to messages - stored in the queue. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "mfifo.h" -#include -#include - -/***************************************************************************** - - Function: MFIFOCreate - - Description: Creates a fifo on top of an existing buffer. - - Parameters: buf ptr to buffer. - size size of buffer in bytes. - index size of index entries (max no messages). - - Return value: 0 if failure, 1 if ok. - -*****************************************************************************/ -int MFIFOCreate(unsigned char *buf, int size, int index) -{ - MFIFO *mf = (MFIFO *)buf; - - mf->first = mf->last = 0; - mf->ixsize = index; - mf->buf = &buf[sizeof(MFIFO) + (sizeof(MINDEX) * index)]; - - if (mf->buf > &buf[size]) - return 0; - - mf->bsize = size - sizeof(MFIFO) - (sizeof(MINDEX) * index); - - return 1; -} - -/***************************************************************************** - - Function: MFIFOClear - - Description: Clear the FIFO - - Paremeters: buf ptr to fifo - - Return Value: none - -*****************************************************************************/ -void MFIFOClear(unsigned char * buf) -{ - MFIFO *mf = (MFIFO *)buf; - - mf->first = mf->last = 0; -} - -/***************************************************************************** - - Function: MFIFOGetLBOffset - - Description: Helper function caclulating offset to the 'first out' byte. - - Paremeters: buf ptr to fifo - - Return Value: offset. - -*****************************************************************************/ -int MFIFOGetLBOffset(unsigned char *buf) -{ - MFIFO *mf = (MFIFO *)buf; - - if (mf->last != mf->first) - return mf->ix[mf->last].offset; - - return 0; -} - -/***************************************************************************** - - Function: MFIFOGetFBOffset - - Description: Helper function calculating the offset to the 'first in' - byte in the buffer. This is the position the next byte - entering the fifo will occupy. - - Paremeters: buf ptr to fifo - - Return Value: offset - -*****************************************************************************/ -int MFIFOGetFBOffset(unsigned char *buf) -{ - MFIFO *mf = (MFIFO *)buf; - int x; - - if (mf->last == mf->first) - return 0; - - x = mf->first - 1; - - if (x < 0) - x = mf->ixsize - 1; - - return mf->ix[x].offset + mf->ix[x].size; -} - -/***************************************************************************** - - Function: MFIFOWriteIX - - Description: Helper function writing a calculated entry. The function - will perform a memcpy to move the message and set the index - values as well as increase the 'first in' index. - - Paremeters: buf ptr to fifo - mes ptr to message - size size of message in bytes. - ix index to index entry. - off offset to position to receive the message - - Return Value: none - -*****************************************************************************/ -void MFIFOWriteIX(unsigned char *buf, unsigned char *mes, int size, int ix, int off) -{ - MFIFO *mf = (MFIFO *)buf; - int x; - - memcpy(&mf->buf[off], mes, size); - mf->ix[ix].offset = off; - mf->ix[ix].size = size; - - x = mf->first + 1; - - if (x >= mf->ixsize) - x = 0; - - mf->first = x; -} - -/***************************************************************************** - - Function: MFIFOWriteMes - - Description: - - Paremeters: - - Return Value: - -*****************************************************************************/ -int MFIFOWriteMes(unsigned char *buf, unsigned char *mes, int size) -{ - MFIFO *mf = (MFIFO *)buf; - int of, ol, x; - - x = mf->first + 1; - - if (x >= mf->ixsize) - x = 0; - - if (x == mf->last) - return 0; /* full queue */ - - of = MFIFOGetFBOffset(buf); - ol = MFIFOGetLBOffset(buf); - if (mf->last == mf->first) { /* empty queue */ - mf->first = mf->last = 0; /* optimize */ - - MFIFOWriteIX(buf, mes, size, mf->first, 0); - return 1; - } - else if (of > ol) { - if (mf->bsize - of >= size) { - MFIFOWriteIX(buf, mes, size, mf->first, of); - return 1; - } - else if (ol > size) { - MFIFOWriteIX(buf, mes, size, mf->first, ol); - return 1; - } - } - else if (ol - of > size) { - MFIFOWriteIX(buf, mes, size, mf->first, of); - return 1; - } - - return 0; -} - -/***************************************************************************** - - Function: MFIFOGetMesPtr - - Description: - - Paremeters: - - Return Value: - -*****************************************************************************/ -unsigned char * MFIFOGetMesPtr(unsigned char *buf, int *size) -{ - MFIFO *mf = (MFIFO *)buf; - - if (mf->first == mf->last) { - return NULL; - } - - *size = mf->ix[mf->last].size; - return &mf->buf[mf->ix[mf->last].offset]; -} - -/***************************************************************************** - - Function: MFIFOKillNext - - Description: - - Paremeters: - - Return Value: - -*****************************************************************************/ -void MFIFOKillNext(unsigned char *buf) -{ - MFIFO *mf = (MFIFO *)buf; - int x; - - if (mf->first != mf->last) { - x = mf->last + 1; - if (x >= mf->ixsize) { - x = 0; - } - - mf->last = x; - } -} - - -/* - * Queue-style accessor functions - */ - -/** - * MFIFOGetMesPtrOffset - * \brief Get pointer to and size of message at position x - */ -unsigned char * MFIFOGetMesPtrOffset(unsigned char *buf, int *size, const int pos) -{ - MFIFO *mf = (MFIFO *)buf; - int x; - - if (mf->first == mf->last) { - return NULL; - } - - if (pos < 0 || pos >= mf->ixsize) { - return NULL; - } - - x = pos - mf->last; - if (x < 0) { - x += (mf->ixsize - 1); - } - - *size = mf->ix[x].size; - return &mf->buf[mf->ix[x].offset]; -} - - -/** - * MFIFOGetMesCount - * \brief How many messages are currently in the buffer? - */ -int MFIFOGetMesCount(unsigned char *buf) -{ - MFIFO *mf = (MFIFO *)buf; - - if (mf->first == mf->last) { - return 0; - } - else if (mf->first > mf->last) { - return mf->first - mf->last; - } - else { - return (mf->ixsize - mf->last) + mf->first; - } -} - -/** - * MFIFOWriteMesOverwrite - * \brief Same as MFIFOWriteMes but old frames will be overwritten if the fifo is full - */ -int MFIFOWriteMesOverwrite(unsigned char *buf, unsigned char *mes, int size) -{ - MFIFO *mf = (MFIFO *)buf; - int of, ol, x; - - x = mf->first + 1; - - if (x >= mf->ixsize) - x = 0; - - if (x == mf->last) { - /* advance last pointer */ - mf->last++; - - if (mf->last >= mf->ixsize) - mf->last = 0; - } - - of = MFIFOGetFBOffset(buf); - ol = MFIFOGetLBOffset(buf); - - if (mf->last == mf->first) { /* empty queue */ - mf->first = mf->last = 0; /* optimize */ - - MFIFOWriteIX(buf, mes, size, mf->first, 0); - return 1; - } - else if (of > ol) { - if (mf->bsize - of >= size) { - MFIFOWriteIX(buf, mes, size, mf->first, of); - return 1; - } - else if (ol > size) { - MFIFOWriteIX(buf, mes, size, mf->first, ol); - return 1; - } - } - else if (ol - of > size) { - MFIFOWriteIX(buf, mes, size, mf->first, of); - return 1; - } - return 0; -} diff --git a/libs/freetdm/src/isdn/nationalStateNT.c b/libs/freetdm/src/isdn/nationalStateNT.c deleted file mode 100644 index b150999650..0000000000 --- a/libs/freetdm/src/isdn/nationalStateNT.c +++ /dev/null @@ -1,130 +0,0 @@ -/***************************************************************************** - - FileName: nationalStateNT.c - - Contents: National ISDN State Engine for NT (Network Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "national.h" - -/***************************************************************************** - Function: nationalCreateNT - - Description: Will create the National ISDN NT as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void nationalCreateNT(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingNT, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingNT, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, Q931ProcConnectNT, Q931Umes_Connect, Q931Pmes_Connect); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, Q931ProcConnectAckNT, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressNT, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupNT, nationalUmes_Setup, nationalPmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckNT, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeNT, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckNT, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectNT, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendNT, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckNT, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectNT, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationNT, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectNT, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseNT, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteNT, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartNT, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckNT, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlNT, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationNT, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyNT, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusNT, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryNT, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentNT, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityNT, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldNT, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckNT, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectNT, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterNT, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveNT, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckNT, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectNT, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - Q931SetIEProc(Q931ie_GENERIC_DIGITS, i, Q931Pie_GenericDigits, Q931Uie_GenericDigits); - - Q931SetIEProc(Q931ie_CONNECTED_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_FACILITY, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_REDIRECTING_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - - /* The following define a state machine. The point is that the Message */ - /* procs can when search this to find out if the message/state */ - /* combination is legale. If not, the proc for unexpected message apply.*/ - - /* TODO define state table here */ -} diff --git a/libs/freetdm/src/isdn/nationalStateTE.c b/libs/freetdm/src/isdn/nationalStateTE.c deleted file mode 100644 index 46731d0910..0000000000 --- a/libs/freetdm/src/isdn/nationalStateTE.c +++ /dev/null @@ -1,217 +0,0 @@ -/***************************************************************************** - - FileName: nationalStateTE.c - - Contents: National ISDN State Engine for TE (User Mode). - - The controlling state engine for Q.931 is the state engine - on the NT side. The state engine on the TE side is a slave - of this. The TE side maintain it's own states as described in - ITU-T Q931, but will in raise conditions be overridden by - the NT side. - - This reference implementation uses a process per message, - meaning that each message must check call states. This - is easier for dialect maintenance as each message proc - can be replaced individually. A new TE variant only - need to copy the Q931CreateTE and replace those procs or - need to override. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*****************************************************************************/ - -#include "national.h" -extern L3INT Q931L4HeaderSpace; - -/***************************************************************************** - Function: nationalCreateTE - - Description: Will create the National TE as a Dialect in the stack. The first - bulk set up the message handlers, the second bulk the IE - encoders/coders, and the last bulk set up the state table. - - Parameters: i Dialect index -*****************************************************************************/ -void nationalCreateTE(L3UCHAR i) -{ - Q931SetMesProc(Q931mes_ALERTING, i, Q931ProcAlertingTE, Q931Umes_Alerting, Q931Pmes_Alerting); - Q931SetMesProc(Q931mes_CALL_PROCEEDING, i, Q931ProcCallProceedingTE, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); - Q931SetMesProc(Q931mes_CONNECT, i, DMSProc0x07TE, DMSUmes_0x07, DMSPmes_0x07); - Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i, DMSProc0x0fTE, DMSUmes_0x0f, DMSPmes_0x0f); - Q931SetMesProc(Q931mes_PROGRESS, i, Q931ProcProgressTE, Q931Umes_Progress, Q931Pmes_Progress); - Q931SetMesProc(Q931mes_SETUP, i, Q931ProcSetupTE, nationalUmes_Setup, nationalPmes_Setup); - Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i, Q931ProcSetupAckTE, Q931Umes_SetupAck, Q931Pmes_SetupAck); - Q931SetMesProc(Q931mes_RESUME, i, Q931ProcResumeTE, Q931Umes_Resume, Q931Pmes_Resume); - Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i, Q931ProcResumeAckTE, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); - Q931SetMesProc(Q931mes_RESUME_REJECT, i, Q931ProcResumeRejectTE, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); - Q931SetMesProc(Q931mes_SUSPEND, i, Q931ProcSuspendTE, Q931Umes_Suspend, Q931Pmes_Suspend); - Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i, Q931ProcSuspendAckTE, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); - Q931SetMesProc(Q931mes_SUSPEND_REJECT, i, Q931ProcSuspendRejectTE, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); - Q931SetMesProc(Q931mes_USER_INFORMATION, i, Q931ProcUserInformationTE, Q931Umes_UserInformation, Q931Pmes_UserInformation); - Q931SetMesProc(Q931mes_DISCONNECT, i, Q931ProcDisconnectTE, Q931Umes_Disconnect, Q931Pmes_Disconnect); - Q931SetMesProc(Q931mes_RELEASE, i, Q931ProcReleaseTE, Q931Umes_Release, Q931Pmes_Release); - Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i, Q931ProcReleaseCompleteTE, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); - Q931SetMesProc(Q931mes_RESTART, i, Q931ProcRestartTE, Q931Umes_Restart, Q931Pmes_Restart); - Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i, Q931ProcRestartAckTE, Q931Umes_RestartAck, Q931Pmes_RestartAck); - Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i, Q931ProcCongestionControlTE, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); - Q931SetMesProc(Q931mes_INFORMATION, i, Q931ProcInformationTE, Q931Umes_Information, Q931Pmes_Information); - Q931SetMesProc(Q931mes_NOTIFY, i, Q931ProcNotifyTE, Q931Umes_Notify, Q931Pmes_Notify); - Q931SetMesProc(Q931mes_STATUS, i, Q931ProcStatusTE, Q931Umes_Status, Q931Pmes_Status); - Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i, Q931ProcStatusEnquiryTE, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); - Q931SetMesProc(Q931mes_SEGMENT, i, Q931ProcSegmentTE, Q931Umes_Segment, Q931Pmes_Segment); - - Q931SetMesProc(Q932mes_FACILITY, i, Q932ProcFacilityTE, Q932Umes_Facility, Q932Pmes_Facility); - Q931SetMesProc(Q932mes_HOLD, i, Q932ProcHoldTE, Q932Umes_Hold, Q932Pmes_Hold); - Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i, Q932ProcHoldAckTE, Q932Umes_HoldAck, Q932Pmes_HoldAck); - Q931SetMesProc(Q932mes_HOLD_REJECT, i, Q932ProcHoldRejectTE, Q932Umes_HoldReject, Q932Pmes_HoldReject); - Q931SetMesProc(Q932mes_REGISTER, i, Q932ProcRegisterTE, Q932Umes_Register, Q932Pmes_Register); - Q931SetMesProc(Q932mes_RETRIEVE, i, Q932ProcRetrieveTE, Q932Umes_Retrieve, Q932Pmes_Retrieve); - Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE, i, Q932ProcRetrieveAckTE, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); - Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i, Q932ProcRetrieveRejectTE, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); - - /* Set up the IE encoder/decoder handle table.*/ - Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i, Q931Pie_Segment, Q931Uie_Segment); - Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i, Q931Pie_BearerCap, Q931Uie_BearerCap); - Q931SetIEProc(Q931ie_CAUSE, i, Q931Pie_Cause, Q931Uie_Cause); - Q931SetIEProc(Q931ie_CALL_IDENTITY, i, Q931Pie_CallID, Q931Uie_CallID); - Q931SetIEProc(Q931ie_CALL_STATE, i, Q931Pie_CallState, Q931Uie_CallState); - Q931SetIEProc(Q931ie_CHANGE_STATUS, i, Q931Pie_ChangeStatus, Q931Uie_ChangeStatus); - Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i, Q931Pie_ChanID, Q931Uie_ChanID); - Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i, Q931Pie_ProgInd, Q931Uie_ProgInd); - Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i, Q931Pie_NetFac, Q931Uie_NetFac); - Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i, Q931Pie_NotifInd, Q931Uie_NotifInd); - Q931SetIEProc(Q931ie_DISPLAY, i, Q931Pie_Display, Q931Uie_Display); - Q931SetIEProc(Q931ie_DATETIME, i, Q931Pie_DateTime, Q931Uie_DateTime); - Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i, Q931Pie_KeypadFac, Q931Uie_KeypadFac); - Q931SetIEProc(Q931ie_SIGNAL, i, Q931Pie_Signal, Q931Uie_Signal); - Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i, Q931Pie_CallingNum, Q931Uie_CallingNum); - Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i, Q931Pie_CallingSub, Q931Uie_CallingSub); - Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i, Q931Pie_CalledNum, Q931Uie_CalledNum); - Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i, Q931Pie_CalledSub, Q931Uie_CalledSub); - Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i, Q931Pie_TransNetSel, Q931Uie_TransNetSel); - Q931SetIEProc(Q931ie_RESTART_INDICATOR, i, Q931Pie_RestartInd, Q931Uie_RestartInd); - Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i, Q931Pie_LLComp, Q931Uie_LLComp); - Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i, Q931Pie_HLComp, Q931Uie_HLComp); - Q931SetIEProc(Q931ie_USER_USER, i, Q931Pie_UserUser, Q931Uie_UserUser); - Q931SetIEProc(Q931ie_GENERIC_DIGITS, i, Q931Pie_GenericDigits, Q931Uie_GenericDigits); - - Q931SetIEProc(Q931ie_CONNECTED_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_FACILITY, i, Q931Pie_Generic, Q931Uie_Generic); - Q931SetIEProc(Q931ie_REDIRECTING_NUMBER, i, Q931Pie_Generic, Q931Uie_Generic); - - /* The following define a state machine. The point is that the Message - * procs can when search this to find out if the message/state - * combination is legale. If not, the proc for unexpected message apply. - */ - - /* State 0 Idle */ - Q931AddStateEntry(i, Q931_U0, Q931mes_RESUME, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_SETUP, 2); - Q931AddStateEntry(i, Q931_U0, Q931mes_STATUS, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U0, Q931mes_RELEASE_COMPLETE, 4); - - /* State 1 Call Initiating */ - Q931AddStateEntry(i, Q931_U1, Q931mes_DISCONNECT, 2); - Q931AddStateEntry(i, Q931_U1, Q931mes_SETUP_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_RELEASE_COMPLETE, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U1, Q931mes_CONNECT, 4); - - /* State 2 Overlap Sending */ - Q931AddStateEntry(i, Q931_U2, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U2, Q931mes_CALL_PROCEEDING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U2, Q931mes_RELEASE, 2); - - /* State 3 Outgoing Call Proceeding */ - Q931AddStateEntry(i, Q931_U3, Q931mes_PROGRESS, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_ALERTING, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_CONNECT, 4); - Q931AddStateEntry(i, Q931_U3, Q931mes_RELEASE, 2); - - /* State 4 Call Delivered */ - Q931AddStateEntry(i, Q931_U4, Q931mes_CONNECT, 4); - - /* State 6 Call Precent */ - Q931AddStateEntry(i, Q931_U6, Q931mes_INFORMATION, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CALL_PROCEEDING, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE_COMPLETE, 2); - Q931AddStateEntry(i, Q931_U6, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U6, Q931mes_DISCONNECT, 4); - - /* State 7 Call Received */ - Q931AddStateEntry(i, Q931_U7, Q931mes_CONNECT, 2); - - /* State 8 Connect request */ - Q931AddStateEntry(i, Q931_U8, Q931mes_CONNECT_ACKNOWLEDGE, 4); - - /* State 9 Incoming Call Proceeding */ - Q931AddStateEntry(i, Q931_U9, Q931mes_CONNECT, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_ALERTING, 2); - Q931AddStateEntry(i, Q931_U9, Q931mes_PROGRESS, 2); - - /* State 10 Active */ - Q931AddStateEntry(i, Q931_U10, Q931mes_SUSPEND, 2); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 4); - Q931AddStateEntry(i, Q931_U10, Q931mes_NOTIFY, 2); - - /* State 11 Disconnect Request */ - Q931AddStateEntry(i, Q931_U11, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U11, Q931mes_NOTIFY, 4); - - /* State 12 Disconnect Ind */ - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 4); - Q931AddStateEntry(i, Q931_U12, Q931mes_RELEASE, 2); - - /* State 15 Suspend Request */ - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_ACKNOWLEDGE, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_SUSPEND_REJECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_DISCONNECT, 4); - Q931AddStateEntry(i, Q931_U15, Q931mes_RELEASE, 4); - -/* TODO - Q931AddStateEntry(i, Q931_U17, - Q931AddStateEntry(i, Q931_U19, - Q931AddStateEntry(i, Q931_U25, -*/ -} diff --git a/libs/freetdm/src/isdn/nationalmes.c b/libs/freetdm/src/isdn/nationalmes.c deleted file mode 100644 index 6d8350fbcd..0000000000 --- a/libs/freetdm/src/isdn/nationalmes.c +++ /dev/null @@ -1,269 +0,0 @@ -/***************************************************************************** - - FileName: nationalmes.c - - Contents: Pack/Unpack functions. These functions will unpack a National ISDN - message from the bit packed original format into structs - that contains variables sized by the user. It will also pack - the struct back into a Q.931 message as required. - - See national.h for description. - - License/Copyright: - - Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. - email:janvb@caselaboratories.com - - Copyright (c) 2007, Michael Jerris. All rights reserved. - email:mike@jerris.com - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the Case Labs, Ltd nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -*****************************************************************************/ - -#include "national.h" - -/***************************************************************************** - - Function: nationalUmes_Setup - -*****************************************************************************/ -L3INT nationalUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size) -{ - L3INT ir = 0; - L3INT OOff = 0; - L3INT rc = Q931E_NO_ERROR; - L3UCHAR last_codeset = 0, codeset = 0; - L3UCHAR shift_lock = 1; - - while (IOff < Size) { - if (!shift_lock) { - codeset = last_codeset; - } - - if ((IBuf[IOff] & 0xF0) == Q931ie_SHIFT ) { - shift_lock = (IBuf[IOff] & 0x08); - if (shift_lock) { - last_codeset = codeset; - } - codeset = ((IBuf[IOff] & 0x07)); - IOff++; - } - - if (codeset == 0) { - switch (IBuf[IOff]) { - case Q931ie_SENDING_COMPLETE: - case Q931ie_BEARER_CAPABILITY: - case Q931ie_CHANNEL_IDENTIFICATION: - case Q931ie_PROGRESS_INDICATOR: - case Q931ie_NETWORK_SPECIFIC_FACILITIES: - case Q931ie_DISPLAY: - case Q931ie_DATETIME: - case Q931ie_KEYPAD_FACILITY: - case Q931ie_SIGNAL: - case Q931ie_CALLING_PARTY_NUMBER: - case Q931ie_CALLING_PARTY_SUBADDRESS: - case Q931ie_CALLED_PARTY_NUMBER: - case Q931ie_CALLED_PARTY_SUBADDRESS: - case Q931ie_TRANSIT_NETWORK_SELECTION: - case Q931ie_LOW_LAYER_COMPATIBILITY: - case Q931ie_HIGH_LAYER_COMPATIBILITY: - case Q931ie_FACILITY: - case Q931ie_REDIRECTING_NUMBER: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - case Q931ie_REPEAT_INDICATOR: - if (ir < 2) { - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - ir++; - } else { - return Q931E_ILLEGAL_IE; - } - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - } else if (codeset == 6) { - switch (IBuf[IOff]) { - case Q931ie_GENERIC_DIGITS: - rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff); - if (rc != Q931E_NO_ERROR) - return rc; - break; - default: - return Q931E_ILLEGAL_IE; - break; - } - - } else { - return Q931E_ILLEGAL_IE; - } - } - mes->Size = sizeof(Q931mes_Generic) - 1 + OOff; - return Q931E_NO_ERROR; -} - -/***************************************************************************** - - Function: nationalPmes_Setup - - Decription: Pack a Q931mes_Generic into a real Q.931 message. The user will - set up a SETUP message and issue this to the stack where it - is processed by Q931ProcSetup that processes and validates - it before it actually sends it out. This function is called - to compute the real Q.931 message. - - Parameters: IBuf[IN] Ptr to un-packed struct - ISize[IN] Size of input buffer (unpacked message). - OBuf[OUT] Ptr to packed 'octet' wise message. - OSize[OUT] Size of packed message. - - Called By: Q931ProcSetup - -*****************************************************************************/ -L3INT nationalPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) -{ - L3INT rc = Q931E_NO_ERROR; - Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf; - L3INT Octet = 0; - - /* Q931 Message Header */ - Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet); - - /* Sending Complete */ - if (Q931IsIEPresent(pMes->SendComplete)) { - OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff); - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->RepeatInd)) { - OBuf[Octet++] = (L3UCHAR)(pMes->RepeatInd & 0x00ff); - } - - /* Bearer capability */ - if (Q931IsIEPresent(pMes->BearerCap)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - else { - rc = Q931E_BEARERCAP; - } - - /* Channel Identification */ - if (Q931IsIEPresent(pMes->ChanID)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Progress indicator */ - if (Q931IsIEPresent(pMes->ProgInd)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Network spesific facilities */ - if (Q931IsIEPresent(pMes->NetFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_NETWORK_SPECIFIC_FACILITIES](pTrunk, Q931GetIEPtr(pMes->NetFac,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Display */ - if (Q931IsIEPresent(pMes->Display)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Date/Time */ - if (Q931IsIEPresent(pMes->DateTime)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DATETIME](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Keypad Facility */ - if (Q931IsIEPresent(pMes->KeypadFac)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_KEYPAD_FACILITY](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Signal */ - if (Q931IsIEPresent(pMes->Signal)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Calling Party Number */ - if (Q931IsIEPresent(pMes->CallingNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CallingNum,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Calling Party Subaddress */ - if (Q931IsIEPresent(pMes->CallingSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CallingSub,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Called Party number */ - if (Q931IsIEPresent(pMes->CalledNum)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Called party subaddress */ - if (Q931IsIEPresent(pMes->CalledSub)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CalledSub,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Transit network selection */ - if (Q931IsIEPresent(pMes->TransNetSel)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_TRANSIT_NETWORK_SELECTION](pTrunk, Q931GetIEPtr(pMes->TransNetSel,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* Repeat Indicator */ - if (Q931IsIEPresent(pMes->LLRepeatInd)) { - rc = Q931E_UNKNOWN_IE;/* TODO */ - } - - /* Low Layer Compatibility */ - if (Q931IsIEPresent(pMes->LLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_LOW_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - /* High Layer Compatibility */ - if (Q931IsIEPresent(pMes->HLComp)) { - if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet)) != 0) - return rc; - } - - *OSize = Octet; - return rc; -} diff --git a/libs/freetdm/src/libteletone_detect.c b/libs/freetdm/src/libteletone_detect.c deleted file mode 100644 index b89ea11645..0000000000 --- a/libs/freetdm/src/libteletone_detect.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * libteletone - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF. - * - * - * The Initial Developer of the Original Code is - * Stephen Underwood - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * The the original interface designed by Steve Underwood was preserved to retain - *the optimizations when considering DTMF tones though the names were changed in the interest - * of namespace. - * - * Much less efficient expansion interface was added to allow for the detection of - * a single arbitrary tone combination which may also exceed 2 simultaneous tones. - * (controlled by compile time constant TELETONE_MAX_TONES) - * - * Copyright (C) 2006 Anthony Minessale II - * - * - * libteletone_detect.c Tone Detection Code - * - * - ********************************************************************************* - * - * Derived from tone_detect.c - General telephony tone detection, and specific - * detection of DTMF. - * - * Copyright (C) 2001 Steve Underwood - * - * Despite my general liking of the GPL, I place this code in the - * public domain for the benefit of all mankind - even the slimy - * ones who might try to proprietize my work and use it to my - * detriment. - * - * - * Exception: - * The author hereby grants the use of this source code under the - * following license if and only if the source code is distributed - * as part of the OpenZAP or FreeTDM library. Any use or distribution of this - * source code outside the scope of the OpenZAP or FreeTDM library will nullify the - * following license and reinact the MPL 1.1 as stated above. - * - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#ifndef _MSC_VER -#include -#endif -#include -#include -#include -#include - -#define LOW_ENG 10000000 -#define ZC 2 -static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR]; -static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR]; -static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR]; -static teletone_detection_descriptor_t dtmf_detect_col_2nd[GRID_FACTOR]; - -static float dtmf_row[] = {697.0f, 770.0f, 852.0f, 941.0f}; -static float dtmf_col[] = {1209.0f, 1336.0f, 1477.0f, 1633.0f}; - -static char dtmf_positions[] = "123A" "456B" "789C" "*0#D"; - -static void goertzel_init(teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc) { - goertzel_state->v2 = goertzel_state->v3 = 0.0; - goertzel_state->fac = tdesc->fac; -} - -TELETONE_API(void) teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state, - int16_t sample_buffer[], - int samples) -{ - int i; - float v1; - - for (i = 0; i < samples; i++) { - v1 = goertzel_state->v2; - goertzel_state->v2 = goertzel_state->v3; - goertzel_state->v3 = (float)(goertzel_state->fac*goertzel_state->v2 - v1 + sample_buffer[i]); - } -} -#ifdef _MSC_VER -#pragma warning(disable:4244) -#endif - -#define teletone_goertzel_result(gs) (double)(((gs)->v3 * (gs)->v3 + (gs)->v2 * (gs)->v2 - (gs)->v2 * (gs)->v3 * (gs)->fac)) - -TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate) -{ - int i; - float theta; - - dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0; - - for (i = 0; i < GRID_FACTOR; i++) { - theta = (float)(M_TWO_PI*(dtmf_row[i]/(float)sample_rate)); - dtmf_detect_row[i].fac = (float)(2.0*cos(theta)); - - theta = (float)(M_TWO_PI*(dtmf_col[i]/(float)sample_rate)); - dtmf_detect_col[i].fac = (float)(2.0*cos(theta)); - - theta = (float)(M_TWO_PI*(dtmf_row[i]*2.0/(float)sample_rate)); - dtmf_detect_row_2nd[i].fac = (float)(2.0*cos(theta)); - - theta = (float)(M_TWO_PI*(dtmf_col[i]*2.0/(float)sample_rate)); - dtmf_detect_col_2nd[i].fac = (float)(2.0*cos(theta)); - - goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]); - goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]); - goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]); - goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]); - - dtmf_detect_state->energy = 0.0; - } - dtmf_detect_state->current_sample = 0; - dtmf_detect_state->detected_digits = 0; - dtmf_detect_state->lost_digits = 0; - dtmf_detect_state->digit = 0; - dtmf_detect_state->dur = 0; -} - -TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map) -{ - float theta = 0; - int x = 0; - - if (!mt->sample_rate) { - mt->sample_rate = 8000; - } - - if (!mt->min_samples) { - mt->min_samples = 102; - } - - mt->min_samples *= (mt->sample_rate / 8000); - - if (!mt->positive_factor) { - mt->positive_factor = 2; - } - - if(!mt->negative_factor) { - mt->negative_factor = 10; - } - - if (!mt->hit_factor) { - mt->hit_factor = 2; - } - - for(x = 0; x < TELETONE_MAX_TONES; x++) { - if ((int) map->freqs[x] == 0) { - break; - } - mt->tone_count++; - theta = (float)(M_TWO_PI*(map->freqs[x]/(float)mt->sample_rate)); - mt->tdd[x].fac = (float)(2.0 * cos(theta)); - goertzel_init (&mt->gs[x], &mt->tdd[x]); - goertzel_init (&mt->gs2[x], &mt->tdd[x]); - } - -} - -TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt, - int16_t sample_buffer[], - int samples) -{ - int sample, limit = 0, j, x = 0; - float v1, famp; - float eng_sum = 0, eng_all[TELETONE_MAX_TONES] = {0.0}; - int gtest = 0, see_hit = 0; - - for (sample = 0; sample >= 0 && sample < samples; sample = limit) { - mt->total_samples++; - - if ((samples - sample) >= (mt->min_samples - mt->current_sample)) { - limit = sample + (mt->min_samples - mt->current_sample); - } else { - limit = samples; - } - if (limit < 0 || limit > samples) { - limit = samples; - } - - for (j = sample; j < limit; j++) { - famp = sample_buffer[j]; - - mt->energy += famp*famp; - - for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) { - v1 = mt->gs[x].v2; - mt->gs[x].v2 = mt->gs[x].v3; - mt->gs[x].v3 = (float)(mt->gs[x].fac * mt->gs[x].v2 - v1 + famp); - - v1 = mt->gs2[x].v2; - mt->gs2[x].v2 = mt->gs2[x].v3; - mt->gs2[x].v3 = (float)(mt->gs2[x].fac*mt->gs2[x].v2 - v1 + famp); - } - } - - mt->current_sample += (limit - sample); - if (mt->current_sample < mt->min_samples) { - continue; - } - - eng_sum = 0; - for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) { - eng_all[x] = (float)(teletone_goertzel_result (&mt->gs[x])); - eng_sum += eng_all[x]; - } - - gtest = 0; - for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) { - gtest += teletone_goertzel_result (&mt->gs2[x]) < eng_all[x] ? 1 : 0; - } - - if ((gtest >= 2 || gtest == mt->tone_count) && eng_sum > 42.0 * mt->energy) { - if(mt->negatives) { - mt->negatives--; - } - mt->positives++; - - if(mt->positives >= mt->positive_factor) { - mt->hits++; - } - if (mt->hits >= mt->hit_factor) { - see_hit++; - mt->positives = mt->negatives = mt->hits = 0; - } - } else { - mt->negatives++; - if(mt->positives) { - mt->positives--; - } - if(mt->negatives > mt->negative_factor) { - mt->positives = mt->hits = 0; - } - } - - /* Reinitialise the detector for the next block */ - for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) { - goertzel_init (&mt->gs[x], &mt->tdd[x]); - goertzel_init (&mt->gs2[x], &mt->tdd[x]); - } - - mt->energy = 0.0; - mt->current_sample = 0; - } - - return see_hit; -} - - -TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state, - int16_t sample_buffer[], - int samples) -{ - float row_energy[GRID_FACTOR]; - float col_energy[GRID_FACTOR]; - float famp; - float v1; - int i; - int j; - int sample; - int best_row; - int best_col; - char hit; - int limit; - teletone_hit_type_t r = 0; - - hit = 0; - for (sample = 0; sample < samples; sample = limit) { - /* BLOCK_LEN is optimised to meet the DTMF specs. */ - if ((samples - sample) >= (BLOCK_LEN - dtmf_detect_state->current_sample)) { - limit = sample + (BLOCK_LEN - dtmf_detect_state->current_sample); - } else { - limit = samples; - } - - for (j = sample; j < limit; j++) { - int x = 0; - famp = sample_buffer[j]; - - dtmf_detect_state->energy += famp*famp; - - for(x = 0; x < GRID_FACTOR; x++) { - v1 = dtmf_detect_state->row_out[x].v2; - dtmf_detect_state->row_out[x].v2 = dtmf_detect_state->row_out[x].v3; - dtmf_detect_state->row_out[x].v3 = (float)(dtmf_detect_state->row_out[x].fac*dtmf_detect_state->row_out[x].v2 - v1 + famp); - - v1 = dtmf_detect_state->col_out[x].v2; - dtmf_detect_state->col_out[x].v2 = dtmf_detect_state->col_out[x].v3; - dtmf_detect_state->col_out[x].v3 = (float)(dtmf_detect_state->col_out[x].fac*dtmf_detect_state->col_out[x].v2 - v1 + famp); - - v1 = dtmf_detect_state->col_out2nd[x].v2; - dtmf_detect_state->col_out2nd[x].v2 = dtmf_detect_state->col_out2nd[x].v3; - dtmf_detect_state->col_out2nd[x].v3 = (float)(dtmf_detect_state->col_out2nd[x].fac*dtmf_detect_state->col_out2nd[x].v2 - v1 + famp); - - v1 = dtmf_detect_state->row_out2nd[x].v2; - dtmf_detect_state->row_out2nd[x].v2 = dtmf_detect_state->row_out2nd[x].v3; - dtmf_detect_state->row_out2nd[x].v3 = (float)(dtmf_detect_state->row_out2nd[x].fac*dtmf_detect_state->row_out2nd[x].v2 - v1 + famp); - } - - } - - if (dtmf_detect_state->zc > 0) { - if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) { - if (!--dtmf_detect_state->zc) { - /* Reinitialise the detector for the next block */ - dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0; - for (i = 0; i < GRID_FACTOR; i++) { - goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]); - goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]); - goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]); - goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]); - } - dtmf_detect_state->dur -= samples; - return TT_HIT_END; - } - } - - dtmf_detect_state->dur += samples; - dtmf_detect_state->lenergy = dtmf_detect_state->energy; - dtmf_detect_state->energy = 0.0; - dtmf_detect_state->current_sample = 0; - return TT_HIT_MIDDLE; - } else if (dtmf_detect_state->digit) { - return TT_HIT_END; - } - - - dtmf_detect_state->current_sample += (limit - sample); - if (dtmf_detect_state->current_sample < BLOCK_LEN) { - continue; - } - /* We are at the end of a DTMF detection block */ - /* Find the peak row and the peak column */ - row_energy[0] = teletone_goertzel_result (&dtmf_detect_state->row_out[0]); - col_energy[0] = teletone_goertzel_result (&dtmf_detect_state->col_out[0]); - - for (best_row = best_col = 0, i = 1; i < GRID_FACTOR; i++) { - row_energy[i] = teletone_goertzel_result (&dtmf_detect_state->row_out[i]); - if (row_energy[i] > row_energy[best_row]) { - best_row = i; - } - col_energy[i] = teletone_goertzel_result (&dtmf_detect_state->col_out[i]); - if (col_energy[i] > col_energy[best_col]) { - best_col = i; - } - } - hit = 0; - /* Basic signal level test and the twist test */ - if (row_energy[best_row] >= DTMF_THRESHOLD && - col_energy[best_col] >= DTMF_THRESHOLD && - col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST && - col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) { - /* Relative peak test */ - for (i = 0; i < GRID_FACTOR; i++) { - if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) || - (i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) { - break; - } - } - /* ... and second harmonic test */ - if (i >= GRID_FACTOR && (row_energy[best_row] + col_energy[best_col]) > 42.0*dtmf_detect_state->energy && - teletone_goertzel_result (&dtmf_detect_state->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col] && - teletone_goertzel_result (&dtmf_detect_state->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) { - hit = dtmf_positions[(best_row << 2) + best_col]; - /* Look for two successive similar results */ - /* The logic in the next test is: - We need two successive identical clean detects, with - something different preceeding it. This can work with - back to back differing digits. More importantly, it - can work with nasty phones that give a very wobbly start - to a digit. */ - if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) { - dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++; - dtmf_detect_state->detected_digits++; - if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) { - dtmf_detect_state->digit = hit; - } else { - dtmf_detect_state->lost_digits++; - } - - if (!dtmf_detect_state->zc) { - dtmf_detect_state->zc = ZC; - dtmf_detect_state->dur = 0; - r = TT_HIT_BEGIN; - break; - } - - } - } - } - - dtmf_detect_state->hit1 = dtmf_detect_state->hit2; - dtmf_detect_state->hit2 = dtmf_detect_state->hit3; - dtmf_detect_state->hit3 = hit; - - dtmf_detect_state->energy = 0.0; - dtmf_detect_state->current_sample = 0; - - } - - return r; -} - - -TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur) -{ - if (!dtmf_detect_state->digit) { - return 0; - } - - *buf = dtmf_detect_state->digit; - - *dur = dtmf_detect_state->dur; - - if (!dtmf_detect_state->zc) { - dtmf_detect_state->dur = 0; - dtmf_detect_state->digit = 0; - } - - return 1; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/libteletone_generate.c b/libs/freetdm/src/libteletone_generate.c deleted file mode 100644 index 3638d94989..0000000000 --- a/libs/freetdm/src/libteletone_generate.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * libteletone - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is libteletone - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * - * libteletone.c -- Tone Generator - * - * - * - * Exception: - * The author hereby grants the use of this source code under the - * following license if and only if the source code is distributed - * as part of the OpenZAP or FreeTDM library. Any use or distribution of this - * source code outside the scope of the OpenZAP or FreeTDM library will nullify the - * following license and reinact the MPL 1.1 as stated above. - * - * Copyright (c) 2007, Anthony Minessale II - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#define SMAX 32767 -#define SMIN -32768 -#define normalize_to_16bit(n) if (n > SMAX) n = SMAX; else if (n < SMIN) n = SMIN; - -#ifdef _MSC_VER -#pragma warning(disable:4706) -#endif - -TELETONE_API_DATA int16_t TELETONE_SINES[SINE_TABLE_MAX] = { - 0x00c9, 0x025b, 0x03ed, 0x057f, 0x0711, 0x08a2, 0x0a33, 0x0bc4, - 0x0d54, 0x0ee4, 0x1073, 0x1201, 0x138f, 0x151c, 0x16a8, 0x1833, - 0x19be, 0x1b47, 0x1cd0, 0x1e57, 0x1fdd, 0x2162, 0x22e5, 0x2467, - 0x25e8, 0x2768, 0x28e5, 0x2a62, 0x2bdc, 0x2d55, 0x2ecc, 0x3042, - 0x31b5, 0x3327, 0x3497, 0x3604, 0x3770, 0x38d9, 0x3a40, 0x3ba5, - 0x3d08, 0x3e68, 0x3fc6, 0x4121, 0x427a, 0x43d1, 0x4524, 0x4675, - 0x47c4, 0x490f, 0x4a58, 0x4b9e, 0x4ce1, 0x4e21, 0x4f5e, 0x5098, - 0x51cf, 0x5303, 0x5433, 0x5560, 0x568a, 0x57b1, 0x58d4, 0x59f4, - 0x5b10, 0x5c29, 0x5d3e, 0x5e50, 0x5f5e, 0x6068, 0x616f, 0x6272, - 0x6371, 0x646c, 0x6564, 0x6657, 0x6747, 0x6832, 0x691a, 0x69fd, - 0x6add, 0x6bb8, 0x6c8f, 0x6d62, 0x6e31, 0x6efb, 0x6fc2, 0x7083, - 0x7141, 0x71fa, 0x72af, 0x735f, 0x740b, 0x74b3, 0x7556, 0x75f4, - 0x768e, 0x7723, 0x77b4, 0x7840, 0x78c8, 0x794a, 0x79c9, 0x7a42, - 0x7ab7, 0x7b27, 0x7b92, 0x7bf9, 0x7c5a, 0x7cb7, 0x7d0f, 0x7d63, - 0x7db1, 0x7dfb, 0x7e3f, 0x7e7f, 0x7eba, 0x7ef0, 0x7f22, 0x7f4e, - 0x7f75, 0x7f98, 0x7fb5, 0x7fce, 0x7fe2, 0x7ff1, 0x7ffa, 0x7fff -}; - - -TELETONE_API(int) teletone_set_tone(teletone_generation_session_t *ts, int index, ...) -{ - va_list ap; - int i = 0; - teletone_process_t x = 0; - - va_start(ap, index); - while (i < TELETONE_MAX_TONES && (x = va_arg(ap, teletone_process_t))) { - ts->TONES[index].freqs[i++] = x; - } - va_end(ap); - - return (i > TELETONE_MAX_TONES) ? -1 : 0; - -} - -TELETONE_API(int) teletone_set_map(teletone_tone_map_t *map, ...) -{ - va_list ap; - int i = 0; - teletone_process_t x = 0; - - va_start(ap, map); - while (i < TELETONE_MAX_TONES && (x = va_arg(ap, teletone_process_t))) { - map->freqs[i++] = x; - } - va_end(ap); - - return (i > TELETONE_MAX_TONES) ? -1 : 0; - -} - -TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data) -{ - memset(ts, 0, sizeof(*ts)); - ts->rate = 8000; - ts->channels = 1; - ts->duration = 2000; - ts->wait = 500; - ts->tmp_duration = -1; - ts->tmp_wait = -1; - ts->handler = handler; - ts->user_data = user_data; - ts->volume = -7; - ts->decay_step = 0; - ts->decay_factor = 1; - if (buflen) { - if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) { - return -1; - } - ts->datalen = buflen; - } else { - ts->dynamic = 1024; - } - /* Add Standard DTMF Tones */ - teletone_set_tone(ts, '1', 697.0, 1209.0, 0.0); - teletone_set_tone(ts, '2', 697.0, 1336.0, 0.0); - teletone_set_tone(ts, '3', 697.0, 1477.0, 0.0); - teletone_set_tone(ts, 'A', 697.0, 1633.0, 0.0); - teletone_set_tone(ts, '4', 770.0, 1209.0, 0.0); - teletone_set_tone(ts, '5', 770.0, 1336.0, 0.0); - teletone_set_tone(ts, '6', 770.0, 1477.0, 0.0); - teletone_set_tone(ts, 'B', 770.0, 1633.0, 0.0); - teletone_set_tone(ts, '7', 859.0, 1209.0, 0.0); - teletone_set_tone(ts, '8', 859.0, 1336.0, 0.0); - teletone_set_tone(ts, '9', 859.0, 1477.0, 0.0); - teletone_set_tone(ts, 'C', 859.0, 1633.0, 0.0); - teletone_set_tone(ts, '*', 941.0, 1209.0, 0.0); - teletone_set_tone(ts, '0', 941.0, 1336.0, 0.0); - teletone_set_tone(ts, '#', 941.0, 1477.0, 0.0); - teletone_set_tone(ts, 'D', 941.0, 1633.0, 0.0); - - return 0; -} - -TELETONE_API(int) teletone_destroy_session(teletone_generation_session_t *ts) -{ - if (ts->buffer) { - free(ts->buffer); - ts->buffer = NULL; - ts->samples = 0; - } - return 0; -} - -static int ensure_buffer(teletone_generation_session_t *ts, int need) -{ - need += ts->samples; - need *= sizeof(teletone_audio_t); - need *= ts->channels; - - if (need > ts->datalen) { - teletone_audio_t *tmp; - ts->datalen = need + ts->dynamic; - tmp = realloc(ts->buffer, ts->datalen); - if (!tmp) { - return -1; - } - ts->buffer = tmp; - } - - return 0; -} - -TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map) -{ - /*teletone_process_t period = (1.0 / ts->rate) / ts->channels;*/ - int i, c; - int freqlen = 0; - teletone_dds_state_t tones[TELETONE_MAX_TONES+1]; - //int decay = 0; - int duration; - int wait = 0; - int32_t sample; - int32_t dc = 0; - float vol = ts->volume; - ts->samples = 0; - memset(tones, 0, sizeof(tones[0]) * TELETONE_MAX_TONES); - duration = (ts->tmp_duration > -1) ? ts->tmp_duration : ts->duration; - wait = (ts->tmp_wait > -1) ? ts->tmp_wait : ts->wait; - - if (map->freqs[0] > 0) { - for (freqlen = 0; freqlen < TELETONE_MAX_TONES && map->freqs[freqlen]; freqlen++) { - teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, 0); - teletone_dds_state_set_tx_level(&tones[freqlen], vol); - } - - if (ts->channels > 1) { - duration *= ts->channels; - } - - if (ts->dynamic) { - if (ensure_buffer(ts, duration)) { - return -1; - } - } - - for (ts->samples = 0; ts->samples < ts->datalen && ts->samples < duration; ts->samples++) { - if (ts->decay_direction && ++dc >= ts->decay_step) { - float nvol = vol + ts->decay_direction * ts->decay_factor; - int j; - - if (nvol <= TELETONE_VOL_DB_MAX && nvol >= TELETONE_VOL_DB_MIN) { - vol = nvol; - for (j = 0; j < TELETONE_MAX_TONES && map->freqs[j]; j++) { - teletone_dds_state_set_tx_level(&tones[j], vol); - } - dc = 0; - } - } - - sample = 128; - - for (i = 0; i < freqlen; i++) { - int32_t s = teletone_dds_state_modulate_sample(&tones[i], 0); - sample += s; - } - sample /= freqlen; - ts->buffer[ts->samples] = (teletone_audio_t)sample; - - for (c = 1; c < ts->channels; c++) { - ts->buffer[ts->samples+1] = ts->buffer[ts->samples]; - ts->samples++; - } - - } - } - if (ts->dynamic) { - if (ensure_buffer(ts, wait)) { - return -1; - } - } - for (c = 0; c < ts->channels; c++) { - for (i = 0; i < wait && ts->samples < ts->datalen; i++) { - ts->buffer[ts->samples++] = 0; - } - } - - if (ts->debug && ts->debug_stream) { - if (map->freqs[0] <= 0) { - fprintf(ts->debug_stream, "wait %d (%dms)\n", wait, wait / (ts->rate / 1000)); - } else { - fprintf(ts->debug_stream, "Generate: ("); - - for (i = 0; i < TELETONE_MAX_TONES && map->freqs[i]; i++) { - fprintf(ts->debug_stream, "%s%0.2f", i == 0 ? "" : "+",map->freqs[i]); - } - - fprintf(ts->debug_stream, - ") [volume %0.2fdB; samples %d(%dms) x %d channel%s; wait %d(%dms); decay_factor %0.2fdB; decay_step %d(%dms); wrote %d bytes]\n", - ts->volume, - duration, - duration / (ts->rate / 1000), - ts->channels, - ts->channels == 1 ? "" : "s", - wait, - wait / (ts->rate / 1000), - ts->decay_factor, - ts->decay_step, - ts->decay_step / (ts->rate / 1000), - ts->samples * 2); - } - } - return ts->samples / ts->channels; -} - -/* don't ask */ -static char *my_strdup (const char *s) -{ - size_t len = strlen (s) + 1; - void *new = malloc (len); - - if (new == NULL) { - return NULL; - } - - return (char *) memcpy (new, s, len); -} - -TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd) -{ - char *data = NULL, *cur = NULL, *end = NULL; - int LOOPING = 0; - - if (!cmd) { - return -1; - } - - do { - if (!(data = my_strdup(cmd))) { - return -1; - } - - cur = data; - - while (*cur) { - if (*cur == ' ' || *cur == '\r' || *cur == '\n') { - cur++; - continue; - } - - if ((end = strchr(cur, ';')) != 0) { - *end++ = '\0'; - } - - if (*(cur + 1) == '=') { - switch(*cur) { - case 'c': - ts->channels = atoi(cur + 2); - break; - case 'r': - ts->rate = atoi(cur + 2); - break; - case 'd': - ts->duration = atoi(cur + 2) * (ts->rate / 1000); - break; - case 'v': - { - float vol = (float)atof(cur + 2); - if (vol <= TELETONE_VOL_DB_MAX && vol >= TELETONE_VOL_DB_MIN) { - ts->volume = vol; - } - } - break; - case '>': - ts->decay_step = atoi(cur + 2) * (ts->rate / 1000); - ts->decay_direction = -1; - break; - case '<': - ts->decay_step = atoi(cur + 2) * (ts->rate / 1000); - ts->decay_direction = 1; - break; - case '+': - ts->decay_factor = (float)atof(cur + 2); - break; - case 'w': - ts->wait = atoi(cur + 2) * (ts->rate / 1000); - break; - case 'l': - ts->loops = atoi(cur + 2); - break; - case 'L': - if (!LOOPING) { - int L; - if ((L = atoi(cur + 2)) > 0) { - ts->LOOPS = L; - LOOPING++; - } - } - break; - } - } else { - while (*cur) { - char *p = NULL, *e = NULL; - teletone_tone_map_t mymap, *mapp = NULL; - - if (*cur == ' ' || *cur == '\r' || *cur == '\n') { - cur++; - continue; - } - - ts->tmp_duration = -1; - ts->tmp_wait = -1; - - memset(&mymap, 0, sizeof(mymap)); - - if (*(cur + 1) == '(') { - p = cur + 2; - if (*cur) { - char *next; - int i = 0; - if ((e = strchr(p, ')')) != 0) { - *e++ = '\0'; - } - do { - if (!p) { - break; - } - if ((next = strchr(p, ',')) != 0) { - *next++ = '\0'; - } - if (i == 0) { - ts->tmp_duration = atoi(p) * (ts->rate / 1000); - i++; - } else if (i == 1) { - ts->tmp_wait = atoi(p) * (ts->rate / 1000); - i++; - } else { - mymap.freqs[i++ - 2] = atof(p); - } - p = next; - - } while (next && (i-2) < TELETONE_MAX_TONES); - if (i > 2 && *cur == '%') { - mapp = &mymap; - } else if ((i != 2 || *cur == '%')) { - if (ts->debug && ts->debug_stream) { - fprintf(ts->debug_stream, "Syntax Error!\n"); - } - goto bottom; - } - } - } - - if (*cur && !mapp) { - if (*cur > 0 && *cur < TELETONE_TONE_RANGE) { - mapp = &ts->TONES[(int)*cur]; - } else if (ts->debug && ts->debug_stream) { - fprintf(ts->debug_stream, "Map [%c] Out Of Range!\n", *cur); - } - } - - if (mapp) { - if (mapp->freqs[0]) { - if (ts->handler) { - do { - ts->handler(ts, mapp); - if (ts->loops > 0) { - ts->loops--; - } - } while (ts->loops); - } - } else if (ts->debug && ts->debug_stream) { - fprintf(ts->debug_stream, "Ignoring Empty Map [%c]!\n", *cur); - } - } - - if (e) { - cur = e; - } else { - cur++; - } - } - } - - if (end) { - cur = end; - } else if (*cur){ - cur++; - } - } - bottom: - free(data); - data = NULL; - - if (ts->LOOPS > 0) { - ts->LOOPS--; - } - - } while (ts->LOOPS); - - return 0; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/priserver.c b/libs/freetdm/src/priserver.c deleted file mode 100644 index bbc1f2236e..0000000000 --- a/libs/freetdm/src/priserver.c +++ /dev/null @@ -1,328 +0,0 @@ -/***************************************************************************** - * priserver.c Refactoring of pritest.c - * - * Author(s): Anthony Minessale II - * Nenad Corbic - * - * Copyright: (c) 2005-2014 Anthony Minessale II - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * ============================================================================ - */ - -#include "freetdm.h" -#include -#include -#include -#include -#include -#include - -typedef struct { - int pid; - q931_call call; - void *pri; - int ready; -}call_info_t; - - -#define SANGOMA_MAX_CHAN_PER_SPAN 32 - -static call_info_t pidmap[SANGOMA_MAX_CHAN_PER_SPAN]; - -FIO_EVENT_CB_FUNCTION(my_ftdm_event_handler) -{ - if (event->e_type = FTDM_EVENT_DTMF) { - char *dtmf = event->data; - printf("DTMF %s\n", dtmf); - } -} - -/* Stupid runtime process to play a file to a b channel*/ -#define BYTES 320 -#define MAX_BYTES 1000 - -static int ready = 1; - -static void handle_SIGINT(int sig) -{ - if (sig) { - ready = 0; - } - - return; -} - -static void launch_channel(struct sangoma_pri *spri, int channo) -{ - pid_t pid; - int fd = 0, file = 0, inlen = 0, outlen = 0; - unsigned char inframe[MAX_BYTES], outframe[MAX_BYTES]; - fd_set readfds; - int mtu_mru=BYTES / 2; - int err; - ftdm_channel_t *chan; - ftdm_codec_t codec = FTDM_CODEC_SLIN; - unsigned ms = 20; - unsigned int lead = 50; - int ifd = -1; - ftdm_tone_type_t tt = FTDM_TONE_DTMF; - char dtmf[] = "1234567890"; - int loops = 0; - - pid = fork(); - - if (pid) { - pidmap[channo-1].pid = pid; - printf("-- Launching process %d to handle channel %d\n", pid, channo); - return; - } - - signal(SIGINT, handle_SIGINT); - - //ifd = open("/nfs/sounds/ptest.raw", O_WRONLY|O_CREAT|O_TRUNC, 777); - - memset(inframe, 0, MAX_BYTES); - memset(outframe, 0, MAX_BYTES); - - if (ftdm_channel_open(spri->span, channo, &chan) != FTDM_SUCCESS) { - printf("DEBUG cant open fd!\n"); - } - - - -#if 1 - if (ftdm_channel_command(chan, FTDM_COMMAND_SET_CODEC, &codec) != FTDM_SUCCESS) { - printf("Critical Error: Failed to set driver codec!\n"); - ftdm_channel_close(&chan); - exit(-1); - } -#endif - -#if 1 - if (ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_DTMF_DETECT, &tt) != FTDM_SUCCESS) { - printf("Critical Error: Failed to set dtmf detect!\n"); - ftdm_channel_close(&chan); - exit(-1); - } - ftdm_channel_set_event_callback(chan, my_ftdm_event_handler); -#endif - - - if (ftdm_channel_command(chan, FTDM_COMMAND_SET_INTERVAL, &ms) != FTDM_SUCCESS) { - printf("Critical Error: Failed to set codec interval!\n"); - ftdm_channel_close(&chan); - exit(-1); - } - - file = open("sound.raw", O_RDONLY); - if (file < 0){ - printf("Critical Error: Failed to open sound file!\n"); - ftdm_channel_close(&chan); - exit(-1); - } - - - while(ready) { - ftdm_wait_flag_t flags = FTDM_READ; - ftdm_size_t len; - loops++; - - if (lead) { - lead--; - } - - if (!lead && loops == 300) { -#if 1 - if (ftdm_channel_command(chan, FTDM_COMMAND_SEND_DTMF, dtmf) != FTDM_SUCCESS) { - printf("Critical Error: Failed to send dtmf\n"); - ftdm_channel_close(&chan); - exit(-1); - } -#endif - - } - - if (ftdm_channel_wait(chan, &flags, 2000) != FTDM_SUCCESS) { - printf("wait FAIL! [%s]\n", chan->last_error); - break; - } - - if (flags & FTDM_READ) { - len = MAX_BYTES; - if (ftdm_channel_read(chan, inframe, &len) == FTDM_SUCCESS) { - //printf("READ: %d\n", len); - //write(ifd, inframe, len); - if(!lead && (outlen = read(file, outframe, len)) <= 0) { - break; - } - - } else { - printf("READ FAIL! %d [%s]\n", len, chan->last_error); - break; - } - if (lead) { - continue; - } - ftdm_channel_write(chan, outframe, sizeof(outframe), &len); - } else { - printf("BREAK"); - break; - } - } - - printf("loop done\n"); - - //sangoma_get_full_cfg(fd, &tdm_api); - close(file); - //close(ifd); - - pri_hangup(spri->pri, channo, 16); - if (ftdm_channel_close(&chan) != FTDM_SUCCESS) { - printf("Critical Error: Failed to close channel [%s]\n", chan->last_error); - } - - printf("Call Handler: Process Finished\n"); - exit(0); -} - - -/* Event Handlers */ - -static int on_info(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event) -{ - printf( "number is: %s\n", event->ring.callednum); - if(strlen(event->ring.callednum) > 3) { - printf( "final number is: %s\n", event->ring.callednum); - pri_answer(spri->pri, event->ring.call, 0, 1); - } - return 0; -} - -static int on_hangup(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event) -{ - //pri_hangup(spri->pri, event->hangup.call, event->hangup.cause); - printf("-- Hanging up channel %d\n", event->hangup.channel); - if(pidmap[event->hangup.channel-1].pid) { - pri_hangup(spri->pri, event->hangup.call, 16); - pri_destroycall(spri->pri, event->hangup.call); - kill(pidmap[event->hangup.channel-1].pid, SIGINT); - pidmap[event->hangup.channel-1].pid = 0; - } - return 0; -} - -static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event) -{ - printf("-- Ring on channel %d (from %s to %s), answering...\n", event->ring.channel, event->ring.callingnum, event->ring.callednum); - pri_answer(spri->pri, event->ring.call, event->ring.channel, 1); - memcpy(&pidmap[event->ring.channel-1].call, event->ring.call, sizeof(q931_call)); - pidmap[event->ring.channel-1].pri=spri->pri; - pidmap[event->ring.channel-1].call = *event->ring.call; - launch_channel(spri, event->ring.channel); - return 0; -} - -static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event) -{ - printf("-- Restarting channel %d\n", event->restart.channel); - return 0; -} - -static int on_anything(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event) -{ - printf("%s: Caught Event %d (%s)\n", __FTDM_FUNC__, event_type, sangoma_pri_event_str(event_type)); - return 0; -} - -/* Generic Reaper */ -static void chan_ended(int sig) -{ - int status; - int x; - struct rusage rusage; - pid_t pid; - pid = wait4(-1, &status, WNOHANG, &rusage); - - printf("-- PID %d ended\n", pid); - - for (x=0;x -1) { - fprintf(stderr, "--!! Unknown PID %d exited\n", pid); - signal(SIGCHLD, chan_ended); - return; - } -} - -/* Our Program */ -int main(int argc, char *argv[]) -{ - struct sangoma_pri spri; - int debug = 0; - if (argv[1]) { - debug = atoi(argv[1]); - } - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - if (ftdm_global_init() != FTDM_SUCCESS) { - fprintf(stderr, "Error loading FreeTDM\n"); - exit(-1); - } - - printf("FreeTDM loaded\n"); - - - debug = PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE; - printf("WTF %d\n", debug); - - if (sangoma_init_pri(&spri, - 1, // span - 24, // dchan - SANGOMA_PRI_SWITCH_DMS100, - SANGOMA_PRI_CPE, - debug) < 0) { - return -1; - } - //spri.pri->debug = (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE); - - //pri_set_debug(&spri.pri, (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)); - - SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_ANY, on_anything); - SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_RING, on_ring); - SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_HANGUP, on_hangup); - SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_HANGUP_REQ, on_hangup); - SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_INFO_RECEIVED, on_info); - SANGOMA_MAP_PRI_EVENT(spri, SANGOMA_PRI_EVENT_RESTART, on_restart); - - signal(SIGCHLD, chan_ended); - sangoma_run_pri(&spri); - return 0; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/sangoma_pri.c b/libs/freetdm/src/sangoma_pri.c deleted file mode 100644 index a6e79c9682..0000000000 --- a/libs/freetdm/src/sangoma_pri.c +++ /dev/null @@ -1,251 +0,0 @@ -/***************************************************************************** - * sangoma_pri.c libpri Sangoma integration - * - * Author(s): Anthony Minessale II - * Nenad Corbic - * - * Copyright: (c) 2005-2014 Anthony Minessale II - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * ============================================================================ - */ - -#include "freetdm.h" -#include -#ifndef HAVE_GETTIMEOFDAY - -#ifdef WIN32 -#include - -static __inline int gettimeofday(struct timeval *tp, void *nothing) -{ -#ifdef WITHOUT_MM_LIB - SYSTEMTIME st; - time_t tt; - struct tm tmtm; - /* mktime converts local to UTC */ - GetLocalTime (&st); - tmtm.tm_sec = st.wSecond; - tmtm.tm_min = st.wMinute; - tmtm.tm_hour = st.wHour; - tmtm.tm_mday = st.wDay; - tmtm.tm_mon = st.wMonth - 1; - tmtm.tm_year = st.wYear - 1900; tmtm.tm_isdst = -1; - tt = mktime (&tmtm); - tp->tv_sec = tt; - tp->tv_usec = st.wMilliseconds * 1000; -#else - /** - ** The earlier time calculations using GetLocalTime - ** had a time resolution of 10ms.The timeGetTime, part - ** of multimedia apis offer a better time resolution - ** of 1ms.Need to link against winmm.lib for this - **/ - unsigned long Ticks = 0; - unsigned long Sec =0; - unsigned long Usec = 0; - Ticks = timeGetTime(); - - Sec = Ticks/1000; - Usec = (Ticks - (Sec*1000))*1000; - tp->tv_sec = Sec; - tp->tv_usec = Usec; -#endif /* WITHOUT_MM_LIB */ - (void)nothing; - return 0; -} -#endif /* WIN32 */ -#endif /* HAVE_GETTIMEOFDAY */ - -static struct sangoma_pri_event_list SANGOMA_PRI_EVENT_LIST[] = { - {0, SANGOMA_PRI_EVENT_ANY, "ANY"}, - {1, SANGOMA_PRI_EVENT_DCHAN_UP, "DCHAN_UP"}, - {2, SANGOMA_PRI_EVENT_DCHAN_DOWN, "DCHAN_DOWN"}, - {3, SANGOMA_PRI_EVENT_RESTART, "RESTART"}, - {4, SANGOMA_PRI_EVENT_CONFIG_ERR, "CONFIG_ERR"}, - {5, SANGOMA_PRI_EVENT_RING, "RING"}, - {6, SANGOMA_PRI_EVENT_HANGUP, "HANGUP"}, - {7, SANGOMA_PRI_EVENT_RINGING, "RINGING"}, - {8, SANGOMA_PRI_EVENT_ANSWER, "ANSWER"}, - {9, SANGOMA_PRI_EVENT_HANGUP_ACK, "HANGUP_ACK"}, - {10, SANGOMA_PRI_EVENT_RESTART_ACK, "RESTART_ACK"}, - {11, SANGOMA_PRI_EVENT_FACNAME, "FACNAME"}, - {12, SANGOMA_PRI_EVENT_INFO_RECEIVED, "INFO_RECEIVED"}, - {13, SANGOMA_PRI_EVENT_PROCEEDING, "PROCEEDING"}, - {14, SANGOMA_PRI_EVENT_SETUP_ACK, "SETUP_ACK"}, - {15, SANGOMA_PRI_EVENT_HANGUP_REQ, "HANGUP_REQ"}, - {16, SANGOMA_PRI_EVENT_NOTIFY, "NOTIFY"}, - {17, SANGOMA_PRI_EVENT_PROGRESS, "PROGRESS"}, - {18, SANGOMA_PRI_EVENT_KEYPAD_DIGIT, "KEYPAD_DIGIT"} -}; - -#define LINE "--------------------------------------------------------------------------------" - -char *sangoma_pri_event_str(sangoma_pri_event_t event_id) -{ - return SANGOMA_PRI_EVENT_LIST[event_id].name; -} - -static int __pri_sangoma_read(struct pri *pri, void *buf, int buflen) -{ - struct sangoma_pri *spri = (struct sangoma_pri *) pri->userdata; - ftdm_size_t len = buflen; - int res; - char bb[4096] = ""; - - - if (ftdm_channel_read(spri->zdchan, buf, &len) != FTDM_SUCCESS) { - printf("D-READ FAIL! [%s]\n", spri->zdchan->last_error); - return 0; - } - res = (int)len; - memset(&((unsigned char*)buf)[res],0,2); - res+=2; - - //print_bits(buf, res-2, bb, sizeof(bb), 1, 0); - //ftdm_log(FTDM_LOG_DEBUG, "READ %d\n%s\n%s\n\n", res-2, LINE, bb); - - return res; -} - -static int __pri_sangoma_write(struct pri *pri, void *buf, int buflen) -{ - struct sangoma_pri *spri = (struct sangoma_pri *) pri->userdata; - int res; - ftdm_size_t len = buflen -2; - char bb[4096] = ""; - - if (ftdm_channel_write(spri->zdchan, buf, buflen, &len) != FTDM_SUCCESS) { - printf("D-WRITE FAIL! [%s]\n", spri->zdchan->last_error); - return 0; - } - - //print_bits(buf, (int)buflen-2, bb, sizeof(bb), 1, 0); - //ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)buflen-2, LINE, bb); - - return (int) buflen; -} - -int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug) -{ - int ret = -1; - ftdm_socket_t dfd = 0; - - memset(spri, 0, sizeof(struct sangoma_pri)); - - if (ftdm_channel_open(span, dchan, &spri->zdchan) != FTDM_SUCCESS) { - fprintf(stderr, "Unable to open DCHAN %d for span %d (%s)\n", dchan, span, strerror(errno)); - } else { - if ((spri->pri = pri_new_cb(spri->zdchan->sockfd, node, swtype, __pri_sangoma_read, __pri_sangoma_write, spri))){ - spri->span = span; - pri_set_debug(spri->pri, debug); - ret = 0; - } else { - fprintf(stderr, "Unable to create PRI\n"); - } - } - return ret; -} - - -int sangoma_one_loop(struct sangoma_pri *spri) -{ - fd_set rfds, efds; - struct timeval now = {0,0}, *next; - pri_event *event; - int sel; - - if (spri->on_loop) { - spri->on_loop(spri); - } - - FD_ZERO(&rfds); - FD_ZERO(&efds); - -#ifdef _MSC_VER - //Windows macro for FD_SET includes a warning C4127: conditional expression is constant -#pragma warning(push) -#pragma warning(disable:4127) -#endif - - FD_SET(spri->pri->fd, &rfds); - FD_SET(spri->pri->fd, &efds); - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - if ((next = pri_schedule_next(spri->pri))) { - gettimeofday(&now, NULL); - now.tv_sec = next->tv_sec - now.tv_sec; - now.tv_usec = next->tv_usec - now.tv_usec; - if (now.tv_usec < 0) { - now.tv_usec += 1000000; - now.tv_sec -= 1; - } - if (now.tv_sec < 0) { - now.tv_sec = 0; - now.tv_usec = 0; - } - } - - sel = select(spri->pri->fd + 1, &rfds, NULL, &efds, next ? &now : NULL); - event = NULL; - - if (!sel) { - event = pri_schedule_run(spri->pri); - } else if (sel > 0) { - event = pri_check_event(spri->pri); - } - - if (event) { - event_handler handler; - /* 0 is catchall event handler */ - if ((handler = spri->eventmap[event->e] ? spri->eventmap[event->e] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) { - handler(spri, event->e, event); - } else { - fprintf(stderr,"No event handler found for event %d.\n", event->e); - } - } - - return sel; -} - -int sangoma_run_pri(struct sangoma_pri *spri) -{ - int ret = 0; - - for (;;){ - ret=sangoma_one_loop(spri); - if (ret < 0){ - -#ifndef WIN32 //This needs to be adressed fror WIN32 still - if (errno == EINTR){ - /* Igonore an interrupted system call */ - continue; - } -#endif - printf("Error = %i\n",ret); - perror("Sangoma Run Pri: "); - break; - } - } - - return ret; - -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/sangoma_pri.h b/libs/freetdm/src/sangoma_pri.h deleted file mode 100644 index 873aab8a27..0000000000 --- a/libs/freetdm/src/sangoma_pri.h +++ /dev/null @@ -1,100 +0,0 @@ -/***************************************************************************** - * libsangoma.c AFT T1/E1: HDLC API Code Library - * - * Author(s): Anthony Minessale II - * Nenad Corbic - * - * Copyright: (c) 2005-2014 Anthony Minessale II - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * ============================================================================ - */ - -#ifndef _SANGOMA_PRI_H -#define _SANGOMA_PRI_H -#include -#include - - -#define SANGOMA_MAX_CHAN_PER_SPAN 32 - -typedef enum { - SANGOMA_PRI_EVENT_ANY = 0, - SANGOMA_PRI_EVENT_DCHAN_UP = PRI_EVENT_DCHAN_UP, - SANGOMA_PRI_EVENT_DCHAN_DOWN = PRI_EVENT_DCHAN_DOWN, - SANGOMA_PRI_EVENT_RESTART = PRI_EVENT_RESTART, - SANGOMA_PRI_EVENT_CONFIG_ERR = PRI_EVENT_CONFIG_ERR, - SANGOMA_PRI_EVENT_RING = PRI_EVENT_RING, - SANGOMA_PRI_EVENT_HANGUP = PRI_EVENT_HANGUP, - SANGOMA_PRI_EVENT_RINGING = PRI_EVENT_RINGING, - SANGOMA_PRI_EVENT_ANSWER = PRI_EVENT_ANSWER, - SANGOMA_PRI_EVENT_HANGUP_ACK = PRI_EVENT_HANGUP_ACK, - SANGOMA_PRI_EVENT_RESTART_ACK = PRI_EVENT_RESTART_ACK, - SANGOMA_PRI_EVENT_FACNAME = PRI_EVENT_FACNAME, - SANGOMA_PRI_EVENT_INFO_RECEIVED = PRI_EVENT_INFO_RECEIVED, - SANGOMA_PRI_EVENT_PROCEEDING = PRI_EVENT_PROCEEDING, - SANGOMA_PRI_EVENT_SETUP_ACK = PRI_EVENT_SETUP_ACK, - SANGOMA_PRI_EVENT_HANGUP_REQ = PRI_EVENT_HANGUP_REQ, - SANGOMA_PRI_EVENT_NOTIFY = PRI_EVENT_NOTIFY, - SANGOMA_PRI_EVENT_PROGRESS = PRI_EVENT_PROGRESS, - SANGOMA_PRI_EVENT_KEYPAD_DIGIT = PRI_EVENT_KEYPAD_DIGIT -} sangoma_pri_event_t; - -typedef enum { - SANGOMA_PRI_NETWORK = PRI_NETWORK, - SANGOMA_PRI_CPE = PRI_CPE -} sangoma_pri_node_t; - -typedef enum { - SANGOMA_PRI_SWITCH_UNKNOWN = PRI_SWITCH_UNKNOWN, - SANGOMA_PRI_SWITCH_NI2 = PRI_SWITCH_NI2, - SANGOMA_PRI_SWITCH_DMS100 = PRI_SWITCH_DMS100, - SANGOMA_PRI_SWITCH_LUCENT5E = PRI_SWITCH_LUCENT5E, - SANGOMA_PRI_SWITCH_ATT4ESS = PRI_SWITCH_ATT4ESS, - SANGOMA_PRI_SWITCH_EUROISDN_E1 = PRI_SWITCH_EUROISDN_E1, - SANGOMA_PRI_SWITCH_EUROISDN_T1 = PRI_SWITCH_EUROISDN_T1, - SANGOMA_PRI_SWITCH_NI1 = PRI_SWITCH_NI1, - SANGOMA_PRI_SWITCH_GR303_EOC = PRI_SWITCH_GR303_EOC, - SANGOMA_PRI_SWITCH_GR303_TMC = PRI_SWITCH_GR303_TMC, - SANGOMA_PRI_SWITCH_QSIG = PRI_SWITCH_QSIG -} sangoma_pri_switch_t; - -typedef enum { - SANGOMA_PRI_READY = (1 << 0) -} sangoma_pri_flag_t; - -struct sangoma_pri; -typedef int (*event_handler)(struct sangoma_pri *, sangoma_pri_event_t, pri_event *); -typedef int (*loop_handler)(struct sangoma_pri *); -#define MAX_EVENT 18 - -struct sangoma_pri { - struct pri *pri; - int span; - int dchan; - unsigned int flags; - void *private_info; - event_handler eventmap[MAX_EVENT+1]; - loop_handler on_loop; - ftdm_channel_t *zdchan; -}; - -struct sangoma_pri_event_list { - int event_id; - int pri_event; - char *name; -}; - - - -#define SANGOMA_MAP_PRI_EVENT(spri, event, func) spri.eventmap[event] = func; - -char *sangoma_pri_event_str(sangoma_pri_event_t event_id); -int sangoma_one_loop(struct sangoma_pri *spri); -int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug); -int sangoma_run_pri(struct sangoma_pri *spri); - -#endif diff --git a/libs/freetdm/src/ss7/README b/libs/freetdm/src/ss7/README deleted file mode 100644 index 0efe94c94a..0000000000 --- a/libs/freetdm/src/ss7/README +++ /dev/null @@ -1,3 +0,0 @@ -SS7 Coming soon - --Shane Burrell- diff --git a/libs/freetdm/src/testanalog.c b/libs/freetdm/src/testanalog.c deleted file mode 100644 index 764c5d81d5..0000000000 --- a/libs/freetdm/src/testanalog.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include "freetdm.h" - - -static void *test_call(ftdm_thread_t *me, void *obj) -{ - ftdm_channel_t *chan = (ftdm_channel_t *) obj; - uint8_t frame[1024]; - ftdm_size_t len; - char *number = ftdm_strdup("5551212"); - - ftdm_unused_arg(me); - - ftdm_sleep(10 * 1000); - - ftdm_log(FTDM_LOG_DEBUG, "answer call and start echo test\n"); - - ftdm_channel_call_answer(chan); - ftdm_channel_command(chan, FTDM_COMMAND_SEND_DTMF, number); - - while (ftdm_channel_call_check_answered(chan)) { - ftdm_wait_flag_t flags = FTDM_READ; - - if (ftdm_channel_wait(chan, &flags, -1) == FTDM_FAIL) { - break; - } - len = sizeof(frame); - if (flags & FTDM_READ) { - if (ftdm_channel_read(chan, frame, &len) == FTDM_SUCCESS) { - //ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n", len); - ftdm_channel_write(chan, frame, sizeof(frame), &len); - } else { - break; - } - } - } - - if (ftdm_channel_call_check_answered(chan)) { - ftdm_channel_call_indicate(chan, FTDM_CHANNEL_INDICATE_BUSY); - } - - ftdm_log(FTDM_LOG_DEBUG, "call over\n"); - ftdm_safe_free(number); - return NULL; -} - -static FIO_SIGNAL_CB_FUNCTION(on_signal) -{ - ftdm_log(FTDM_LOG_DEBUG, "got sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id)); - - switch(sigmsg->event_id) { - case FTDM_SIGEVENT_START: - ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_RINGING); - ftdm_log(FTDM_LOG_DEBUG, "launching thread and indicating ring\n"); - ftdm_thread_create_detached(test_call, sigmsg->channel); - break; - default: - break; - } - - return FTDM_SUCCESS; -} - -static int R = 0; -#if 0 -static void handle_SIGINT(int sig) -{ - if (sig); - R = 0; - return; -} -#endif - -int main(int argc, char *argv[]) -{ - ftdm_span_t *span; - int span_id; - int digit_timeout = 2000; - int max_dialstr = 11; - - if (argc < 2) { - printf("usage %s \n", argv[0]); - exit(-1); - } - - span_id = atoi(argv[1]); - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - - if (ftdm_global_init() != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n"); - exit(-1); - } - - ftdm_log(FTDM_LOG_DEBUG, "FreeTDM loaded\n"); - - if (ftdm_span_find(span_id, &span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span\n"); - goto done; - } - - - if (ftdm_configure_span(span, "analog", on_signal, - "tonemap", "us", - "digit_timeout", &digit_timeout, - "max_dialstr", &max_dialstr, - FTDM_TAG_END - ) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM span\n"); - goto done; - } - ftdm_span_start(span); - - R = 1; - - while(ftdm_running() && R) { - ftdm_sleep(1 * 1000); - } - -done: - - ftdm_global_destroy(); - return 0; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ - diff --git a/libs/freetdm/src/testapp.c b/libs/freetdm/src/testapp.c deleted file mode 100644 index 1d7a2cb8cb..0000000000 --- a/libs/freetdm/src/testapp.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "freetdm.h" -#include - -int main(int argc, char *argv[]) -{ - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - ftdm_channel_t *chan; - unsigned ms = 20; - ftdm_codec_t codec = FTDM_CODEC_SLIN; - unsigned runs = 1; - int spanid, chanid; - - ftdm_unused_arg(argc); - ftdm_unused_arg(argv); - - if (ftdm_global_init() != FTDM_SUCCESS) { - fprintf(stderr, "Error loading FreeTDM\n"); - exit(-1); - } - - printf("FreeTDM loaded\n"); - - top: - //if (ftdm_channel_open_any("wanpipe", 0, FTDM_HUNT_BOTTOM_UP, &chan) == FTDM_SUCCESS) { - if (ftdm_channel_open(1, 1, &chan) == FTDM_SUCCESS) { - int x = 0; - spanid = ftdm_channel_get_span_id(chan); - chanid = ftdm_channel_get_id(chan); - printf("opened channel %d:%d\n", spanid, chanid); - -#if 1 - if (ftdm_channel_command(chan, FTDM_COMMAND_SET_INTERVAL, &ms) == FTDM_SUCCESS) { - ms = 0; - ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &ms); - printf("interval set to %u\n", ms); - } else { - printf("set interval failed [%s]\n", ftdm_channel_get_last_error(chan)); - } -#endif - if (ftdm_channel_command(chan, FTDM_COMMAND_SET_CODEC, &codec) == FTDM_SUCCESS) { - codec = 1; - ftdm_channel_command(chan, FTDM_COMMAND_GET_CODEC, &codec); - printf("codec set to %u\n", codec); - } else { - printf("set codec failed [%s]\n", ftdm_channel_get_last_error(chan)); - } - - for(x = 0; x < 25; x++) { - unsigned char buf[2048]; - ftdm_size_t len = sizeof(buf); - ftdm_wait_flag_t flags = FTDM_READ; - - if (ftdm_channel_wait(chan, &flags, -1) == FTDM_FAIL) { - printf("wait FAIL! %u [%s]\n", (unsigned)len, ftdm_channel_get_last_error(chan)); - } - if (flags & FTDM_READ) { - if (ftdm_channel_read(chan, buf, &len) == FTDM_SUCCESS) { - printf("READ: %u\n", (unsigned)len); - } else { - printf("READ FAIL! %u [%s]\n", (unsigned)len, ftdm_channel_get_last_error(chan)); - break; - } - } else { - printf("wait fail [%s]\n", ftdm_channel_get_last_error(chan)); - } - } - ftdm_channel_close(&chan); - } else { - printf("open fail [%s]\n", ftdm_channel_get_last_error(chan)); - } - - if(--runs) { - goto top; - } - - ftdm_global_destroy(); - return 0; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/testcid.c b/libs/freetdm/src/testcid.c deleted file mode 100644 index e6a0116d4a..0000000000 --- a/libs/freetdm/src/testcid.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "private/ftdm_core.h" - -ftdm_status_t my_write_sample(int16_t *buf, ftdm_size_t buflen, void *user_data); - -struct helper { - int fd; - int wrote; -}; - -ftdm_status_t my_write_sample(int16_t *buf, ftdm_size_t buflen, void *user_data) -{ - struct helper *foo = (struct helper *) user_data; - size_t len; - len = write(foo->fd, buf, buflen * 2); - if (!len) return FTDM_FAIL; - foo->wrote += buflen * 2; - return FTDM_SUCCESS; -} - -int main(int argc, char *argv[]) -{ - struct ftdm_fsk_modulator fsk_trans; - ftdm_fsk_data_state_t fsk_data = {0}; - int fd = -1; - int16_t buf[160] = {0}; - ssize_t len = 0; - size_t type, mlen; - char *sp; - char str[128] = ""; - char fbuf[256]; - uint8_t databuf[1024] = ""; - struct helper foo = {0}; - // int x, bytes, start_bits = 180, stop_bits = 5, sbits = 300; - char time_str[9]; - struct tm tm; - time_t now; - - if (argc < 2) { - int x; - const char *url = "sip:cool@rad.com"; - - if ((fd = open("tone.raw", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { - fprintf(stderr, "File Error! [%s]\n", strerror(errno)); - exit(-1); - } - - - time(&now); - localtime_r(&now, &tm); - strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm); - - ftdm_fsk_data_init(&fsk_data, databuf, sizeof(databuf)); -#if 1 - - ftdm_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *)time_str, strlen(time_str)); - //ftdm_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, "06091213", 8); - ftdm_fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NUM, (uint8_t *)"14149361212", 7); - ftdm_fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NAME, (uint8_t *)"Fred Smith", 10); - for(x = 0; x < 0; x++) - ftdm_fsk_data_add_mdmf(&fsk_data, MDMF_ALT_ROUTE, (uint8_t *)url, strlen(url)); -#else - ftdm_fsk_data_add_sdmf(&fsk_data, "06061234", "0"); - //ftdm_fsk_data_add_sdmf(&state, "06061234", "5551212"); -#endif - ftdm_fsk_data_add_checksum(&fsk_data); - - foo.fd = fd; - - - ftdm_fsk_modulator_init(&fsk_trans, FSK_BELL202, 8000, &fsk_data, -14, 180, 5, 300, my_write_sample, &foo); - ftdm_fsk_modulator_send_all((&fsk_trans)); - - printf("%u %d %d\n", (unsigned) fsk_data.dlen, foo.wrote, fsk_trans.est_bytes); - - if (fd > -1) { - close (fd); - } - - return 0; - } - - if (ftdm_fsk_demod_init(&fsk_data, 8000, (uint8_t *)fbuf, sizeof(fbuf))) { - printf("wtf\n"); - return 0; - } - - if ((fd = open(argv[1], O_RDONLY)) < 0) { - fprintf(stderr, "cant open file %s\n", argv[1]); - exit (-1); - } - - while((len = read(fd, buf, sizeof(buf))) > 0) { - if (ftdm_fsk_demod_feed(&fsk_data, buf, len / 2) != FTDM_SUCCESS) { - break; - } - } - - while(ftdm_fsk_data_parse(&fsk_data, &type, &sp, &mlen) == FTDM_SUCCESS) { - ftdm_copy_string(str, sp, mlen+1); - *(str+mlen) = '\0'; - ftdm_clean_string(str); - printf("TYPE %u (%s) LEN %u VAL [%s]\n", (unsigned)type, ftdm_mdmf_type2str(type), (unsigned)mlen, str); - } - - ftdm_fsk_demod_destroy(&fsk_data); - - close(fd); - return 0; -} diff --git a/libs/freetdm/src/testisdn.c b/libs/freetdm/src/testisdn.c deleted file mode 100644 index 13e14aedd2..0000000000 --- a/libs/freetdm/src/testisdn.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "freetdm.h" -#include - - -static FIO_SIGNAL_CB_FUNCTION(on_signal) -{ - return FTDM_FAIL; -} - -static int R = 0; -static void handle_SIGINT(int sig) -{ - if (sig); - R = 0; - return; -} - -int main(int argc, char *argv[]) -{ - ftdm_span_t *span; - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - - if (argc < 2) { - printf("umm no\n"); - exit(-1); - } - - if (ftdm_global_init() != FTDM_SUCCESS) { - fprintf(stderr, "Error loading FreeTDM\n"); - exit(-1); - } - - printf("FreeTDM loaded\n"); - - if (ftdm_span_find(atoi(argv[1]), &span) != FTDM_SUCCESS) { - fprintf(stderr, "Error finding FreeTDM span\n"); - goto done; - } - - if (ftdm_configure_span("isdn", span, on_signal, - "mode", "te", - "dialect", "national", - TAG_END) == FTDM_SUCCESS) { - ftdm_span_start(span); - } else { - fprintf(stderr, "Error starting ISDN D-Channel\n"); - goto done; - } - - signal(SIGINT, handle_SIGINT); - R = 1; - while(R) { - ftdm_sleep(1 * 1000); - } - - done: - - ftdm_global_destroy(); - - return 1; - -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/testpri.c b/libs/freetdm/src/testpri.c deleted file mode 100644 index fb7c0bdd38..0000000000 --- a/libs/freetdm/src/testpri.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "freetdm.h" -#include -#include -#include -#include -#include -#include -#include - -static int THREADS[4][31] = { {0} }; -static int R = 0; -static int T = 0; -static ftdm_mutex_t *mutex = NULL; - - -static void *channel_run(ftdm_thread_t *me, void *obj) -{ - ftdm_channel_t *ftdmchan = obj; - int fd = -1; - short buf[160]; - int spanid = ftdm_channel_get_span_id(ftdmchan); - int chanid = ftdm_channel_get_id(ftdmchan); - - ftdm_unused_arg(me); - - ftdm_mutex_lock(mutex); - T++; - ftdm_mutex_unlock(mutex); - - ftdm_channel_call_answer(ftdmchan); - - if ((fd = open("test.raw", O_RDONLY, 0)) < 0) { - goto end; - } - - while(R == 1 && THREADS[spanid][chanid] == 1) { - ssize_t bytes = read(fd, buf, sizeof(buf)); - size_t bbytes; - - if (bytes <= 0) { - break; - } - - bbytes = (size_t) bytes; - - fio_slin2alaw(buf, sizeof(buf), &bbytes); - - if (ftdm_channel_write(ftdmchan, buf, sizeof(buf), &bbytes) != FTDM_SUCCESS) { - break; - } - } - - close(fd); - - end: - - ftdm_channel_call_hangup(ftdmchan); - - THREADS[spanid][chanid] = 0; - - ftdm_mutex_lock(mutex); - T = 0; - ftdm_mutex_unlock(mutex); - - return NULL; -} - -static FIO_SIGNAL_CB_FUNCTION(on_signal) -{ - int spanid = ftdm_channel_get_span_id(sigmsg->channel); - int chanid = ftdm_channel_get_id(sigmsg->channel); - ftdm_log(FTDM_LOG_DEBUG, "got sig %d:%d [%s]\n", spanid, chanid, ftdm_signal_event2str(sigmsg->event_id)); - - switch(sigmsg->event_id) { - - case FTDM_SIGEVENT_STOP: - THREADS[spanid][chanid] = -1; - break; - - case FTDM_SIGEVENT_START: - if (!THREADS[spanid][chanid]) { - THREADS[spanid][chanid] = 1; - ftdm_thread_create_detached(channel_run, sigmsg->channel); - } - - break; - default: - break; - } - - return FTDM_SUCCESS; -} - - -static void handle_SIGINT(int sig) -{ - ftdm_unused_arg(sig); - - ftdm_mutex_lock(mutex); - R = 0; - ftdm_mutex_unlock(mutex); - - return; -} - -int main(int argc, char *argv[]) -{ - ftdm_span_t *span; - ftdm_mutex_create(&mutex); - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - - if (argc < 2) { - printf("umm no\n"); - exit(-1); - } - - if (ftdm_global_init() != FTDM_SUCCESS) { - fprintf(stderr, "Error loading FreeTDM\n"); - exit(-1); - } - - printf("FreeTDM loaded\n"); - - if (ftdm_span_find(atoi(argv[1]), &span) != FTDM_SUCCESS) { - fprintf(stderr, "Error finding FreeTDM span\n"); - goto done; - } - - - - if (ftdm_configure_span( - span, "libpri", on_signal, - "node", "cpe", - "switch", "euroisdn", - "dp", "unknown", - "l1", "alaw", - "debug", NULL, - "opts", 0, - FTDM_TAG_END) == FTDM_SUCCESS) { - - - ftdm_span_start(span); - } else { - fprintf(stderr, "Error starting ISDN D-Channel\n"); - goto done; - } - - signal(SIGINT, handle_SIGINT); - ftdm_mutex_lock(mutex); - R = 1; - ftdm_mutex_unlock(mutex); - while(R || T) { - ftdm_sleep(1 * 1000); - } - - done: - - ftdm_global_destroy(); - - return 1; - -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/testr2.c b/libs/freetdm/src/testr2.c deleted file mode 100644 index ef6897fc29..0000000000 --- a/libs/freetdm/src/testr2.c +++ /dev/null @@ -1,169 +0,0 @@ -#include "freetdm.h" -#include -#include - -static volatile int running = 0; -static ftdm_mutex_t *the_mutex = NULL; -static ftdm_channel_t *fchan = NULL; -static ftdm_channel_indication_t indication = FTDM_CHANNEL_INDICATE_NONE; - -static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) -{ - int chanid = ftdm_channel_get_ph_id(sigmsg->channel); - ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel %d\n", ftdm_signal_event2str(sigmsg->event_id), chanid); - switch (sigmsg->event_id) { - case FTDM_SIGEVENT_START: - { - ftdm_mutex_lock(the_mutex); - if (!fchan) { - fchan = sigmsg->channel; - indication = FTDM_CHANNEL_INDICATE_PROCEED; - } - ftdm_mutex_unlock(the_mutex); - } - break; - case FTDM_SIGEVENT_INDICATION_COMPLETED: - { - ftdm_channel_indication_t ind = FTDM_CHANNEL_INDICATE_NONE; - if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROCEED) { - ftdm_log(FTDM_LOG_DEBUG, "Proceed indication result = %d\n", sigmsg->ev_data.indication_completed.status); - ind = FTDM_CHANNEL_INDICATE_PROGRESS; - } else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROGRESS) { - ftdm_log(FTDM_LOG_DEBUG, "Progress indication result = %d\n", sigmsg->ev_data.indication_completed.status); - ind = FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA; - } else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA) { - ftdm_log(FTDM_LOG_DEBUG, "Progress media indication result = %d\n", sigmsg->ev_data.indication_completed.status); - ind = FTDM_CHANNEL_INDICATE_ANSWER; - } else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_ANSWER) { - ftdm_log(FTDM_LOG_DEBUG, "Answer indication result = %d\n", sigmsg->ev_data.indication_completed.status); - } else { - ftdm_log(FTDM_LOG_DEBUG, "Unexpected indication, result = %d\n", sigmsg->ev_data.indication_completed.status); - exit(1); - } - ftdm_mutex_lock(the_mutex); - if (fchan) { - indication = ind; - } - ftdm_mutex_unlock(the_mutex); - } - break; - case FTDM_SIGEVENT_STOP: - { - ftdm_channel_call_hangup(sigmsg->channel); - } - break; - case FTDM_SIGEVENT_RELEASED: - { - ftdm_mutex_lock(the_mutex); - if (fchan && fchan == sigmsg->channel) { - fchan = NULL; - } - ftdm_mutex_unlock(the_mutex); - } - break; - default: - break; - } - return FTDM_SUCCESS; -} - -static void stop_test(int sig) -{ - ftdm_unused_arg(sig); - running = 0; -} - -int main(int argc, char *argv[]) -{ - ftdm_span_t *span; - ftdm_conf_parameter_t parameters[20]; - - ftdm_mutex_create(&the_mutex); - - if (argc < 2) { - printf("umm no\n"); - exit(1); - } - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - - if (ftdm_global_init() != FTDM_SUCCESS) { - fprintf(stderr, "Error loading FreeTDM\n"); - exit(1); - } - - ftdm_global_configuration(); - - printf("FreeTDM loaded\n"); - - if (ftdm_span_find_by_name(argv[1], &span) != FTDM_SUCCESS) { - fprintf(stderr, "Error finding FreeTDM span %s\n", argv[1]); - goto done; - } - - /* testing non-blocking operation */ - //ftdm_span_set_blocking_mode(span, FTDM_FALSE); - - parameters[0].var = "variant"; - parameters[0].val = "br"; - - parameters[1].var = "max_ani"; - parameters[1].val = "4"; - - parameters[2].var = "max_dnis"; - parameters[2].val = "4"; - - parameters[3].var = "logging"; - parameters[3].val = "all"; - - parameters[4].var = NULL; - parameters[4].val = NULL; - - if (ftdm_configure_span_signaling(span, "r2", on_r2_signal, parameters) == FTDM_SUCCESS) { - ftdm_span_start(span); - } else { - fprintf(stderr, "Error starting R2 span\n"); - goto done; - } - - running = 1; - signal(SIGINT, stop_test); - while(running) { - ftdm_sleep(20); - if (fchan && indication != FTDM_CHANNEL_INDICATE_NONE) { - ftdm_channel_t *lchan = NULL; - ftdm_channel_indication_t ind = FTDM_CHANNEL_INDICATE_NONE; - ftdm_time_t start, stop, diff; - - ftdm_mutex_lock(the_mutex); - ind = indication; - indication = FTDM_CHANNEL_INDICATE_NONE; - lchan = fchan; - ftdm_mutex_unlock(the_mutex); - - start = ftdm_current_time_in_ms(); - ftdm_channel_call_indicate(lchan, ind); - stop = ftdm_current_time_in_ms(); - diff = stop - start; - ftdm_log(FTDM_LOG_DEBUG, "Setting indication %s took %"FTDM_TIME_FMT" ms\n", - ftdm_channel_indication2str(ind), diff); - } - } - -done: - - ftdm_global_destroy(); - - return 0; -} - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/libs/freetdm/src/testtones.c b/libs/freetdm/src/testtones.c deleted file mode 100644 index d5d5d548bf..0000000000 --- a/libs/freetdm/src/testtones.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "private/ftdm_core.h" - -struct ttmp { - int fd; -}; - -static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map) -{ - struct ttmp *tmp = ts->user_data; - int wrote; - size_t len; - - wrote = teletone_mux_tones(ts, map); - len = write(tmp->fd, ts->buffer, wrote * 2); - - if (!len) return -1; - - return 0; -} - -#if 1 -int main(int argc, char *argv[]) -{ - teletone_generation_session_t ts; - struct ttmp tmp; - - if (argc < 3) { - fprintf(stderr, "Arg Error! \n"); - exit(-1); - } - - if ((tmp.fd = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { - fprintf(stderr, "File Error! [%s]\n", strerror(errno)); - exit(-1); - } - - teletone_init_session(&ts, 0, teletone_handler, &tmp); - ts.rate = 8000; - ts.debug = 1; - ts.debug_stream = stdout; - teletone_run(&ts, argv[2]); - close(tmp.fd); - - return 0; -} -#else -int32_t main(int argc, char *argv[]) -{ - int32_t j, i, fd = -1; - int32_t rate = 8000; - /* SIT tones and durations */ - float tones[] = { 913.8, 1370.6, 1776.7, 0 }; - int32_t durations[] = {274, 274, 380, 0}; - teletone_dds_state_t dds = {0}; - int16_t sample; - size_t len = 1; - - if (argc < 2 || (fd = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { - fprintf(stderr, "File Error!\n", strerror(errno)); - exit(-1); - } - - for (j = 0; tones[j] && durations[j]; j++) { - - teletone_dds_state_set_tone(&dds, tones[j], rate, -50); - - for(i = 0; (i < durations[j] * rate / 1000) && len != 0; i++) { - sample = teletone_dds_modulate_sample(&dds) * 20; - len = write(fd, &sample, sizeof(sample)); - } - - } - - close(fd); -} -#endif diff --git a/libs/freetdm/src/uart.c b/libs/freetdm/src/uart.c deleted file mode 100644 index 7211d9c643..0000000000 --- a/libs/freetdm/src/uart.c +++ /dev/null @@ -1,125 +0,0 @@ - -/* - * uart.c - * - * Copyright (c) 2005 Robert Krten. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This module contains a simple 8-bit UART, which performs a callback - * with the decoded byte value. - * - * 2005 06 11 R. Krten created -*/ - -#include -#include -#include -#include -#include - -#include "uart.h" - -/* - * dsp_uart_attr_init - * - * Initializes the attributes structure; this must be done before the - * attributes structure is used. -*/ - -void dsp_uart_attr_init (dsp_uart_attr_t *attr) -{ - memset (attr, 0, sizeof (*attr)); -} - -/* - * dsp_uart_attr_get_bytehandler - * dsp_uart_attr_set_bytehandler - * - * These functions get and set their respective elements from the - * attributes structure. If an error code is returned, it is just - * zero == ok, -1 == fail. -*/ - -bytehandler_func_t dsp_uart_attr_get_bytehandler(dsp_uart_attr_t *attr, void **bytehandler_arg) -{ - *bytehandler_arg = attr->bytehandler_arg; - return attr->bytehandler; -} - -void dsp_uart_attr_set_bytehandler(dsp_uart_attr_t *attr, bytehandler_func_t bytehandler, void *bytehandler_arg) -{ - attr->bytehandler = bytehandler; - attr->bytehandler_arg = bytehandler_arg; -} - -dsp_uart_handle_t *dsp_uart_create(dsp_uart_attr_t *attr) -{ - dsp_uart_handle_t *handle; - - handle = ftdm_malloc(sizeof (*handle)); - if (handle) { - memset(handle, 0, sizeof (*handle)); - - /* fill the attributes member */ - memcpy(&handle->attr, attr, sizeof (*attr)); - } - return handle; -} - -void dsp_uart_destroy(dsp_uart_handle_t **handle) -{ - if (*handle) { - ftdm_safe_free(*handle); - *handle = NULL; - } -} - - -void dsp_uart_bit_handler(void *x, int bit) -{ - dsp_uart_handle_t *handle = (dsp_uart_handle_t *) x; - - if (!handle->have_start) { - if (bit) { - return; /* waiting for start bit (0) */ - } - handle->have_start = 1; - handle->data = 0; - handle->nbits = 0; - return; - } - - handle->data >>= 1; - handle->data |= 0x80 * !!bit; - handle->nbits++; - - if (handle->nbits == 8) { - handle->attr.bytehandler(handle->attr.bytehandler_arg, handle->data); - handle->nbits = 0; - handle->data = 0; - handle->have_start = 0; - } -/* might consider handling errors in the future... */ -} -