From: Andreas Eversberg Date: Sun, 31 Mar 2013 10:50:04 +0000 (+0200) Subject: Add support for TCH/H and half rate codec X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=commitdiff_plain;h=a3b269f357b7e6b74d91a942f874ee041320dce7 Add support for TCH/H and half rate codec --- diff --git a/Makefile.am b/Makefile.am index a322d55..11a2beb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,10 +45,6 @@ INSTALLATION_DEFINES = \ SUBDIRS = include -if ENABLE_GSMHR -SUBDIRS += libgsmhr -endif - if ENABLE_MISDN MISDN_INCLUDE = -DWITH_MISDN -DWITH_CRYPT @@ -79,7 +75,7 @@ if ENABLE_GSMHR GSM_INCLUDE += -DWITH_GSMHR -GSM_LIB += libgsmhr/libgsmhr.a +GSM_LIB += libgsmhr/libgsmhr.la SUBDIRS += libgsmhr @@ -172,7 +168,7 @@ uninstall-hook: cd '$(DESTDIR)$(astmoddir)' && rm -f chan_lcr.so endif -INCLUDES = $(all_includes) $(MISDN_INCLUDE) $(GSM_INCLUDE) $(SS5_INCLUDE) $(SIP_INCLUDE) -Wall $(INSTALLATION_DEFINES) +INCLUDES = $(all_includes) -I$(top_srcdir)/include $(MISDN_INCLUDE) $(GSM_INCLUDE) $(SS5_INCLUDE) $(SIP_INCLUDE) -Wall $(INSTALLATION_DEFINES) lcr_SOURCES = \ main.c select.c trace.c options.c tones.c alawulaw.c cause.c interface.c message.c callerid.c socket_server.c \ diff --git a/acinclude.m4 b/acinclude.m4 deleted file mode 100644 index 816bd1f..0000000 --- a/acinclude.m4 +++ /dev/null @@ -1,797 +0,0 @@ - - - -dnl ------------------------------------------------------------------------ -dnl create a small program to test the settings of mISDNuser package -dnl ------------------------------------------------------------------------ -# ported from the KDE project -AC_DEFUN([PBX_PRINT_MISDNUSER_PROGRAM], -[ -cat > conftest.$ac_ext < -#include -#ifdef __cplusplus -} -#endif - -int main() -{ - /* TODO: try to reference some function here */ - return 0; -} -EOF -]) - -dnl ------------------------------------------------------------------------ -dnl create a small program to test the settings of mISDN package -dnl ------------------------------------------------------------------------ -# ported from the KDE project -AC_DEFUN([PBX_PRINT_MISDNKERNEL_PROGRAM], -[ -cat > conftest.$ac_ext < -#include -#include -#ifdef __cplusplus -} -#endif - -#define MISDN_MAJOR_VERSION_TEST $misdn_kernel_major_version_demand -#define MISDN_MINOR_VERSION_TEST $misdn_kernel_minor_version_demand -#define MISDN_VERSION_TEST ((MISDN_MAJOR_VERSION_TEST<<16) | MISDN_MINOR_VERSION_TEST) -//#define MISDN_VERSION ((MISDN_MAJOR_VERSION<<16) | MISDN_MINOR_VERSION) - -#if (MISDN_VERSION < MISDN_VERSION_TEST) -# error mISDN version mismatch. Need at least $misdn_kernel_major_version_demand.$misdn_kernel_minor_version_demand -#endif - - -int main() -{ - static u16 sum1; - /* access some constants from misdn kernel headers */ - u16 v1 = CMX_TXDATA_ON; - u16 v2 = CMX_TXDATA_OFF; - u16 v3 = CMX_DELAY; - u16 v4 = CMX_TX_DATA; - u16 v5 = CMX_JITTER; - - /* extend here more variables or function call - * to access more header information */ - - - /* anti optimisation constuct */ - sum1 = v1 + v2 + v3 + v4 + v5; - - return 0; -} -EOF -]) - - - -dnl prints a program. -dnl $1 is the include file -dnl $2 is the prefix before include -dnl $3 is the suffix, e.g. some variable or class definitions -dnl $4 is the program body within main() -AC_DEFUN([PBX_PRINT_PROGRAM], -[AC_LANG_PROGRAM([$2 -$1 - -$3], -[$4]) -]) - - - -dnl ------------------------------------------------------------------------ -dnl if --enable-debug, it disables optimisation and enables debugging symbols -dnl if --disable-debug (default) other way around -dnl ------------------------------------------------------------------------ -AC_DEFUN([AC_CHECK_COMPILERS], -[# taken from KDE project - - # enable debugging options on demand - DEBUGGING= - AC_ARG_ENABLE([debug], - [AS_HELP_STRING([--enable-debug], - [enable debugging symbols, turns off compiler optimisations (default=disable)]) - ], - [use_debug_code="yes"], - [use_debug_code="no"] - ) - AM_CONDITIONAL(ENABLE_DEBUGGING, test "x$DEBUGGING" == "xyes" ) - AC_ARG_ENABLE(dummyoption, - AC_HELP_STRING([--disable-debug], - [disables debugging symbols, turns on compiler optimisations]), - [:], - [:] - ) - - dnl this prevents stupid AC_PROG_CC to add "-g" to the default CFLAGS - CFLAGS=" $CFLAGS" - AC_PROG_CC - AC_PROG_CPP - - if test "$GCC" = "yes" ; then - if test "$use_debug_code" != "no"; then - CFLAGS="-g -O0 $CFLAGS" - else - CFLAGS="-O2 $CFLAGS" - fi - fi - - if test -z "$LDFLAGS" && test "$use_debug_code" = "no" && test "$GCC" = "yes"; then - LDFLAGS="" - fi - - CXXFLAGS=" $CXXFLAGS" - AC_PROG_CXX - - if test "$GXX" = "yes" ; then - if test "$use_debug_code" != "no"; then - CXXFLAGS="-g -O0 $CXXFLAGS" - else - CXXFLAGS="-O2 $CXXFLAGS" - fi - fi - -]) - - -dnl ------------------------------------------------------------------------ -dnl Try to find the mISDN-user headers and libraries. -dnl $(MISDN_LDFLAGS) will be -Lmisdnliblocation (if needed) -dnl and $(MISDN_INCLUDES) will be -Imisdnhdrlocation (if needed) -dnl ------------------------------------------------------------------------ -dnl -AC_DEFUN([AC_PATH_MISDNUSER], -[ -dnl AC_REQUIRE([K_PATH_X]) -dnl AC_REQUIRE([KDE_USE_MISDN]) -dnl AC_REQUIRE([KDE_CHECK_LIB64]) - -dnl ------------------------------------------------------------------------ -dnl Add configure flag to enable linking to MT version of mISDN-user library. -dnl ------------------------------------------------------------------------ - -dnl AC_ARG_ENABLE( -dnl mt, -dnl AC_HELP_STRING([--disable-mt],[link to non-threaded mISDN-user (deprecated)]), -dnl pbx_use_misdn_mt=$enableval, -dnl [ -dnl if test $pbx_misdnver = 3; then -dnl pbx_use_misdn_mt=yes -dnl else -dnl pbx_use_misdn_mt=no -dnl fi -dnl ] -dnl ) - -dnl USING_MISDN_MT="" - -dnl ------------------------------------------------------------------------ -dnl If we not get --disable-misdn-mt then adjust some vars for the host. -dnl ------------------------------------------------------------------------ - -dnl KDE_MT_LDFLAGS= -dnl KDE_MT_LIBS= -dnl if test "x$pbx_use_misdn_mt" = "xyes"; then -dnl KDE_CHECK_THREADING -dnl if test "x$pbx_use_threading" = "xyes"; then -dnl CPPFLAGS="$USE_THREADS -DMISDN_THREAD_SUPPORT $CPPFLAGS" -dnl KDE_MT_LDFLAGS="$USE_THREADS" -dnl KDE_MT_LIBS="$LIBPTHREAD" -dnl else -dnl pbx_use_misdn_mt=no -dnl fi -dnl fi -dnl AC_SUBST(KDE_MT_LDFLAGS) -dnl AC_SUBST(KDE_MT_LIBS) - -dnl pbx_misdn_was_given=yes - -dnl ------------------------------------------------------------------------ -dnl If we haven't been told how to link to mISDN-user, we work it out for ourselves. -dnl ------------------------------------------------------------------------ -dnl if test -z "$LIBMISDN_GLOB"; then -dnl if test "x$pbx_use_misdn_emb" = "xyes"; then -dnl LIBMISDN_GLOB="libmisdne.*" -dnl else -dnl LIBMISDN_GLOB="libmisdn.*" -dnl fi -dnl fi - -dnl ------------------------------------------------------------ -dnl If we got --enable-embedded then adjust the mISDN-user library name. -dnl ------------------------------------------------------------ -dnl if test "x$pbx_use_misdn_emb" = "xyes"; then -dnl misdnlib="misdne" -dnl else - misdnlib="mISDN" -dnl fi - -dnl pbx_int_misdn="-l$misdnlib" - -dnl if test -z "$LIBQPE"; then -dnl ------------------------------------------------------------ -dnl If we got --enable-palmtop then add -lqpe to the link line -dnl ------------------------------------------------------------ -dnl if test "x$pbx_use_misdn_emb" = "xyes"; then -dnl if test "x$pbx_use_misdn_emb_palm" = "xyes"; then -dnl LIB_QPE="-lqpe" -dnl else -dnl LIB_QPE="" -dnl fi -dnl else -dnl LIB_QPE="" -dnl fi -dnl fi - -dnl ------------------------------------------------------------------------ -dnl If we got --enable-misdn-mt then adjust the mISDN-user library name for the host. -dnl ------------------------------------------------------------------------ - -dnl if test "x$pbx_use_misdn_mt" = "xyes"; then -dnl LIBMISDN="-l$misdnlib-mt" -dnl pbx_int_misdn="-l$misdnlib-mt" -dnl LIBMISDN_GLOB="lib$misdnlib-mt.*" -dnl USING_MISDN_MT="using -mt" -dnl else -dnl LIBMISDN="-l$misdnlib" -dnl fi - -dnl if test $pbx_misdnver != 1; then - -dnl AC_REQUIRE([AC_FIND_PNG]) -dnl AC_REQUIRE([AC_FIND_JPEG]) -dnl LIBMISDN="$LIBMISDN $LIBPNG $LIBJPEG" -dnl fi - -dnl if test $pbx_misdnver = 3; then -dnl AC_REQUIRE([KDE_CHECK_LIBDL]) -dnl LIBMISDN="$LIBMISDN $LIBDL" -dnl fi - -dnl probably there could be a whole installation of misdn -pbx_misdn_dirs="/usr/local/mISDNuser /usr/local/misdn /usr/lib/mISDNuser /usr/lib/misdn" - - -AC_MSG_CHECKING([for mISDN-user]) -LIBMISDN="-l$misdnlib -lisdnnet" - -dnl if test "x$pbx_use_misdn_emb" != "xyes" && test "x$pbx_use_misdn_mac" != "xyes"; then -dnl LIBMISDN="$LIBMISDN $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET" -dnl fi -ac_misdnuser_includes=NO ac_misdnuser_libraries=NO ac_misdnuser_bindir=NO -misdnuser_libraries="" -misdnuser_includes="" -AC_ARG_WITH(misdnuser-dir, - AC_HELP_STRING([--with-misdnuser-dir=DIR],[where the root of mISDN-user is installed]), - [ ac_misdnuser_includes="$withval"/include - ac_misdnuser_libraries="$withval"/lib - ac_misdnuser_bindir="$withval"/bin - ]) - -AC_ARG_WITH(misdnuser-includes, - AC_HELP_STRING([--with-misdnuser-includes=DIR],[where the mISDN-user includes are (default=$with-misdnuser-dir/include)]), - [ - ac_misdnuser_includes="$withval" - ]) - -pbx_misdn_libs_given=no - -AC_ARG_WITH(misdnuser-libraries, - AC_HELP_STRING([--with-misdnuser-libraries=DIR],[where the mISDN-user library is installed (default=$with-misdnuser-dir/lib)]), - [ ac_misdnuser_libraries="$withval" - pbx_misdn_libs_given=yes - ]) - -AC_CACHE_VAL(ac_cv_have_misdn, -[#try to guess mISDN-user locations - -misdn_incdirs="" -for dir in $pbx_misdn_dirs; do - misdn_incdirs="$misdn_incdirs $dir/include $dir" -done -misdn_incdirs="$MISDNINC $misdn_incdirs /usr/include/mISDNuser /usr/include/misdn /usr/include" -if test ! "$ac_misdnuser_includes" = "NO"; then - misdn_incdirs="$ac_misdnuser_includes $misdn_incdirs" -fi - -dnl if test "$pbx_misdnver" != "1"; then - pbx_misdn_header=mISDNlib.h -dnl -> und auch "isdn_net.h" -dnl else -dnl pbx_misdn_header=qglobal.h -dnl fi - -AC_FIND_FILE($pbx_misdn_header, $misdn_incdirs, misdn_incdir) -ac_misdnuser_includes="$misdn_incdir" - -misdn_libdirs="" -for dir in $pbx_misdn_dirs; do - misdn_libdirs="$misdn_libdirs $dir/lib $dir" -done -misdn_libdirs="$MISDNLIB $misdn_libdirs /usr/lib /usr/local/lib" -if test ! "$ac_misdnuser_libraries" = "NO"; then - misdn_libdir=$ac_misdnuser_libraries -else - misdn_libdirs="$ac_misdnuser_libraries $misdn_libdirs" - # if the mISDN-user was given, the chance is too big that libmisdn.* doesn't exist - misdn_libdir=NONE - for dir in $misdn_libdirs; do - try="ls -1 $dir/${LIBMISDN_GLOB}" - if test -n "`$try 2> /dev/null`"; then misdn_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi - done -fi -for a in $misdn_libdir/lib`echo ${pbx_int_misdn} | sed 's,^-l,,'`_incremental.*; do - if test -e "$a"; then - LIBMISDN="$LIBMISDN ${pbx_int_misdn}_incremental" - break - fi -done - -ac_misdnuser_libraries="$misdn_libdir" - -AC_LANG_SAVE -AC_LANG_CPLUSPLUS - -ac_cxxflags_safe="$CXXFLAGS" -ac_ldflags_safe="$LDFLAGS" -ac_libs_safe="$LIBS" - -CXXFLAGS="$CXXFLAGS -I$misdn_incdir $all_includes" -LDFLAGS="$LDFLAGS -L$misdn_libdir $all_libraries $USER_LDFLAGS" -LIBS="$LIBS $LIBMISDN" - -PBX_PRINT_MISDNUSER_PROGRAM - -if AC_TRY_EVAL(ac_link) && test -s conftest; then - rm -f conftest* -else - echo "configure: failed program was:" >&AC_FD_CC - cat conftest.$ac_ext >&AC_FD_CC - ac_misdnuser_libraries="NO" -fi -rm -f conftest* -CXXFLAGS="$ac_cxxflags_safe" -LDFLAGS="$ac_ldflags_safe" -LIBS="$ac_libs_safe" - -AC_LANG_RESTORE -if test "$ac_misdnuser_includes" = NO || test "$ac_misdnuser_libraries" = NO; then - ac_cv_have_misdn="have_misdn=no" - ac_misdnuser_notfound="" - missing_misdn_mt="" - if test "$ac_misdnuser_includes" = NO; then - if test "$ac_misdnuser_libraries" = NO; then - ac_misdnuser_notfound="(headers and libraries)"; - else - ac_misdnuser_notfound="(headers)"; - fi - else -dnl if test "x$pbx_use_misdn_mt" = "xyes"; then -dnl missing_misdn_mt="Make sure that you have compiled mISDN-user with thread support!" -dnl ac_misdnuser_notfound="(library $misdnlib-mt)"; -dnl else - ac_misdnuser_notfound="(library $misdnlib)"; -dnl fi - fi - - AC_MSG_ERROR([mISDN-user ($pbx_misdn_minversion) $ac_misdnuser_notfound not found. Please check your installation! -For more details about this problem, look at the end of config.log.$missing_misdn_mt]) -else - have_misdn="yes" -fi -]) - - -eval "$ac_cv_have_misdn" - -if test "$have_misdn" != yes; then - AC_MSG_RESULT([$have_misdn]); -else - ac_cv_have_misdn="have_misdn=yes \ - ac_misdnuser_includes=$ac_misdnuser_includes ac_misdnuser_libraries=$ac_misdnuser_libraries" - AC_MSG_RESULT([libraries $ac_misdnuser_libraries, headers $ac_misdnuser_includes $USING_MISDN_MT]) - - misdnuser_libraries="$ac_misdnuser_libraries" - misdnuser_includes="$ac_misdnuser_includes" -fi - -dnl if test ! "$pbx_misdn_libs_given" = "yes" && test ! "$pbx_misdnver" = 3; then -dnl KDE_CHECK_MISDN_DIRECT(misdnuser_libraries= ,[]) -dnl fi - -AC_SUBST(misdnuser_libraries) -AC_SUBST(misdnuser_includes) - -if test -z "$misdnuser_includes"; then - MISDN_INCLUDES="" -else - MISDN_INCLUDES="-I$misdnuser_includes" - all_includes="$MISDN_INCLUDES $all_includes" -fi - -if test -z "$misdnuser_libraries"; then - MISDN_LDFLAGS="" -else - MISDN_LDFLAGS="-L$misdnuser_libraries" - all_libraries="$MISDN_LDFLAGS $all_libraries" -fi -dnl test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS" - -AC_SUBST(MISDN_INCLUDES) -AC_SUBST(MISDN_LDFLAGS) -dnl AC_PATH_MISDN_MOC_UIC - -dnl KDE_CHECK_MISDN_JPEG - -dnl if test "x$pbx_use_misdn_emb" != "xyes" && test "x$pbx_use_misdn_mac" != "xyes"; then -dnl LIB_MISDN="$pbx_int_misdn $LIBJPEG_MISDN "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)' -dnl else -dnl LIB_MISDN="$pbx_int_misdn $LIBJPEG_MISDN "'$(LIBZ) $(LIBPNG)' -dnl fi -dnl test -z "$KDE_MT_LIBS" || LIB_MISDN="$LIB_MISDN $KDE_MT_LIBS" -dnl for a in $misdn_libdir/lib`echo ${pbx_int_misdn} | sed 's,^-l,,'`_incremental.*; do -dnl if test -e "$a"; then -dnl LIB_MISDN="$LIB_MISDN ${pbx_int_misdn}_incremental" -dnl break -dnl fi -dnl done - -AC_SUBST(LIB_MISDN) -dnl AC_SUBST(LIB_QPE) - -AC_SUBST(pbx_misdnver) - -]) - - - -dnl ------------------------------------------------------------------------ -dnl Try to find the mISDN-kernel headers. -dnl $(MISDNKERNEL_INCLUDES) will be -Imisdnkernelhdrlocation (if needed) -dnl ------------------------------------------------------------------------ -dnl -AC_DEFUN([AC_PATH_MISDNKERNEL], -[ - - misdnlib="mISDN" -misdn_kernel_major_version_demand=6 -misdn_kernel_minor_version_demand=0 -lcr_misdn_kernel_minversion=$misdn_kernel_major_version_demand.$misdn_kernel_minor_version_demand - -dnl ## TODO !! convert misdnuser variables to misdn kernel header variables - -dnl probably there could be a whole installation of misdn -kernel_ver=$(uname -r) -misdn_kernelheader_dirs="/lib/modules/$kernel_ver/source/include /usr/src/linux/include/" - - -AC_MSG_CHECKING([for mISDN-kernel]) -dnl LIBMISDN="-l$misdnlib -lisdnnet" -dnl -dnl if test "x$pbx_use_misdn_emb" != "xyes" && test "x$pbx_use_misdn_mac" != "xyes"; then -dnl LIBMISDN="$LIBMISDN $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET" -dnl fi -dnl ac_misdnkernel_includes=NO ac_misdnkernel_libraries=NO ac_misdnkernel_bindir=NO -ac_misdnkernel_includes=NO -dnl misdnkernel_libraries="" -misdnkernel_includes="" -dnl AC_ARG_WITH(misdnkernel-dir, -dnl AC_HELP_STRING([--with-misdnkernel-dir=DIR],[where the mISDN-headers are installed ]), -dnl [ ac_misdnkernel_includes="$withval"/include -dnl ac_misdnkernel_libraries="$withval"/lib -dnl ac_misdnkernel_bindir="$withval"/bin -dnl ]) - -AC_ARG_WITH(misdnkernel-includes, - AC_HELP_STRING([--with-misdnkernel-includes=DIR],[where the mISDN-kernel includes are. Used if enable-socket-misdn]), - [ - ac_misdnkernel_includes="$withval" - ]) - -dnl pbx_misdn_libs_given=no - -dnl AC_ARG_WITH(misdnkernel-libraries, -dnl AC_HELP_STRING([--with-misdnkernel-libraries=DIR],[where the mISDN-kernel library is installed.]), -dnl [ ac_misdnkernel_libraries="$withval" -dnl pbx_misdn_libs_given=yes -dnl ]) - -AC_CACHE_VAL(ac_cv_have_misdnkernel, -[#try to guess mISDN-user locations - -misdnkernel_incdirs="" -for dir in $misdn_kernelheader_dirs; do - misdnkernel_incdirs="$misdnkernel_incdirs $dir/include $dir" -done -misdnkernel_incdirs="$MISDNKERNELINC $misdnkernel_incdirs /usr/include/mISDNuser /usr/include/misdn /usr/include" -if test ! "$ac_misdnkernel_includes" = "NO"; then - misdnkernel_incdirs="$ac_misdnkernel_includes $misdnkernel_incdirs" -fi - - pbx_misdn_kernel_header=linux/mISDNif.h - -AC_FIND_FILE($pbx_misdn_kernel_header, $misdnkernel_incdirs, misdnkernel_incdir) -ac_misdnkernel_includes="$misdnkernel_incdir" - -dnl misdn_libdirs="" -dnl for dir in $misdn_kernelheader_dirs; do -dnl misdn_libdirs="$misdn_libdirs $dir/lib $dir" -dnl done -dnl misdn_libdirs="$MISDNLIB $misdn_libdirs /usr/lib /usr/local/lib" -dnl if test ! "$ac_misdnkernel_libraries" = "NO"; then -dnl misdn_libdir=$ac_misdnkernel_libraries -dnl else -dnl misdn_libdirs="$ac_misdnkernel_libraries $misdn_libdirs" -dnl # if the mISDN-user was given, the chance is too big that libmisdn.* doesn't exist -dnl misdn_libdir=NONE -dnl for dir in $misdn_libdirs; do -dnl try="ls -1 $dir/${LIBMISDN_GLOB}" -dnl if test -n "`$try 2> /dev/null`"; then misdn_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi -dnl done -dnl fi -dnl for a in $misdn_libdir/lib`echo ${pbx_int_misdn} | sed 's,^-l,,'`_incremental.*; do -dnl if test -e "$a"; then -dnl LIBMISDN="$LIBMISDN ${pbx_int_misdn}_incremental" -dnl break -dnl fi -dnl done -dnl -dnl ac_misdnkernel_libraries="$misdn_libdir" -dnl -AC_LANG_SAVE -AC_LANG_CPLUSPLUS - -ac_cxxflags_safe="$CXXFLAGS" -ac_ldflags_safe="$LDFLAGS" -ac_libs_safe="$LIBS" - -CXXFLAGS="$CXXFLAGS -I$misdnkernel_incdir $all_includes" -LDFLAGS="$LDFLAGS -L$misdn_libdir $all_libraries $USER_LDFLAGS" -LIBS="$LIBS $LIBMISDN" - -PBX_PRINT_MISDNKERNEL_PROGRAM - -if AC_TRY_EVAL(ac_compile) && test -s conftest.o; then - rm -f conftest* -else - echo "configure: failed program was:" >&AC_FD_CC - cat conftest.$ac_ext >&AC_FD_CC - ac_misdnkernel_includes="NO" -dnl ac_misdnkernel_libraries="NO" -fi -rm -f conftest* -CXXFLAGS="$ac_cxxflags_safe" -LDFLAGS="$ac_ldflags_safe" -LIBS="$ac_libs_safe" - -AC_LANG_RESTORE -dnl if test "$ac_misdnkernel_includes" = NO || test "$ac_misdnkernel_libraries" = NO; then -if test "$ac_misdnkernel_includes" = NO; then - ac_cv_have_misdnkernel="have_misdnkernel=no" - ac_misdnkernel_notfound="" - missing_misdn_mt="" -dnl if test "$ac_misdnkernel_includes" = NO; then -dnl if test "$ac_misdnkernel_libraries" = NO; then -dnl ac_misdnkernel_notfound="(headers and libraries)"; -dnl else - ac_misdnkernel_notfound="(headers)"; -dnl fi -dnl else -dnl ac_misdnkernel_notfound="(library $misdnlib)"; -dnl fi - - AC_MSG_ERROR([mISDN kernel header (version >= $lcr_misdn_kernel_minversion) not found. Please check your installation! -For more details about this problem, look at the end of config.log.$missing_misdn_mt]) -else - have_misdnkernel="yes" -fi -]) - -dnl check cache content -dnl TODO: maybe move this to beginning (before compilation test?) -eval "$ac_cv_have_misdnkernel" - -if test "$have_misdnkernel" != yes; then - AC_MSG_RESULT([$have_misdnkernel]); -else - ac_cv_have_misdnkernel="have_misdnkernel=yes \ - ac_misdnkernel_includes=$ac_misdnkernel_includes" -dnl ac_misdnkernel_libraries=$ac_misdnkernel_libraries" - AC_MSG_RESULT([headers $ac_misdnkernel_includes]) - -dnl misdnkernel_libraries="$ac_misdnkernel_libraries" - misdnkernel_includes="$ac_misdnkernel_includes" -fi - -dnl if test ! "$pbx_misdn_libs_given" = "yes" && test ! "$pbx_misdnver" = 3; then -dnl KDE_CHECK_MISDN_DIRECT(misdnkernel_libraries= ,[]) -dnl fi - -dnl AC_SUBST(misdnkernel_libraries) -AC_SUBST(misdnkernel_includes) - -if test -z "$misdnkernel_includes"; then - MISDNKERNEL_INCLUDES="" -else - MISDNKERNEL_INCLUDES="-I$misdnkernel_includes" - all_includes="$MISDNKERNEL_INCLUDES $all_includes" -fi - -dnl if test -z "$misdnkernel_libraries"; then -dnl MISDN_LDFLAGS="" -dnl else -dnl MISDN_LDFLAGS="-L$misdnkernel_libraries" -dnl all_libraries="$MISDN_LDFLAGS $all_libraries" -dnl fi -dnl test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS" - -AC_SUBST(MISDNKERNEL_INCLUDES) -dnl AC_SUBST(MISDN_LDFLAGS) -dnl AC_PATH_MISDN_MOC_UIC - -dnl KDE_CHECK_MISDN_JPEG - -dnl if test "x$pbx_use_misdn_emb" != "xyes" && test "x$pbx_use_misdn_mac" != "xyes"; then -dnl LIB_MISDN="$pbx_int_misdn $LIBJPEG_MISDN "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)' -dnl else -dnl LIB_MISDN="$pbx_int_misdn $LIBJPEG_MISDN "'$(LIBZ) $(LIBPNG)' -dnl fi -dnl test -z "$KDE_MT_LIBS" || LIB_MISDN="$LIB_MISDN $KDE_MT_LIBS" -dnl for a in $misdn_libdir/lib`echo ${pbx_int_misdn} | sed 's,^-l,,'`_incremental.*; do -dnl if test -e "$a"; then -dnl LIB_MISDN="$LIB_MISDN ${pbx_int_misdn}_incremental" -dnl break -dnl fi -dnl done - -dnl AC_SUBST(LIB_MISDN) -dnl AC_SUBST(LIB_QPE) - -AC_SUBST(pbx_misdnver) - -]) - - - -dnl ------------------------------------------------------------------------ -dnl Find a file (or one of more files in a list of dirs) -dnl ------------------------------------------------------------------------ -AC_DEFUN([AC_FIND_FILE], -[ -$3=NO -for i in $2; -do - for j in $1; - do - echo "configure: __oline__: $i/$j" >&AC_FD_CC - if test -r "$i/$j"; then - echo "taking that" >&AC_FD_CC - $3=$i - break 2 - fi - done -done -]) - - - -dnl ------------------------------------------------------------------------ -dnl Taken from http://autoconf-archive.cryp.to/ac_define_dir.html -dnl Copyright © 2006 Stepan Kasal -dnl Copyright © 2006 Andreas Schwab -dnl Copyright © 2006 Guido U. Draheim -dnl Copyright © 2006 Alexandre Oliva -dnl Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. -dnl -dnl This macro sets VARNAME to the expansion of the DIR variable, taking care -dnl of fixing up ${prefix} and such. -dnl ------------------------------------------------------------------------ -AC_DEFUN([AC_DEFINE_DIR], [ - prefix_NONE= - exec_prefix_NONE= - test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix - test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix -dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn -dnl refers to ${prefix}. Thus we have to use `eval' twice. - eval ac_define_dir="\"[$]$2\"" - eval ac_define_dir="\"$ac_define_dir\"" - AC_SUBST($1, "$ac_define_dir") - AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3]) - test "$prefix_NONE" && prefix=NONE - test "$exec_prefix_NONE" && exec_prefix=NONE -]) - - -dnl ------------------------------------------------------------------------ -dnl taken from http://autoconf-archive.cryp.to/ax_ext_check_header.html -dnl Copyright © 2005 Duncan Simpson -dnl Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. -dnl -dnl Checks locations of headers in various places -dnl Extended by Jörg Habenicht -dnl ------------------------------------------------------------------------ -AC_DEFUN([AX_EXT_HAVE_HEADER], -[AC_LANG_PUSH(C) - AC_CHECK_HEADER($1, [$3 got="yes"], [$4 got="no"], [$5]) - hdr=`echo $1 | $as_tr_sh` - for dir in $2 - do - if test "x${got}" = "xno"; then - ext_hashdr_cvdir=`echo $dir | $as_tr_sh` - AC_CACHE_CHECK([for $1 header with -I$dir], - [ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}], - [ext_have_hdr_save_cflags=${CFLAGS} - CFLAGS="${CFLAGS} -I${dir}" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([#include <$1>])], - [got="yes"; eval "ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}"="yes"], - [got="no"; eval "ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}"="no"]) - CFLAGS=$ext_have_hdr_save_cflags]) - if eval `echo 'test x${'ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}'}' = "xyes"`; then - CFLAGS="${CFLAGS} -I${dir}" - CPPFLAGS="${CPPFLAGS} -I${dir}" - got="yes"; - hdr=`echo $1 | $as_tr_cpp` - AC_DEFINE_UNQUOTED(HAVE_${hdr}, 1, - [Define this if you have the $1 header]) - fi; - fi; - done -AC_LANG_POP]) - - -dnl ------------------------------------------------------------------------ -dnl taken from http://autoconf-archive.cryp.to/ax_ext_check_header.html -dnl Copyright © 2005 Duncan Simpson -dnl Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. -dnl -dnl Checks locations of headers in various places -dnl Extended by Jörg Habenicht -dnl ------------------------------------------------------------------------ -dnl $1 include file name -dnl $2 directory list -dnl $3 action yes -dnl $4 action no -dnl $5 include prefix -dnl $6 include suffix -dnl $7 main() body content -AC_DEFUN([PBX_EXT_HAVE_CXX_HEADER], -[AC_LANG_PUSH(C++) - AC_CHECK_HEADER($1, [$3 got="yes"], [$4 got="no"], [$5]) - hdr=`echo $1 | $as_tr_sh` - for dir in $2 ; do - if test "x${got}" = "xno"; then - ext_hashdr_cvdir=`echo $dir | $as_tr_sh` - AC_CACHE_CHECK([for $1 header with -I$dir], - [ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}], - [ext_have_hdr_save_cxxflags=${CXXFLAGS} - CXXFLAGS="${CXXFLAGS} -I${dir}" - AC_COMPILE_IFELSE( - [PBX_PRINT_PROGRAM([#include <$1>],[$5],[$6],[$7])], - [$3 got="yes"; eval "ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}"="yes"], - [$4 got="no"; eval "ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}"="no"]) - CXXFLAGS=$ext_have_hdr_save_cxxflags]) - if eval `echo 'test x${'ext_cv${ext_hashdr_cvdir}_hashdr_${hdr}'}' = "xyes"`; then - CXXFLAGS="${CXXFLAGS} -I${dir}" - CPPFLAGS="${CPPFLAGS} -I${dir}" - got="yes"; - hdr=`echo $1 | $as_tr_cpp` - AC_DEFINE_UNQUOTED(HAVE_${hdr}, 1, - [Define this if you have the $1 header]) - fi; - fi; - done -AC_LANG_POP]) - diff --git a/gsm.cpp b/gsm.cpp index 6a7445d..50ca2ea 100644 --- a/gsm.cpp +++ b/gsm.cpp @@ -82,20 +82,31 @@ static const struct _value_string { { MNCC_STOP_DTMF_REQ, "MNCC_STOP_DTMF_REQ" }, { MNCC_HOLD_REQ, "MNCC_HOLD_REQ " }, { MNCC_RETRIEVE_REQ, "MNCC_RETRIEVE_REQ" }, + { MNCC_LCHAN_MODIFY, "MNCC_LCHAN_MODIFY" }, + + { MNCC_BRIDGE, "MNCC_BRIDGE" }, + { MNCC_FRAME_RECV, "MNCC_FRAME_RECV" }, + { MNCC_FRAME_DROP, "MNCC_FRAME_DROP" }, + { MNCC_RTP_CREATE, "MNCC_RTP_CREATE" }, + { MNCC_RTP_CONNECT, "MNCC_RTP_CONNECT" }, + { MNCC_RTP_FREE, "MNCC_RTP_FREE" }, + { 0, NULL } }; const char *mncc_name(int value) { int i = 0; + static char ukn[32]; while (mncc_names[i].name) { if (mncc_names[i].msg_type == value) return mncc_names[i].name; i++; } - return "unknown"; + SPRINT(ukn, "unknown(0x%x)", value); + return ukn; } static int mncc_send(struct lcr_gsm *lcr_gsm, int msg_type, void *data); @@ -157,6 +168,11 @@ static int delete_event(struct lcr_work *work, void *instance, int index); */ Pgsm::Pgsm(int type, char *portname, struct port_settings *settings, struct interface *interface) : Port(type, portname, settings, interface) { +#ifdef WITH_GSMHR + signed short homing[160]; + int i; +#endif + p_g_tones = 0; if (interface->is_tones == IS_YES) p_g_tones = 1; @@ -196,6 +212,18 @@ Pgsm::Pgsm(int type, char *portname, struct port_settings *settings, struct inte trigger_work(&p_g_delete); } #endif +#ifdef WITH_GSMHR + p_g_hr_decoder = gsm_hr_create(); + p_g_hr_encoder = gsm_hr_create(); + if (!p_g_hr_encoder || !p_g_hr_decoder) { + PERROR("Failed to create GSM HR codec instance\n"); + trigger_work(&p_g_delete); + } + /* Homing */ + for (i = 0; i < 160; i++) + homing[i] = 0x0008; + gsm_hr_encode(p_g_hr_encoder, homing, NULL); +#endif #ifdef WITH_GSMAMR p_g_amr_decoder = gsm_amr_create(); p_g_amr_encoder = gsm_amr_create(); @@ -235,6 +263,12 @@ Pgsm::~Pgsm() if (p_g_fr_decoder) gsm_fr_destroy(p_g_fr_decoder); //#endif +#ifdef WITH_GSMHR + if (p_g_hr_encoder) + gsm_hr_destroy(p_g_hr_encoder); + if (p_g_hr_decoder) + gsm_hr_destroy(p_g_hr_decoder); +#endif #ifdef WITH_GSMAMR /* close codec */ if (p_g_amr_encoder) @@ -277,6 +311,26 @@ void Pgsm::frame_receive(void *arg) } #endif break; + case GSM_TCHH_FRAME: + if (p_g_media_type != MEDIA_TYPE_GSM_HR) { + PERROR("HR frame, but current media type mismatches.\n"); + return; + } + if (!p_g_hr_decoder) { + PERROR("HR frame, but decoder not created.\n"); + return; + } + if ((frame->data[0]>>4) != 0x0) + goto bfi; +#ifdef WITH_GSMHR + /* decode */ + if (gsm_hr_decode(p_g_hr_decoder, frame->data, p_g_samples)) + goto bfi; + for (i = 0; i < 160; i++) { + data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff]; + } +#endif + break; case GSM_TCHF_FRAME_EFR: if (p_g_media_type != MEDIA_TYPE_GSM_EFR) { PERROR("EFR frame, but current media type mismatches.\n"); @@ -402,6 +456,17 @@ int Pgsm::audio_send(unsigned char *data, int len) frame_send(frame, 33, GSM_TCHF_FRAME); #endif break; + case MEDIA_TYPE_GSM_HR: + if (!p_g_hr_encoder) { + PERROR("HR frame, but encoder not created.\n"); + break; + } +#ifdef WITH_GSMHR + /* encode data */ + gsm_hr_encode(p_g_hr_encoder, p_g_rxdata, frame); + frame_send(frame, 15, GSM_TCHH_FRAME); +#endif + break; case MEDIA_TYPE_GSM_EFR: if (!p_g_amr_encoder) { PERROR("EFR frame, but encoder not created.\n"); @@ -664,6 +729,11 @@ void Pgsm::setup_compl_ind(unsigned int msg_type, unsigned int callref, struct g send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame); p_g_tch_connected = 1; } + + /* modify to GSM FR, if not already */ + if (!p_g_media_type) { + modify_lchan(MEDIA_TYPE_GSM); + } } /* DISCONNECT INDICATION */ @@ -871,6 +941,11 @@ void Pgsm::message_alerting(unsigned int epoint_id, int message_id, union parame send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc); p_g_tch_connected = 1; } + + /* modify to GSM FR, if not already */ + if (!p_g_media_type) { + modify_lchan(MEDIA_TYPE_GSM); + } } /* MESSAGE_CONNECT */ diff --git a/gsm_audio.c b/gsm_audio.c index 64756c7..6755803 100644 --- a/gsm_audio.c +++ b/gsm_audio.c @@ -221,5 +221,125 @@ int gsm_efr_encode(void *arg, signed short *samples, unsigned char *frame) #endif +#ifdef WITH_GSMHR + +#include + +/* create gsm instance */ +void *gsm_hr_create(void) +{ + struct gsmhr *state; + + state = gsmhr_init(); + + return state; +} + +/* free gsm instance */ +void gsm_hr_destroy(void *arg) +{ + gsmhr_exit((struct gsmhr *)arg); +} + +#include +/* decode frame into samples, return error */ +int gsm_hr_decode(void *arg, unsigned char *frame, signed short *samples) +{ + int16_t w[22]; + int rc; + + w[0] = frame[1] >> 3; + w[1] = ((frame[1] & 0x07) << 8) | frame[2]; + w[2] = (frame[3] << 1) | (frame[4] >> 7); + w[3] = ((frame[4] & 0x7f) << 1) | (frame[5] >> 7); + w[4] = (frame[5] & 0x7f) >> 6; + w[5] = (frame[5] & 0x3f) >> 4; + if (w[5]) { + /* voiced */ + w[6] = ((frame[5] & 0x0f) << 4) | (frame[6] >> 4); + w[7] = ((frame[6] & 0x0f) << 5) | (frame[7] >> 3); + w[8] = ((frame[7] & 0x07) << 2) | (frame[8] >> 6); + w[9] = (frame[8] & 0x3f) >> 2; + w[10] = ((frame[8] & 0x03) << 7) | (frame[9] >> 1); + w[11] = ((frame[9] & 0x01) << 4) | (frame[10] >> 4); + w[12] = frame[10] & 0x0f; + w[13] = (frame[11] << 1) | (frame[12] >> 7); + w[14] = (frame[12] & 0x7f) >> 2; + w[15] = ((frame[12] & 0x03) << 2) | (frame[13] >> 6); + w[16] = ((frame[13] & 0x3f) << 3) | (frame[14] >> 5); + w[17] = frame[14] & 0x1f; + } else { + /* unvoiced */ + w[6] = ((frame[5] & 0x0f) << 3) | (frame[6] >> 5); + w[7] = ((frame[6] & 0x1f) << 2) | (frame[7] >> 6); + w[8] = (frame[7] & 0x3f) >> 1; + w[9] = ((frame[7] & 0x01) << 6) | (frame[8] >> 2); + w[10] = ((frame[8] & 0x03) << 5) | (frame[9] >> 3); + w[11] = ((frame[9] & 0x07) << 2) | (frame[10] >> 6); + w[12] = ((frame[10] & 0x3f) << 1) | (frame[11] >> 7); + w[13] = frame[11] & 0x7f; + w[14] = frame[12] >> 3; + w[15] = ((frame[12] & 0x07) << 4) | (frame[13] >> 4); + w[16] = ((frame[13] & 0x1f) << 3) | (frame[14] >> 5); + w[17] = frame[14] & 0x1f; + } + w[18] = 0; /* BFI : 1 bit */ + w[19] = 0; /* UFI : 1 bit */ + w[20] = 0; /* SID : 2 bit */ + w[21] = 0; /* TAF : 1 bit */ + + rc = gsmhr_decode((struct gsmhr *)arg, samples, w); + + if (rc < 0) + return rc; + + return 0; +} + +/* encode samples into frame */ +void gsm_hr_encode(void *arg, signed short *samples, unsigned char *frame) +{ + int16_t w[22]; + + gsmhr_encode((struct gsmhr *)arg, w, samples); + + if (!frame) + return; + + frame[0] = 0x00; + frame[1] = (w[0] << 3) | (w[1] >> 8); + frame[2] = w[1]; + frame[3] = (w[2] >> 1); + frame[4] = (w[2] << 7) | (w[3] >> 1); + frame[5] = (w[3] << 7) | (w[4] << 6) | (w[5] << 4); + if (w[5]) { + /* voiced */ + frame[5] |= (w[6] >> 4); + frame[6] = (w[6] << 4) | (w[7] >> 5); + frame[7] = (w[7] << 3) | (w[8] >> 2); + frame[8] = (w[8] << 6) | (w[9] << 2) | (w[10] >> 7); + frame[9] = (w[10] << 1) | (w[11] >> 4); + frame[10] = (w[11] << 4) | w[12]; + frame[11] = (w[13] >> 1); + frame[12] = (w[13] << 7) | (w[14] << 2) | (w[15] >> 2); + frame[13] = (w[15] << 6) | (w[16] >> 3); + frame[14] = (w[16] << 5) | w[17]; + } else { + /* unvoiced */ + frame[5] |= (w[6] >> 3); + frame[6] = (w[6] << 5) | (w[7] >> 2); + frame[7] = (w[7] << 6) | (w[8] << 1) | (w[9] >> 6); + frame[8] = (w[9] << 2) | (w[10] >> 5); + frame[9] = (w[10] << 3) | (w[11] >> 2); + frame[10] = (w[11] << 6) | (w[12] >> 1); + frame[11] = (w[12] << 7) | w[13]; + frame[12] = (w[14] << 3) | (w[15] >> 4); + frame[13] = (w[15] << 4) | (w[16] >> 3); + frame[14] = (w[16] << 5) | w[17]; + } +} + +#endif + } /* extern "C" */ diff --git a/gsm_audio.h b/gsm_audio.h index 76138fc..2eeba36 100644 --- a/gsm_audio.h +++ b/gsm_audio.h @@ -15,3 +15,9 @@ int gsm_efr_decode(void *arg, unsigned char *frame, signed short *samples); int gsm_efr_encode(void *arg, signed short *samples, unsigned char *frame); #endif +#ifdef WITH_GSMHR +void *gsm_hr_create(void); +void gsm_hr_destroy(void *arg); +int gsm_hr_decode(void *arg, unsigned char *frame, signed short *samples); +void gsm_hr_encode(void *arg, signed short *samples, unsigned char *frame); +#endif diff --git a/gsm_bs.cpp b/gsm_bs.cpp index 4855a5c..e9b6be8 100644 --- a/gsm_bs.cpp +++ b/gsm_bs.cpp @@ -103,11 +103,36 @@ void Pgsm_bs::call_conf_ind(unsigned int msg_type, unsigned int callref, struct /* get list of offered payload types * if list ist empty, the FR V1 is selected */ select_payload_type(mncc, payload_types, media_types, &payloads, sizeof(payload_types)); - /* if no given payload type is supported, we assume */ + /* if no given payload type is supported, we select from channel type */ if (!payloads) { - media_types[0] = MEDIA_TYPE_GSM; - payload_types[0] = PAYLOAD_TYPE_GSM; - payloads = 1; + switch (mncc->lchan_type) { + case GSM_LCHAN_TCH_F: + media_types[0] = MEDIA_TYPE_GSM; + payload_types[0] = PAYLOAD_TYPE_GSM; + payloads = 1; + break; + case GSM_LCHAN_TCH_H: + media_types[0] = MEDIA_TYPE_GSM_HR; + payload_types[0] = 96; /* dynamic */ + payloads = 1; + break; + default: + mncc = create_mncc(MNCC_REL_REQ, callref); + gsm_trace_header(p_interface_name, this, MNCC_REL_REQ, DIRECTION_OUT); + mncc->fields |= MNCC_F_CAUSE; + mncc->cause.coding = 3; + mncc->cause.location = 1; + mncc->cause.value = 65; + add_trace("cause", "coding", "%d", mncc->cause.coding); + add_trace("cause", "location", "%d", mncc->cause.location); + add_trace("cause", "value", "%d", mncc->cause.value); + add_trace("reason", NULL, "Given lchan not supported"); + end_trace(); + send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc); + new_state(PORT_STATE_RELEASE); + trigger_work(&p_g_delete); + return; + } } /* select first payload type that matches the rtp list */ @@ -317,6 +342,8 @@ void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_ { int media_type; unsigned char payload_type; + int half; + void *encoder, *decoder; *payloads = 0; @@ -328,32 +355,45 @@ void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_ add_trace("bearer", "capa", "given by MS"); for (i = 0; mncc->bearer_cap.speech_ver[i] >= 0; i++) { + half = 0; /* select payload type we support */ switch (mncc->bearer_cap.speech_ver[i]) { case 0: add_trace("speech", "version", "Full Rate given"); media_type = MEDIA_TYPE_GSM; payload_type = PAYLOAD_TYPE_GSM; + encoder = p_g_fr_encoder; + decoder = p_g_fr_decoder; break; case 2: add_trace("speech", "version", "EFR given"); media_type = MEDIA_TYPE_GSM_EFR; payload_type = dynamic_type++; + encoder = p_g_amr_encoder; + decoder = p_g_amr_decoder; break; case 4: add_trace("speech", "version", "AMR given"); media_type = MEDIA_TYPE_AMR; payload_type = dynamic_type++; + encoder = p_g_amr_encoder; + decoder = p_g_amr_decoder; break; case 1: add_trace("speech", "version", "Half Rate given"); media_type = MEDIA_TYPE_GSM_HR; payload_type = dynamic_type++; + encoder = p_g_hr_encoder; + decoder = p_g_hr_decoder; + half = 1; break; case 5: add_trace("speech", "version", "AMR Half Rate given"); media_type = MEDIA_TYPE_AMR; payload_type = dynamic_type++; + encoder = p_g_amr_encoder; + decoder = p_g_amr_decoder; + half = 1; break; default: add_trace("speech", "version", "%d given", mncc->bearer_cap.speech_ver[i]); @@ -365,9 +405,17 @@ void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_ add_trace("speech", "ignored", "Not supported by LCR"); continue; } + if (!half && mncc->lchan_type != GSM_LCHAN_TCH_F) { + add_trace("speech", "ignored", "Not TCH/F"); + continue; + } + if (half && mncc->lchan_type != GSM_LCHAN_TCH_H) { + add_trace("speech", "ignored", "Not TCH/H"); + continue; + } if (!p_g_rtp_bridge) { - if (media_type != MEDIA_TYPE_GSM) { - add_trace("speech", "ignored", "Not suitable for LCR"); + if (!encoder || !decoder) { + add_trace("speech", "ignored", "Codec not supported"); continue; } } @@ -480,30 +528,40 @@ void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ /* get list of offered payload types * if list ist empty, the FR V1 is selected */ select_payload_type(mncc, payload_types, media_types, &payloads, sizeof(payload_types)); - /* if no given payload type is supported, we assume */ + /* if no given payload type is supported, we select from channel type */ if (!payloads) { - media_types[0] = MEDIA_TYPE_GSM; - payload_types[0] = PAYLOAD_TYPE_GSM; - payloads = 1; + switch (mncc->lchan_type) { + case GSM_LCHAN_TCH_F: + media_types[0] = MEDIA_TYPE_GSM; + payload_types[0] = PAYLOAD_TYPE_GSM; + payloads = 1; + break; + case GSM_LCHAN_TCH_H: + media_types[0] = MEDIA_TYPE_GSM_HR; + payload_types[0] = 96; /* dynamic */ + payloads = 1; + break; + default: + mncc = create_mncc(MNCC_REJ_REQ, callref); + gsm_trace_header(p_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT); + mncc->fields |= MNCC_F_CAUSE; + mncc->cause.coding = 3; + mncc->cause.location = 1; + mncc->cause.value = 65; + add_trace("cause", "coding", "%d", mncc->cause.coding); + add_trace("cause", "location", "%d", mncc->cause.location); + add_trace("cause", "value", "%d", mncc->cause.value); + add_trace("reason", NULL, "Given lchan not supported"); + end_trace(); + send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc); + new_state(PORT_STATE_RELEASE); + trigger_work(&p_g_delete); + return; + } } #if 0 /* if no given payload type is supported, we reject the call */ if (!payloads) { - mncc = create_mncc(MNCC_REJ_REQ, callref); - gsm_trace_header(p_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT); - mncc->fields |= MNCC_F_CAUSE; - mncc->cause.coding = 3; - mncc->cause.location = 1; - mncc->cause.value = 65; - add_trace("cause", "coding", "%d", mncc->cause.coding); - add_trace("cause", "location", "%d", mncc->cause.location); - add_trace("cause", "value", "%d", mncc->cause.value); - add_trace("reason", NULL, "Given speech codec(s) not supported"); - end_trace(); - send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc); - new_state(PORT_STATE_RELEASE); - trigger_work(&p_g_delete); - return; } #endif @@ -616,6 +674,9 @@ int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg) } if (msg_type == GSM_TCHF_FRAME + || msg_type == GSM_TCHF_FRAME_EFR + || msg_type == GSM_TCHH_FRAME + || msg_type == GSM_TCH_FRAME_AMR || msg_type == GSM_BAD_FRAME) { if (port) { /* inject DTMF, if enabled */ diff --git a/mncc.h b/mncc.h index 9f0f7e3..4b6d3a1 100644 --- a/mncc.h +++ b/mncc.h @@ -262,6 +262,17 @@ enum { GSM_MNCC_BCAP_RESERVED = 7, }; +enum { + GSM_LCHAN_NONE, + GSM_LCHAN_SDCCH, + GSM_LCHAN_TCH_F, + GSM_LCHAN_TCH_H, + GSM_LCHAN_UNKNOWN, + GSM_LCHAN_CCCH, + GSM_LCHAN_PDTCH, + _GSM_LCHAN_MAX +}; + struct gsm_mncc { /* context based information */ u_int32_t msg_type;