freeswitch-branches
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
August 2007
- 2 participants
- 20 discussions
24 Aug '07
Author: cseket
Date: Fri Aug 24 13:53:53 2007
New Revision: 5663
Added:
freeswitch/branches/cseket/libs/portmixer/
freeswitch/branches/cseket/libs/portmixer/.update
freeswitch/branches/cseket/libs/portmixer/CVS/
freeswitch/branches/cseket/libs/portmixer/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/CVS/Entries.Log
freeswitch/branches/cseket/libs/portmixer/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/CVS/Root
freeswitch/branches/cseket/libs/portmixer/LICENSE.txt
freeswitch/branches/cseket/libs/portmixer/Makefile
freeswitch/branches/cseket/libs/portmixer/Makefile.in
freeswitch/branches/cseket/libs/portmixer/README.txt
freeswitch/branches/cseket/libs/portmixer/configure (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/configure.ac
freeswitch/branches/cseket/libs/portmixer/include/
freeswitch/branches/cseket/libs/portmixer/include/CVS/
freeswitch/branches/cseket/libs/portmixer/include/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/include/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/include/CVS/Root
freeswitch/branches/cseket/libs/portmixer/include/portmixer.h
freeswitch/branches/cseket/libs/portmixer/macproj/
freeswitch/branches/cseket/libs/portmixer/macproj/CVS/
freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Root
freeswitch/branches/cseket/libs/portmixer/portaudio.patch
freeswitch/branches/cseket/libs/portmixer/px_common/
freeswitch/branches/cseket/libs/portmixer/px_common/CVS/
freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Root
freeswitch/branches/cseket/libs/portmixer/px_common/portmixer.h (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/px_mac/
freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/
freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Root
freeswitch/branches/cseket/libs/portmixer/px_mac/px_mac.c (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/px_mac_core/
freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/
freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Root
freeswitch/branches/cseket/libs/portmixer/px_mac_core/Makefile
freeswitch/branches/cseket/libs/portmixer/px_mac_core/px_mac_core.c (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/px_none/
freeswitch/branches/cseket/libs/portmixer/px_none/CVS/
freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Root
freeswitch/branches/cseket/libs/portmixer/px_none/Makefile
freeswitch/branches/cseket/libs/portmixer/px_none/px_none.c (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/px_tests/
freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/
freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Root
freeswitch/branches/cseket/libs/portmixer/px_tests/Makefile (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/px_tests/px_test.c (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/px_unix_oss/
freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/
freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Root
freeswitch/branches/cseket/libs/portmixer/px_unix_oss/Makefile
freeswitch/branches/cseket/libs/portmixer/px_unix_oss/px_unix_oss.c (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/px_win_wmme/
freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/
freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Root
freeswitch/branches/cseket/libs/portmixer/px_win_wmme/Makefile
freeswitch/branches/cseket/libs/portmixer/px_win_wmme/px_win_wmme.c (contents, props changed)
freeswitch/branches/cseket/libs/portmixer/src/
freeswitch/branches/cseket/libs/portmixer/src/CVS/
freeswitch/branches/cseket/libs/portmixer/src/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/src/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/src/CVS/Root
freeswitch/branches/cseket/libs/portmixer/src/px_example_api.c
freeswitch/branches/cseket/libs/portmixer/src/px_linux_alsa.c
freeswitch/branches/cseket/libs/portmixer/src/px_mac_coreaudio.c
freeswitch/branches/cseket/libs/portmixer/src/px_mixer.c
freeswitch/branches/cseket/libs/portmixer/src/px_mixer.h
freeswitch/branches/cseket/libs/portmixer/src/px_unix_oss.c
freeswitch/branches/cseket/libs/portmixer/src/px_win_common.c
freeswitch/branches/cseket/libs/portmixer/src/px_win_common.h
freeswitch/branches/cseket/libs/portmixer/src/px_win_ds.c
freeswitch/branches/cseket/libs/portmixer/src/px_win_wmme.c
freeswitch/branches/cseket/libs/portmixer/winproj/
freeswitch/branches/cseket/libs/portmixer/winproj/CVS/
freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Entries
freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Repository
freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Root
freeswitch/branches/cseket/libs/portmixer/winproj/portmixer.vcproj
Log:
add portmixer for setting voulme in mod_portaudio
Added: freeswitch/branches/cseket/libs/portmixer/.update
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/.update Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+Thu Aug 21 13.01.02 UTC 2007
\ No newline at end of file
Added: freeswitch/branches/cseket/libs/portmixer/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,7 @@
+/LICENSE.txt/1.1.1.1/Mon Dec 2 01:14:03 2002//
+/Makefile.in/1.1/Mon Oct 2 00:27:51 2006//
+/README.txt/1.1/Mon Oct 2 00:27:51 2006//
+/configure/1.3/Sun Jun 3 08:30:36 2007//
+/configure.ac/1.2/Sun Jun 3 08:30:36 2007//
+/portaudio.patch/1.2/Sun Jun 3 08:30:36 2007//
+D
Added: freeswitch/branches/cseket/libs/portmixer/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/CVS/Entries.Log Fri Aug 24 13:53:53 2007
@@ -0,0 +1,11 @@
+A D/include////
+A D/macproj////
+A D/px_common////
+A D/px_mac////
+A D/px_mac_core////
+A D/px_none////
+A D/px_tests////
+A D/px_unix_oss////
+A D/px_win_wmme////
+A D/src////
+A D/winproj////
Added: freeswitch/branches/cseket/libs/portmixer/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer
Added: freeswitch/branches/cseket/libs/portmixer/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/LICENSE.txt
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/LICENSE.txt Fri Aug 24 13:53:53 2007
@@ -0,0 +1,75 @@
+Portable header file to contain:
+/*
+ * PortMixer
+ * PortMixer API Header File
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+Implementation files to contain:
+/*
+ * PortMixer
+ * <platform> Implementation
+ *
+ * <copyright message>
+ *
+ * <author>
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
Added: freeswitch/branches/cseket/libs/portmixer/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/Makefile Fri Aug 24 13:53:53 2007
@@ -0,0 +1,42 @@
+### PortMixer library Makefile
+
+OBJECTS = px_mixer.o
+
+LIBRARY = libportmixer.a
+
+CC = gcc
+AR = /usr/bin/ar
+RANLIB = ranlib
+
+DEFS += -DPACKAGE_NAME=\"PortMixer\" -DPACKAGE_TARNAME=\"portmixer\" -DPACKAGE_VERSION=\"2.0\" -DPACKAGE_STRING=\"PortMixer\ 2.0\" -DPACKAGE_BUGREPORT=\"audacity.sourceforge.net\" -DSTDC_HEADERS=1
+CFLAGS += -O2 -I
+CFLAGS += -Iinclude
+
+all : $(LIBRARY)
+
+tests:
+ cd tests && $(MAKE) all
+
+$(LIBRARY): $(OBJECTS)
+ $(AR) ruv $(LIBRARY) $(OBJECTS)
+ $(RANLIB) $(LIBRARY)
+
+%.o : src/%.c
+ $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@
+
+clean :
+ -rm -f $(LIBRARY)
+ -rm -f $(OBJECTS)
+
+distclean: clean
+ -$(RM) -rf config.log config.status autom4te.cache Makefile portmixer-v2
+
+dist:
+ rm -rf portmixer-v2
+ mkdir portmixer-v2
+ cp -pr include src LICENSE.txt README.txt portaudio.patch Makefile.in configure.ac configure portmixer-v2
+ tar -zcf ../portmixer-v2.tar.gz portmixer-v2
+
+strip :
+ strip $(LIBRARY)
+ ranlib $(LIBRARY)
Added: freeswitch/branches/cseket/libs/portmixer/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/Makefile.in Fri Aug 24 13:53:53 2007
@@ -0,0 +1,42 @@
+### PortMixer library Makefile
+
+OBJECTS = @objects@
+
+LIBRARY = libportmixer.a
+
+CC = @CC@
+AR = @AR@
+RANLIB = @RANLIB@
+
+DEFS += @DEFS@
+CFLAGS += @cflags@
+CFLAGS += @include@
+
+all : $(LIBRARY)
+
+tests:
+ cd tests && $(MAKE) all
+
+$(LIBRARY): $(OBJECTS)
+ $(AR) ruv $(LIBRARY) $(OBJECTS)
+ $(RANLIB) $(LIBRARY)
+
+%.o : src/%.c
+ $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@
+
+clean :
+ -rm -f $(LIBRARY)
+ -rm -f $(OBJECTS)
+
+distclean: clean
+ -$(RM) -rf config.log config.status autom4te.cache Makefile portmixer-v2
+
+dist:
+ rm -rf portmixer-v2
+ mkdir portmixer-v2
+ cp -pr include src LICENSE.txt README.txt portaudio.patch Makefile.in configure.ac configure portmixer-v2
+ tar -zcf ../portmixer-v2.tar.gz portmixer-v2
+
+strip :
+ strip $(LIBRARY)
+ ranlib $(LIBRARY)
Added: freeswitch/branches/cseket/libs/portmixer/README.txt
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/README.txt Fri Aug 24 13:53:53 2007
@@ -0,0 +1,6 @@
+This is where some sort of README should be...but this is all there is for now.
+
+As of October 1st, 2006, Portaudio v2.0 (or v1.9) doesn't have the required support
+to use this version of Portmixer. To add the support, apply the portaudio.patch
+found in this direcotry.
+
Added: freeswitch/branches/cseket/libs/portmixer/configure
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/configure Fri Aug 24 13:53:53 2007
@@ -0,0 +1,4415 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for PortMixer 2.0.
+#
+# Report bugs to <audacity.sourceforge.net>.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='PortMixer'
+PACKAGE_TARNAME='portmixer'
+PACKAGE_VERSION='2.0'
+PACKAGE_STRING='PortMixer 2.0'
+PACKAGE_BUGREPORT='audacity.sourceforge.net'
+
+ac_unique_file="src"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB AR CPP EGREP cflags include objects LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures PortMixer 2.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of PortMixer 2.0:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-debug enable debug compilation
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pa-include specify path to portaudio v2.0 include directory
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <audacity.sourceforge.net>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+PortMixer configure 2.0
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by PortMixer $as_me 2.0, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_files="$ac_config_files Makefile"
+
+
+#
+# Checks for programs.
+#
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+# Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $AR in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_AR="$AR" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_AR" && ac_cv_path_AR="no"
+ ;;
+esac
+fi
+AR=$ac_cv_path_AR
+
+if test -n "$AR"; then
+ echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if [ $AR = "no" ] ; then
+ { { echo "$as_me:$LINENO: error: \"Could not find ar - needed to create a library\"" >&5
+echo "$as_me: error: \"Could not find ar - needed to create a library\"" >&2;}
+ { (exit 1); exit 1; }; };
+fi
+
+#
+# Checks for libraries.
+#
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+#
+# Check for debug
+#
+echo "$as_me:$LINENO: checking whether to compile debug version" >&5
+echo $ECHO_N "checking whether to compile debug version... $ECHO_C" >&6
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+ enableval="$enable_debug"
+ cflags="$cflags -g"
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ cflags="$cflags -O2"
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+#
+# Check for portaudio path
+#
+
+# Check whether --with-pa-include or --without-pa-include was given.
+if test "${with_pa_include+set}" = set; then
+ withval="$with_pa_include"
+ with_portaudio=$withval
+else
+ with_portaudio=""
+fi;
+
+#
+#
+#
+if [ with_portaudio != "" ] ; then
+ CPPFLAGS="$CPPFLAGS -I$withval"
+ cflags="$cflags -I$withval"
+
+fi
+
+#
+# Make sure the support is there
+#
+have_support=yes
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pa_win_ds.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "PaWinDS_GetStreamInputGUID" >/dev/null 2>&1; then
+ :
+#else
+# have_support=no
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pa_linux_alsa.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "PaAlsa_GetStreamInputCard" >/dev/null 2>&1; then
+ :
+#else
+# have_support=no
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pa_win_wmme.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "PaWinMME_GetStreamInputHandle" >/dev/null 2>&1; then
+ :
+#else
+# have_support=no
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pa_mac_core.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "PaMacCore_GetStreamInputDevice" >/dev/null 2>&1; then
+ :
+#else
+# have_support=no
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pa_unix_oss.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "PaOSS_GetStreamInputDevice" >/dev/null 2>&1; then
+ :
+#else
+# have_support=no
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <portaudio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "Pa_GetStreamHostApiType" >/dev/null 2>&1; then
+ :
+#else
+# have_support=no
+fi
+rm -f conftest*
+
+if [ $have_support = "no" ] ; then
+ { { echo "$as_me:$LINENO: error: \"You're version of portaudio does not include required functions\"" >&5
+echo "$as_me: error: \"You're version of portaudio does not include required functions\"" >&2;}
+ { (exit 1); exit 1; }; };
+fi
+
+#
+#
+#
+include=-Iinclude
+
+objects=px_mixer.o
+
+
+#
+# Check which APIs are available
+#
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_linux_soundcard_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5
+echo $ECHO_N "checking for linux/soundcard.h... $ECHO_C" >&6
+if test "${ac_cv_header_linux_soundcard_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5
+echo "${ECHO_T}$ac_cv_header_linux_soundcard_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking linux/soundcard.h usability" >&5
+echo $ECHO_N "checking linux/soundcard.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <linux/soundcard.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking linux/soundcard.h presence" >&5
+echo $ECHO_N "checking linux/soundcard.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <linux/soundcard.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: linux/soundcard.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: linux/soundcard.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: linux/soundcard.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: linux/soundcard.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: linux/soundcard.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: linux/soundcard.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: linux/soundcard.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: linux/soundcard.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to audacity.sourceforge.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for linux/soundcard.h" >&5
+echo $ECHO_N "checking for linux/soundcard.h... $ECHO_C" >&6
+if test "${ac_cv_header_linux_soundcard_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_linux_soundcard_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_linux_soundcard_h" >&5
+echo "${ECHO_T}$ac_cv_header_linux_soundcard_h" >&6
+
+fi
+if test $ac_cv_header_linux_soundcard_h = yes; then
+ have_oss=yes
+else
+ have_oss=no
+fi
+
+
+if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5
+echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking alsa/asoundlib.h usability" >&5
+echo $ECHO_N "checking alsa/asoundlib.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <alsa/asoundlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking alsa/asoundlib.h presence" >&5
+echo $ECHO_N "checking alsa/asoundlib.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <alsa/asoundlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: alsa/asoundlib.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to audacity.sourceforge.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for alsa/asoundlib.h" >&5
+echo $ECHO_N "checking for alsa/asoundlib.h... $ECHO_C" >&6
+if test "${ac_cv_header_alsa_asoundlib_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_alsa_asoundlib_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_alsa_asoundlib_h" >&5
+echo "${ECHO_T}$ac_cv_header_alsa_asoundlib_h" >&6
+
+fi
+if test $ac_cv_header_alsa_asoundlib_h = yes; then
+ have_alsa=yes
+else
+ have_alsa=no
+fi
+
+
+if test "${ac_cv_header_CoreAudio_CoreAudio_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for CoreAudio/CoreAudio.h" >&5
+echo $ECHO_N "checking for CoreAudio/CoreAudio.h... $ECHO_C" >&6
+if test "${ac_cv_header_CoreAudio_CoreAudio_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_CoreAudio_CoreAudio_h" >&5
+echo "${ECHO_T}$ac_cv_header_CoreAudio_CoreAudio_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking CoreAudio/CoreAudio.h usability" >&5
+echo $ECHO_N "checking CoreAudio/CoreAudio.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <CoreAudio/CoreAudio.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking CoreAudio/CoreAudio.h presence" >&5
+echo $ECHO_N "checking CoreAudio/CoreAudio.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <CoreAudio/CoreAudio.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: CoreAudio/CoreAudio.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: CoreAudio/CoreAudio.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to audacity.sourceforge.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for CoreAudio/CoreAudio.h" >&5
+echo $ECHO_N "checking for CoreAudio/CoreAudio.h... $ECHO_C" >&6
+if test "${ac_cv_header_CoreAudio_CoreAudio_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_CoreAudio_CoreAudio_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_CoreAudio_CoreAudio_h" >&5
+echo "${ECHO_T}$ac_cv_header_CoreAudio_CoreAudio_h" >&6
+
+fi
+if test $ac_cv_header_CoreAudio_CoreAudio_h = yes; then
+ have_coreaudio=yes
+else
+ have_coreaudio=no
+fi
+
+
+
+#
+# Set up to use the identified ones
+#
+{ echo "$as_me:$LINENO: ---------------------------------------" >&5
+echo "$as_me: ---------------------------------------" >&6;};
+if [ $have_oss = "yes" ] ; then
+ { echo "$as_me:$LINENO: Including support for OSS" >&5
+echo "$as_me: Including support for OSS" >&6;};
+ cat >>confdefs.h <<\_ACEOF
+#define PX_USE_UNIX_OSS 1
+_ACEOF
+
+ objects="$objects px_unix_oss.o"
+fi
+
+if [ $have_alsa = "yes" ] ; then
+ { echo "$as_me:$LINENO: Including support for ALSA" >&5
+echo "$as_me: Including support for ALSA" >&6;};
+ cat >>confdefs.h <<\_ACEOF
+#define PX_USE_LINUX_ALSA 1
+_ACEOF
+
+ objects="$objects px_linux_alsa.o"
+fi
+
+if [ $have_coreaudio = "yes" ] ; then
+ { echo "$as_me:$LINENO: Including support for Coreaudio" >&5
+echo "$as_me: Including support for Coreaudio" >&6;};
+ cat >>confdefs.h <<\_ACEOF
+#define PX_USE_MAC_COREAUDIO 1
+_ACEOF
+
+ objects="$objects px_mac_coreaudio.o"
+fi
+{ echo "$as_me:$LINENO: ---------------------------------------" >&5
+echo "$as_me: ---------------------------------------" >&6;};
+
+#
+# Write it all out
+#
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+t quote
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output. A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by PortMixer $as_me 2.0, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf(a)gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+PortMixer config.status 2.0
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@AR@,$AR,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@cflags@,$cflags,;t t
+s,@include@,$include,;t t
+s,@objects@,$objects,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
Added: freeswitch/branches/cseket/libs/portmixer/configure.ac
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/configure.ac Fri Aug 24 13:53:53 2007
@@ -0,0 +1,104 @@
+#
+# PortMixer 2.0
+#
+
+AC_INIT(PortMixer, 2.0, audacity.sourceforge.net, portmixer)
+AC_CONFIG_SRCDIR(src)
+AC_CONFIG_FILES([Makefile])
+
+#
+# Checks for programs.
+#
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_PATH_PROG(AR, ar, no)
+if [[ $AR = "no" ]] ; then
+ AC_MSG_ERROR("Could not find ar - needed to create a library");
+fi
+
+#
+# Checks for libraries.
+#
+AC_HEADER_STDC
+
+#
+# Check for debug
+#
+AC_MSG_CHECKING(whether to compile debug version)
+AC_ARG_ENABLE([debug],
+ AC_HELP_STRING([--enable-debug],
+ [enable debug compilation]),
+ [AC_SUBST( cflags, ["$cflags -g"] ) AC_MSG_RESULT(yes)],
+ [AC_SUBST( cflags, ["$cflags -O2"] ) AC_MSG_RESULT(no)])
+
+#
+# Check for portaudio path
+#
+AC_ARG_WITH([pa-include],
+ AC_HELP_STRING([--with-pa-include],
+ [specify path to portaudio v2.0 include directory]),
+ [with_portaudio=$withval],
+ [with_portaudio=""])
+
+#
+#
+#
+if [[ with_portaudio != "" ]] ; then
+ CPPFLAGS="$CPPFLAGS -I$withval"
+ AC_SUBST(cflags, ["$cflags -I$withval"] )
+fi
+
+#
+# Make sure the support is there
+#
+have_support=yes
+AC_EGREP_HEADER([PaWinDS_GetStreamInputGUID], [pa_win_ds.h], , [have_support=no])
+AC_EGREP_HEADER([PaAlsa_GetStreamInputCard], [pa_linux_alsa.h], , [have_support=no])
+AC_EGREP_HEADER([PaWinMME_GetStreamInputHandle], [pa_win_wmme.h], , [have_support=no])
+AC_EGREP_HEADER([PaMacCore_GetStreamInputDevice], [pa_mac_core.h], , [have_support=no])
+AC_EGREP_HEADER([PaOSS_GetStreamInputDevice], [pa_unix_oss.h], , [have_support=no])
+AC_EGREP_HEADER([Pa_GetStreamHostApiType], [portaudio.h], , [have_support=no])
+#if [[ $have_support = "no" ]] ; then
+# AC_MSG_ERROR("You're version of portaudio does not include required functions");
+#fi
+
+#
+#
+#
+AC_SUBST( include, [-Iinclude] )
+AC_SUBST( objects, [px_mixer.o] )
+
+#
+# Check which APIs are available
+#
+AC_CHECK_HEADER(linux/soundcard.h, have_oss=yes, have_oss=no)
+AC_CHECK_HEADER(alsa/asoundlib.h, have_alsa=yes, have_alsa=no)
+AC_CHECK_HEADER(CoreAudio/CoreAudio.h, have_coreaudio=yes, have_coreaudio=no)
+
+#
+# Set up to use the identified ones
+#
+AC_MSG_NOTICE(---------------------------------------);
+if [[ $have_oss = "yes" ]] ; then
+ AC_MSG_NOTICE(Including support for OSS);
+ AC_DEFINE(PX_USE_UNIX_OSS)
+ objects="$objects px_unix_oss.o"
+fi
+
+if [[ $have_alsa = "yes" ]] ; then
+ AC_MSG_NOTICE(Including support for ALSA);
+ AC_DEFINE(PX_USE_LINUX_ALSA)
+ objects="$objects px_linux_alsa.o"
+fi
+
+if [[ $have_coreaudio = "yes" ]] ; then
+ AC_MSG_NOTICE(Including support for Coreaudio);
+ AC_DEFINE(PX_USE_MAC_COREAUDIO)
+ objects="$objects px_mac_coreaudio.o"
+fi
+AC_MSG_NOTICE(---------------------------------------);
+
+#
+# Write it all out
+#
+AC_OUTPUT
Added: freeswitch/branches/cseket/libs/portmixer/include/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/include/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,2 @@
+/portmixer.h/1.2/Wed Jul 11 06:16:15 2007//
+D
Added: freeswitch/branches/cseket/libs/portmixer/include/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/include/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/include
Added: freeswitch/branches/cseket/libs/portmixer/include/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/include/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/include/portmixer.h
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/include/portmixer.h Fri Aug 24 13:53:53 2007
@@ -0,0 +1,139 @@
+#ifndef PORT_MIXER_H
+#define PORT_MIXER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/*
+ * PortMixer
+ * PortMixer API Header File
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include "portaudio.h"
+
+typedef void PxMixer;
+
+typedef float PxVolume; /* 0.0 (min) --> 1.0 (max) */
+typedef float PxBalance; /* -1.0 (left) --> 1.0 (right) */
+
+/*
+ Px_OpenMixer() returns a mixer which will work with the given PortAudio
+ audio device. Pass 0 as the index for the first (default) mixer.
+*/
+
+PxMixer *Px_OpenMixer( void *pa_stream, int i );
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer( PxMixer *mixer );
+
+/*
+ Px_GetNumMixers returns the number of mixers which could be
+ used with the given PortAudio device. On most systems, there
+ will be only one mixer for each device; however there may be
+ multiple mixers for each device, or possibly multiple mixers
+ which are independent of any particular PortAudio device.
+*/
+
+int Px_GetNumMixers( PxMixer *mixer );
+const char *Px_GetMixerName( PxMixer *mixer, int i );
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer );
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume );
+
+/*
+ Main output volume
+*/
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer );
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume );
+int Px_SupportsPCMOutputVolume( PxMixer* mixer ) ;
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer );
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i );
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i );
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume );
+
+/*
+ Input source
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer );
+const char *Px_GetInputSourceName( PxMixer *mixer, int i);
+int Px_GetCurrentInputSource( PxMixer *mixer ); /* may return -1 == none */
+void Px_SetCurrentInputSource( PxMixer *mixer, int i );
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer );
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume );
+
+/*
+ Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer );
+PxBalance Px_GetOutputBalance( PxMixer *mixer );
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance );
+
+/*
+ Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer );
+PxVolume Px_GetPlaythrough( PxMixer *mixer );
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PORT_AUDIO_H */
Added: freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+D
Added: freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/macproj
Added: freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/macproj/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/portaudio.patch
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/portaudio.patch Fri Aug 24 13:53:53 2007
@@ -0,0 +1,1239 @@
+#
+# This patch applies to portaudio v19 source as of 2007-jun-01.
+#
+diff -ruN pa/build/msvc/PAStaticWMMEv19.vcproj pam/build/msvc/PAStaticWMMEv19.vcproj
+--- pa/build/msvc/PAStaticWMMEv19.vcproj 1969-12-31 18:00:00.000000000 -0600
++++ pam/build/msvc/PAStaticWMMEv19.vcproj 2007-06-03 06:23:38.000000000 -0500
+@@ -0,0 +1,774 @@
++<?xml version="1.0" encoding="Windows-1252"?>
++<VisualStudioProject
++ ProjectType="Visual C++"
++ Version="8.00"
++ Name="PAStaticWMMEv19"
++ ProjectGUID="{7ABA0F80-94AE-4E82-AB89-2E1258212D59}"
++ RootNamespace="PAStaticWMMEv19"
++ >
++ <Platforms>
++ <Platform
++ Name="Win32"
++ />
++ </Platforms>
++ <ToolFiles>
++ </ToolFiles>
++ <Configurations>
++ <Configuration
++ Name="Release|Win32"
++ OutputDirectory="$(ConfigurationName)"
++ IntermediateDirectory="$(ConfigurationName)"
++ ConfigurationType="4"
++ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
++ UseOfMFC="0"
++ ATLMinimizesCRunTimeLibraryUsage="false"
++ CharacterSet="2"
++ >
++ <Tool
++ Name="VCPreBuildEventTool"
++ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF "%DXSDK_DIR%" == "" echo #define PA_NO_DS >>".\$(ConfigurationName)\config.h"
IF "%ASIOSDK_DIR%" == "" echo #define PA_NO_ASIO >>".\$(ConfigurationName)\config.h"
"
++ />
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ <Tool
++ Name="VCXMLDataGeneratorTool"
++ />
++ <Tool
++ Name="VCWebServiceProxyGeneratorTool"
++ />
++ <Tool
++ Name="VCMIDLTool"
++ />
++ <Tool
++ Name="VCCLCompilerTool"
++ AdditionalOptions="/O2"
++ Optimization="2"
++ InlineFunctionExpansion="1"
++ AdditionalIncludeDirectories="../../include;../../src/common"
++ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
++ StringPooling="true"
++ RuntimeLibrary="0"
++ EnableFunctionLevelLinking="true"
++ UsePrecompiledHeader="0"
++ PrecompiledHeaderFile=".\$(ConfigurationName)/PA19StaticWMME.pch"
++ AssemblerListingLocation=".\$(ConfigurationName)/"
++ ObjectFile=".\$(ConfigurationName)/"
++ ProgramDataBaseFileName=".\$(ConfigurationName)/"
++ WarningLevel="3"
++ SuppressStartupBanner="true"
++ CompileAs="0"
++ DisableSpecificWarnings="4996"
++ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
++ />
++ <Tool
++ Name="VCManagedResourceCompilerTool"
++ />
++ <Tool
++ Name="VCResourceCompilerTool"
++ PreprocessorDefinitions="NDEBUG"
++ Culture="1032"
++ />
++ <Tool
++ Name="VCPreLinkEventTool"
++ />
++ <Tool
++ Name="VCLibrarianTool"
++ OutputFile="$(SolutionDir)\$(ConfigurationName)\pastaticwmmev19.lib"
++ SuppressStartupBanner="true"
++ />
++ <Tool
++ Name="VCALinkTool"
++ />
++ <Tool
++ Name="VCXDCMakeTool"
++ />
++ <Tool
++ Name="VCBscMakeTool"
++ />
++ <Tool
++ Name="VCFxCopTool"
++ />
++ <Tool
++ Name="VCPostBuildEventTool"
++ CommandLine="set CFLAGS=/I "../../include" /I "../../src/common" /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_MBCS" /O2 /Ob1 /GF /FD /EHsc /MT /Gy /W3 /c /wd4996 /nologo /Fo".\$(OutDir)/" /Fd".\$(OutDir)/"
set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds.c"
cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds_dynlink.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

if "%ASIOSDK_DIR%"=="" goto NoASIO

cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\pa_asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\iasiothiscallresolver.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\common\asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\asiodrivers.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\pc\asiolist.cpp"

:NoASIO

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
++ />
++ </Configuration>
++ <Configuration
++ Name="Debug|Win32"
++ OutputDirectory="$(ConfigurationName)"
++ IntermediateDirectory="$(ConfigurationName)"
++ ConfigurationType="4"
++ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
++ UseOfMFC="0"
++ ATLMinimizesCRunTimeLibraryUsage="false"
++ CharacterSet="2"
++ >
++ <Tool
++ Name="VCPreBuildEventTool"
++ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF "%DXSDK_DIR%" == "" echo #define PA_NO_DS >>".\$(ConfigurationName)\config.h"
IF "%ASIOSDK_DIR%" == "" echo #define PA_NO_ASIO >>".\$(ConfigurationName)\config.h"
"
++ />
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ <Tool
++ Name="VCXMLDataGeneratorTool"
++ />
++ <Tool
++ Name="VCWebServiceProxyGeneratorTool"
++ />
++ <Tool
++ Name="VCMIDLTool"
++ />
++ <Tool
++ Name="VCCLCompilerTool"
++ Optimization="0"
++ AdditionalIncludeDirectories="../../include;../../src/common"
++ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
++ BasicRuntimeChecks="3"
++ RuntimeLibrary="1"
++ UsePrecompiledHeader="0"
++ PrecompiledHeaderFile=".\$(ConfigurationName)/PA19StaticWMME.pch"
++ AssemblerListingLocation=".\$(ConfigurationName)/"
++ ObjectFile=".\$(ConfigurationName)/"
++ ProgramDataBaseFileName=".\$(ConfigurationName)/"
++ WarningLevel="3"
++ SuppressStartupBanner="true"
++ DebugInformationFormat="4"
++ CompileAs="0"
++ DisableSpecificWarnings="4996"
++ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
++ />
++ <Tool
++ Name="VCManagedResourceCompilerTool"
++ />
++ <Tool
++ Name="VCResourceCompilerTool"
++ PreprocessorDefinitions="_DEBUG"
++ Culture="1032"
++ />
++ <Tool
++ Name="VCPreLinkEventTool"
++ />
++ <Tool
++ Name="VCLibrarianTool"
++ OutputFile="$(SolutionDir)\$(ConfigurationName)\pastaticwmmev19d.lib"
++ SuppressStartupBanner="true"
++ />
++ <Tool
++ Name="VCALinkTool"
++ />
++ <Tool
++ Name="VCXDCMakeTool"
++ />
++ <Tool
++ Name="VCBscMakeTool"
++ />
++ <Tool
++ Name="VCFxCopTool"
++ />
++ <Tool
++ Name="VCPostBuildEventTool"
++ CommandLine="set CFLAGS= /I "../../include" /I "../../src/common" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_MBCS" /Od /FD /EHsc /RTC1 /MTd /W3 /c /ZI /wd4996 /nologo /Fo".\$(OutDir)/" /Fd".\$(OutDir)/"
set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds.c"
cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds_dynlink.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

if "%ASIOSDK_DIR%"=="" goto NoASIO

cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\pa_asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\iasiothiscallresolver.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\common\asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\asiodrivers.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\pc\asiolist.cpp"

:NoASIO

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
++ />
++ </Configuration>
++ <Configuration
++ Name="Unicode_Debug|Win32"
++ OutputDirectory="$(ConfigurationName)"
++ IntermediateDirectory="$(ConfigurationName)"
++ ConfigurationType="4"
++ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
++ UseOfMFC="0"
++ ATLMinimizesCRunTimeLibraryUsage="false"
++ CharacterSet="0"
++ >
++ <Tool
++ Name="VCPreBuildEventTool"
++ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF "%DXSDK_DIR%" == "" echo #define PA_NO_DS >>".\$(ConfigurationName)\config.h"
IF "%ASIOSDK_DIR%" == "" echo #define PA_NO_ASIO >>".\$(ConfigurationName)\config.h"
"
++ />
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ <Tool
++ Name="VCXMLDataGeneratorTool"
++ />
++ <Tool
++ Name="VCWebServiceProxyGeneratorTool"
++ />
++ <Tool
++ Name="VCMIDLTool"
++ />
++ <Tool
++ Name="VCCLCompilerTool"
++ Optimization="0"
++ AdditionalIncludeDirectories="../../include;../../src/common"
++ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
++ BasicRuntimeChecks="3"
++ RuntimeLibrary="1"
++ UsePrecompiledHeader="0"
++ PrecompiledHeaderFile=".\$(ConfigurationName)/PA19StaticWMME.pch"
++ AssemblerListingLocation=".\$(ConfigurationName)/"
++ ObjectFile=".\$(ConfigurationName)/"
++ ProgramDataBaseFileName=".\$(ConfigurationName)/"
++ WarningLevel="3"
++ SuppressStartupBanner="true"
++ DebugInformationFormat="4"
++ CompileAs="0"
++ DisableSpecificWarnings="4996"
++ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
++ />
++ <Tool
++ Name="VCManagedResourceCompilerTool"
++ />
++ <Tool
++ Name="VCResourceCompilerTool"
++ PreprocessorDefinitions="_DEBUG"
++ Culture="1032"
++ />
++ <Tool
++ Name="VCPreLinkEventTool"
++ />
++ <Tool
++ Name="VCLibrarianTool"
++ OutputFile="$(SolutionDir)\$(ConfigurationName)\pastaticwmmev19ud.lib"
++ SuppressStartupBanner="true"
++ />
++ <Tool
++ Name="VCALinkTool"
++ />
++ <Tool
++ Name="VCXDCMakeTool"
++ />
++ <Tool
++ Name="VCBscMakeTool"
++ />
++ <Tool
++ Name="VCFxCopTool"
++ />
++ <Tool
++ Name="VCPostBuildEventTool"
++ CommandLine="set CFLAGS= /I "../../include" /I "../../src/common" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_MBCS" /Od /FD /EHsc /RTC1 /MTd /W3 /c /ZI /wd4996 /nologo /Fo".\$(OutDir)/" /Fd".\$(OutDir)/"
set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds.c"
cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds_dynlink.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

if "%ASIOSDK_DIR%"=="" goto NoASIO

cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\pa_asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\iasiothiscallresolver.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\common\asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\asiodrivers.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\pc\asiolist.cpp"

:NoASIO

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
++ />
++ </Configuration>
++ <Configuration
++ Name="Unicode_Release|Win32"
++ OutputDirectory="$(ConfigurationName)"
++ IntermediateDirectory="$(ConfigurationName)"
++ ConfigurationType="4"
++ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
++ UseOfMFC="0"
++ ATLMinimizesCRunTimeLibraryUsage="false"
++ CharacterSet="0"
++ >
++ <Tool
++ Name="VCPreBuildEventTool"
++ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF "%DXSDK_DIR%" == "" echo #define PA_NO_DS >>".\$(ConfigurationName)\config.h"
IF "%ASIOSDK_DIR%" == "" echo #define PA_NO_ASIO >>".\$(ConfigurationName)\config.h"
"
++ />
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ <Tool
++ Name="VCXMLDataGeneratorTool"
++ />
++ <Tool
++ Name="VCWebServiceProxyGeneratorTool"
++ />
++ <Tool
++ Name="VCMIDLTool"
++ />
++ <Tool
++ Name="VCCLCompilerTool"
++ AdditionalOptions="/O2"
++ Optimization="2"
++ InlineFunctionExpansion="1"
++ AdditionalIncludeDirectories="../../include;../../src/common"
++ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
++ StringPooling="true"
++ RuntimeLibrary="0"
++ EnableFunctionLevelLinking="true"
++ UsePrecompiledHeader="0"
++ PrecompiledHeaderFile=".\$(ConfigurationName)/PA19StaticWMME.pch"
++ AssemblerListingLocation=".\$(ConfigurationName)/"
++ ObjectFile=".\$(ConfigurationName)/"
++ ProgramDataBaseFileName=".\$(ConfigurationName)/"
++ WarningLevel="3"
++ SuppressStartupBanner="true"
++ CompileAs="0"
++ DisableSpecificWarnings="4996"
++ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
++ />
++ <Tool
++ Name="VCManagedResourceCompilerTool"
++ />
++ <Tool
++ Name="VCResourceCompilerTool"
++ PreprocessorDefinitions="NDEBUG"
++ Culture="1032"
++ />
++ <Tool
++ Name="VCPreLinkEventTool"
++ />
++ <Tool
++ Name="VCLibrarianTool"
++ OutputFile="$(SolutionDir)\$(ConfigurationName)\pastaticwmmev19u.lib"
++ SuppressStartupBanner="true"
++ />
++ <Tool
++ Name="VCALinkTool"
++ />
++ <Tool
++ Name="VCXDCMakeTool"
++ />
++ <Tool
++ Name="VCBscMakeTool"
++ />
++ <Tool
++ Name="VCFxCopTool"
++ />
++ <Tool
++ Name="VCPostBuildEventTool"
++ CommandLine="set CFLAGS=/I "../../include" /I "../../src/common" /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_MBCS" /O2 /Ob1 /GF /FD /EHsc /MT /Gy /W3 /c /wd4996 /nologo /Fo".\$(OutDir)/" /Fd".\$(OutDir)/"
set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds.c"
cl %CFLAGS% /I "%DXSDK_DIR%include" "..\..\src\hostapi\dsound\pa_win_ds_dynlink.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

if "%ASIOSDK_DIR%"=="" goto NoASIO

cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\pa_asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "..\..\src\hostapi\asio\iasiothiscallresolver.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\common\asio.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\asiodrivers.cpp"
cl %CFLAGS% /I "%ASIOSDK_DIR%/common" /I "%ASIOSDK_DIR%/host" /I "%ASIOSDK_DIR%/host/pc" "%ASIOSDK_DIR%\host\pc\asiolist.cpp"

:NoASIO

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
++ />
++ </Configuration>
++ </Configurations>
++ <References>
++ </References>
++ <Files>
++ <Filter
++ Name="Source Files"
++ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
++ >
++ <Filter
++ Name="common"
++ >
++ <File
++ RelativePath="..\..\src\common\pa_allocation.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_allocation.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_converters.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_converters.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_cpuload.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_cpuload.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_dither.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_dither.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_endianness.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_front.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_hostapi.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_process.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_process.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_skeleton.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_stream.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_stream.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_trace.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_trace.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_types.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\common\pa_util.h"
++ >
++ </File>
++ </Filter>
++ <Filter
++ Name="hostapi"
++ >
++ <Filter
++ Name="wmme"
++ >
++ <File
++ RelativePath="..\..\src\hostapi\wmme\pa_win_wmme.c"
++ >
++ </File>
++ </Filter>
++ <Filter
++ Name="wdmks"
++ >
++ <File
++ RelativePath="..\..\src\hostapi\wdmks\pa_win_wdmks.c"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ </File>
++ </Filter>
++ <Filter
++ Name="dsound"
++ >
++ <File
++ RelativePath="..\..\src\hostapi\dsound\pa_win_ds.c"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ </File>
++ <File
++ RelativePath="..\..\src\hostapi\dsound\pa_win_ds_dynlink.c"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ </File>
++ <File
++ RelativePath="..\..\src\hostapi\dsound\pa_win_ds_dynlink.h"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ </File>
++ </Filter>
++ <Filter
++ Name="asio"
++ >
++ <File
++ RelativePath="..\..\src\hostapi\asio\iasiothiscallresolver.cpp"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ </File>
++ <File
++ RelativePath="..\..\src\hostapi\asio\iasiothiscallresolver.h"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ </File>
++ <File
++ RelativePath="..\..\src\hostapi\asio\pa_asio.cpp"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCLCompilerTool"
++ />
++ </FileConfiguration>
++ </File>
++ </Filter>
++ </Filter>
++ <Filter
++ Name="os"
++ >
++ <File
++ RelativePath="..\..\src\os\win\pa_win_hostapis.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\os\win\pa_win_util.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\os\win\pa_x86_plain_converters.c"
++ >
++ </File>
++ <File
++ RelativePath="..\..\src\os\win\pa_x86_plain_converters.h"
++ >
++ </File>
++ </Filter>
++ </Filter>
++ <Filter
++ Name="Public Headers"
++ Filter="h;hpp;hxx;hm;inl"
++ >
++ <File
++ RelativePath="..\..\include\pa_win_ds.h"
++ >
++ <FileConfiguration
++ Name="Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Debug|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ <FileConfiguration
++ Name="Unicode_Release|Win32"
++ ExcludedFromBuild="true"
++ >
++ <Tool
++ Name="VCCustomBuildTool"
++ />
++ </FileConfiguration>
++ </File>
++ <File
++ RelativePath="..\..\include\pa_win_wmme.h"
++ >
++ </File>
++ <File
++ RelativePath="..\..\include\portaudio.h"
++ >
++ </File>
++ </Filter>
++ </Files>
++ <Globals>
++ </Globals>
++</VisualStudioProject>
+diff -ruN pa/include/pa_unix_oss.h pam/include/pa_unix_oss.h
+--- pa/include/pa_unix_oss.h 1969-12-31 18:00:00.000000000 -0600
++++ pam/include/pa_unix_oss.h 2007-06-03 06:41:57.000000000 -0500
+@@ -0,0 +1,104 @@
++#ifndef PA_UNIX_OSS_H
++#define PA_UNIX_OSS_H
++
++/*
++ * $Id: portaudio.patch,v 1.2 2007/06/03 08:30:36 llucius Exp $
++ * PortAudio Portable Real-Time Audio Library
++ * OSS-specific extensions
++ *
++ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
++ *
++ * 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.
++ *
++ * Any person wishing to distribute modifications to the Software is
++ * requested to send the modifications to the original developer so that
++ * they can be incorporated into the canonical version.
++ *
++ * 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.
++ *
++ */
++
++/** @file
++ * OSS-specific PortAudio API extension header file.
++ */
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++const char *PaOSS_GetStreamInputDevice( PaStream *s );
++
++const char *PaOSS_GetStreamOutputDevice( PaStream *s );
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
++#ifndef PA_UNIX_OSS_H
++#define PA_UNIX_OSS_H
++
++/*
++ * $Id: portaudio.patch,v 1.2 2007/06/03 08:30:36 llucius Exp $
++ * PortAudio Portable Real-Time Audio Library
++ * OSS-specific extensions
++ *
++ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
++ *
++ * 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.
++ *
++ * Any person wishing to distribute modifications to the Software is
++ * requested to send the modifications to the original developer so that
++ * they can be incorporated into the canonical version.
++ *
++ * 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.
++ *
++ */
++
++/** @file
++ * OSS-specific PortAudio API extension header file.
++ */
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++const char *PaOSS_GetStreamInputDevice( PaStream *s );
++
++const char *PaOSS_GetStreamOutputDevice( PaStream *s );
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+diff -ruN pa/include/pa_win_ds.h pam/include/pa_win_ds.h
+--- pa/include/pa_win_ds.h 1969-12-31 18:00:00.000000000 -0600
++++ pam/include/pa_win_ds.h 2007-06-03 06:41:57.000000000 -0500
+@@ -0,0 +1,138 @@
++#ifndef PA_WIN_DS_H
++#define PA_WIN_DS_H
++/*
++ * $Id: portaudio.patch,v 1.2 2007/06/03 08:30:36 llucius Exp $
++ * PortAudio Portable Real-Time Audio Library
++ * DirectSound specific extensions
++ *
++ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
++ *
++ * 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.
++ *
++ * Any person wishing to distribute modifications to the Software is
++ * requested to send the modifications to the original developer so that
++ * they can be incorporated into the canonical version.
++ *
++ * 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.
++ *
++ */
++
++/** @file
++ @brief DirectSound-specific PortAudio API extension header file.
++*/
++
++
++#include "portaudio.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++
++/** Retrieve the GUID of the input device.
++
++ @param stream The stream to query.
++
++ @return A pointer to the GUID, or NULL if none.
++*/
++LPGUID PaWinDS_GetStreamInputGUID( PaStream* s );
++
++
++/** Retrieve the GUID of the output device.
++
++ @param stream The stream to query.
++
++ @return A pointer to the GUID, or NULL if none.
++*/
++LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s );
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* PA_WIN_DS_H */
++#ifndef PA_WIN_DS_H
++#define PA_WIN_DS_H
++/*
++ * $Id: portaudio.patch,v 1.2 2007/06/03 08:30:36 llucius Exp $
++ * PortAudio Portable Real-Time Audio Library
++ * DirectSound specific extensions
++ *
++ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
++ *
++ * 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.
++ *
++ * Any person wishing to distribute modifications to the Software is
++ * requested to send the modifications to the original developer so that
++ * they can be incorporated into the canonical version.
++ *
++ * 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.
++ *
++ */
++
++/** @file
++ @brief DirectSound-specific PortAudio API extension header file.
++*/
++
++
++#include "portaudio.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++
++/** Retrieve the GUID of the input device.
++
++ @param stream The stream to query.
++
++ @return A pointer to the GUID, or NULL if none.
++*/
++LPGUID PaWinDS_GetStreamInputGUID( PaStream* s );
++
++
++/** Retrieve the GUID of the output device.
++
++ @param stream The stream to query.
++
++ @return A pointer to the GUID, or NULL if none.
++*/
++LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s );
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* PA_WIN_DS_H */
+diff -ruN pa/include/portaudio.h pam/include/portaudio.h
+--- pa/include/portaudio.h 2007-06-03 05:55:55.000000000 -0500
++++ pam/include/portaudio.h 2007-06-03 06:41:57.000000000 -0500
+@@ -1106,6 +1106,15 @@
+ signed long Pa_GetStreamWriteAvailable( PaStream* stream );
+
+
++/** Retrieve the host type handling an open stream.
++
++ @return Returns a non-negative value representing the host API type
++ handling an open stream or, a PaErrorCode (which are always negative)
++ if PortAudio is not initialized or an error is encountered.
++*/
++PaHostApiTypeId Pa_GetStreamHostApiType( PaStream* stream );
++
++
+ /* Miscellaneous utilities */
+
+
+diff -ruN pa/src/common/pa_front.c pam/src/common/pa_front.c
+--- pa/src/common/pa_front.c 2007-06-03 05:56:15.000000000 -0500
++++ pam/src/common/pa_front.c 2007-06-03 06:41:57.000000000 -0500
+@@ -1315,8 +1315,10 @@
+ hostApiInputParametersPtr, hostApiOutputParametersPtr,
+ sampleRate, framesPerBuffer, streamFlags, streamCallback, userData );
+
+- if( result == paNoError )
++ if( result == paNoError ) {
+ AddOpenStream( *stream );
++ PA_STREAM_REP(*stream)->hostApiType = hostApi->info.type;
++ }
+
+
+ #ifdef PA_LOG_API_CALLS
+@@ -1908,6 +1910,32 @@
+ return result;
+ }
+
++PaHostApiTypeId Pa_GetStreamHostApiType( PaStream* stream )
++{
++ PaError error = PaUtil_ValidateStreamPointer( stream );
++ PaHostApiTypeId result;
++
++#ifdef PA_LOG_API_CALLS
++ PaUtil_DebugPrint("Pa_GetStreamHostApiType called:\n" );
++ PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
++#endif
++
++ if( error == paNoError )
++ {
++ result = PA_STREAM_REP(stream)->hostApiType;
++ }
++ else
++ {
++ result = (PaHostApiTypeId) error;
++ }
++
++#ifdef PA_LOG_API_CALLS
++ PaUtil_DebugPrint("Pa_GetStreamHostApiType returned:\n" );
++ PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
++#endif
++
++ return result;
++}
+
+ PaError Pa_GetSampleSize( PaSampleFormat format )
+ {
+diff -ruN pa/src/common/pa_stream.c pam/src/common/pa_stream.c
+--- pa/src/common/pa_stream.c 2007-06-03 05:56:15.000000000 -0500
++++ pam/src/common/pa_stream.c 2007-06-03 06:41:57.000000000 -0500
+@@ -93,6 +93,8 @@
+ streamRepresentation->streamInfo.inputLatency = 0.;
+ streamRepresentation->streamInfo.outputLatency = 0.;
+ streamRepresentation->streamInfo.sampleRate = 0.;
++
++ streamRepresentation->hostApiType = 0;
+ }
+
+
+diff -ruN pa/src/common/pa_stream.h pam/src/common/pa_stream.h
+--- pa/src/common/pa_stream.h 2007-06-03 05:56:15.000000000 -0500
++++ pam/src/common/pa_stream.h 2007-06-03 06:41:57.000000000 -0500
+@@ -152,6 +152,7 @@
+ PaStreamFinishedCallback *streamFinishedCallback;
+ void *userData;
+ PaStreamInfo streamInfo;
++ PaHostApiTypeId hostApiType;
+ } PaUtilStreamRepresentation;
+
+
+diff -ruN pa/src/hostapi/coreaudio/pa_mac_core_blocking.c pam/src/hostapi/coreaudio/pa_mac_core_blocking.c
+--- pa/src/hostapi/coreaudio/pa_mac_core_blocking.c 2007-06-03 05:56:06.000000000 -0500
++++ pam/src/hostapi/coreaudio/pa_mac_core_blocking.c 2007-06-03 06:41:57.000000000 -0500
+@@ -66,6 +66,9 @@
+ #ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS
+ # define OSAtomicOr32( a, b ) ( (*(b)) |= (a) )
+ # define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) )
++#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3
++# define OSAtomicOr32( a, b ) BitOrAtomic( a, (UInt32 *) b )
++# define OSAtomicAnd32( a, b ) BitAndAtomic( a, (UInt32 *) b )
+ #else
+ # include <libkern/OSAtomic.h>
+ #endif
+diff -ruN pa/src/hostapi/dsound/pa_win_ds.c pam/src/hostapi/dsound/pa_win_ds.c
+--- pa/src/hostapi/dsound/pa_win_ds.c 2007-06-03 05:56:11.000000000 -0500
++++ pam/src/hostapi/dsound/pa_win_ds.c 2007-06-03 06:41:57.000000000 -0500
+@@ -198,6 +198,7 @@
+ /* DirectSound specific data. */
+
+ /* Output */
++ LPGUID pOutputGuid;
+ LPDIRECTSOUND pDirectSound;
+ LPDIRECTSOUNDBUFFER pDirectSoundOutputBuffer;
+ DWORD outputBufferWriteOffsetBytes; /* last write position */
+@@ -213,6 +214,7 @@
+ double dsw_framesWritten;
+ double framesPlayed;
+ /* Input */
++ LPGUID pInputGuid;
+ LPDIRECTSOUNDCAPTURE pDirectSoundCapture;
+ LPDIRECTSOUNDCAPTUREBUFFER pDirectSoundInputBuffer;
+ INT bytesPerInputFrame;
+@@ -1267,8 +1269,8 @@
+ PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi;
+ PaWinDsStream *stream = 0;
+ int inputChannelCount, outputChannelCount;
+- PaSampleFormat inputSampleFormat, outputSampleFormat;
+- PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
++ PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0;
++ PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0;
+ unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames;
+
+ if( inputParameters )
+@@ -1486,6 +1488,11 @@
+ goto error;
+ }
+
++ stream->pOutputGuid = winDsHostApi->winDsDeviceInfos[outputParameters->device].lpGUID;
++ if( stream->pOutputGuid == NULL )
++ {
++ stream->pOutputGuid = (GUID *) &DSDEVID_DefaultPlayback;
++ }
+
+ hr = paWinDsDSoundEntryPoints.DirectSoundCreate( winDsHostApi->winDsDeviceInfos[outputParameters->device].lpGUID,
+ &stream->pDirectSound, NULL );
+@@ -1532,6 +1539,12 @@
+ goto error;
+ }
+
++ stream->pInputGuid = winDsHostApi->winDsDeviceInfos[inputParameters->device].lpGUID;
++ if( stream->pInputGuid == NULL )
++ {
++ stream->pInputGuid = (GUID *)&DSDEVID_DefaultCapture;
++ }
++
+ hr = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( winDsHostApi->winDsDeviceInfos[inputParameters->device].lpGUID,
+ &stream->pDirectSoundCapture, NULL );
+ if( hr != DS_OK )
+@@ -2193,4 +2206,19 @@
+ }
+
+
++/***********************************************************************************/
++LPGUID PaWinDS_GetStreamInputGUID( PaStream* s )
++{
++ PaWinDsStream *stream = (PaWinDsStream*)s;
+
++ return stream->pInputGuid;
++}
++
++
++/***********************************************************************************/
++LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s )
++{
++ PaWinDsStream *stream = (PaWinDsStream*)s;
++
++ return stream->pOutputGuid;
++}
+diff -ruN pa/src/hostapi/oss/pa_unix_oss.c pam/src/hostapi/oss/pa_unix_oss.c
+--- pa/src/hostapi/oss/pa_unix_oss.c 2007-06-03 05:55:58.000000000 -0500
++++ pam/src/hostapi/oss/pa_unix_oss.c 2007-06-03 06:41:57.000000000 -0500
+@@ -1942,3 +1942,26 @@
+ return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback );
+ }
+
++const char *PaOSS_GetStreamInputDevice( PaStream* s )
++{
++ PaOssStream *stream = (PaOssStream*)s;
++
++ if( stream->capture )
++ {
++ return stream->capture->devName;
++ }
++
++ return NULL;
++}
++
++const char *PaOSS_GetStreamOutputDevice( PaStream* s )
++{
++ PaOssStream *stream = (PaOssStream*)s;
++
++ if( stream->playback )
++ {
++ return stream->playback->devName;
++ }
++
++ return NULL;
++}
Added: freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,2 @@
+/portmixer.h/1.2/Tue Jun 15 07:59:34 2004//
+D
Added: freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/px_common
Added: freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_common/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/px_common/portmixer.h
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_common/portmixer.h Fri Aug 24 13:53:53 2007
@@ -0,0 +1,138 @@
+#ifndef PORT_MIXER_H
+#define PORT_MIXER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/*
+ * PortMixer
+ * PortMixer API Header File
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include "portaudio.h"
+
+typedef void PxMixer;
+
+typedef float PxVolume; /* 0.0 (min) --> 1.0 (max) */
+typedef float PxBalance; /* -1.0 (left) --> 1.0 (right) */
+
+/*
+ Px_GetNumMixers returns the number of mixers which could be
+ used with the given PortAudio device. On most systems, there
+ will be only one mixer for each device; however there may be
+ multiple mixers for each device, or possibly multiple mixers
+ which are independent of any particular PortAudio device.
+*/
+
+int Px_GetNumMixers( void *pa_stream );
+const char *Px_GetMixerName( void *pa_stream, int i );
+
+/*
+ Px_OpenMixer() returns a mixer which will work with the given PortAudio
+ audio device. Pass 0 as the index for the first (default) mixer.
+*/
+
+PxMixer *Px_OpenMixer( void *pa_stream, int i );
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer);
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer );
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume );
+
+/*
+ Main output volume
+*/
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer );
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume );
+int Px_SupportsPCMOutputVolume( PxMixer* mixer ) ;
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer );
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i );
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i );
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume );
+
+/*
+ Input source
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer );
+const char *Px_GetInputSourceName( PxMixer *mixer, int i);
+int Px_GetCurrentInputSource( PxMixer *mixer ); /* may return -1 == none */
+void Px_SetCurrentInputSource( PxMixer *mixer, int i );
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer );
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume );
+
+/*
+ Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer );
+PxBalance Px_GetOutputBalance( PxMixer *mixer );
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance );
+
+/*
+ Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer );
+PxVolume Px_GetPlaythrough( PxMixer *mixer );
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PORT_AUDIO_H */
Added: freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,2 @@
+/px_mac.c/1.2/Tue Jun 15 07:59:35 2004//
+D
Added: freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/px_mac
Added: freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/px_mac/px_mac.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac/px_mac.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,406 @@
+/*
+ * PortMixer
+ * Mac OS 9 implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "portaudio.h"
+#include "pa_host.h"
+#include "portmixer.h"
+
+#define PA_MAX_NUM_HOST_BUFFERS (16) /* Do not exceed!! */
+
+typedef struct MultiBuffer
+{
+ char *buffers[PA_MAX_NUM_HOST_BUFFERS];
+ int numBuffers;
+ int nextWrite;
+ int nextRead;
+}
+MultiBuffer;
+
+/* Define structure to contain all Macintosh specific data. */
+typedef struct PaHostSoundControl
+{
+ UInt64 pahsc_EntryCount;
+ double pahsc_InverseMicrosPerHostBuffer; /* 1/Microseconds of real-time audio per user buffer. */
+
+ /* Use char instead of Boolean for atomic operation. */
+ volatile char pahsc_IsRecording; /* Recording in progress. Set by foreground. Cleared by background. */
+ volatile char pahsc_StopRecording; /* Signal sent to background. */
+ volatile char pahsc_IfInsideCallback;
+ /* Input */
+ SPB pahsc_InputParams;
+ SICompletionUPP pahsc_InputCompletionProc;
+ MultiBuffer pahsc_InputMultiBuffer;
+ int32 pahsc_BytesPerInputHostBuffer;
+ int32 pahsc_InputRefNum;
+ /* Output */
+ CmpSoundHeader pahsc_SoundHeaders[PA_MAX_NUM_HOST_BUFFERS];
+ int32 pahsc_BytesPerOutputHostBuffer;
+ SndChannelPtr pahsc_Channel;
+ SndCallBackUPP pahsc_OutputCompletionProc;
+ int32 pahsc_NumOutsQueued;
+ int32 pahsc_NumOutsPlayed;
+ PaTimestamp pahsc_NumFramesDone;
+ UInt64 pahsc_WhenFramesDoneIncremented;
+ /* Init Time -------------- */
+ int32 pahsc_NumHostBuffers;
+ int32 pahsc_FramesPerHostBuffer;
+ int32 pahsc_UserBuffersPerHostBuffer;
+ int32 pahsc_MinFramesPerHostBuffer; /* Can vary depending on virtual memory usage. */
+}
+PaHostSoundControl;
+
+typedef struct PxSource
+{
+ char name[256];
+} PxSource;
+
+typedef struct PxInfo
+{
+ SPB *input;
+ int32 inputRefNum;
+ SndChannelPtr output;
+ int32 numSources;
+ PxSource *sources;
+} PxInfo;
+
+int Px_GetNumMixers( void *pa_stream )
+{
+ return 0;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+ return "Mac Sound Manager";
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+ PxInfo *info;
+ internalPortAudioStream *past;
+ PaHostSoundControl *macInfo;
+ OSErr err;
+ int i, j;
+ Handle h;
+ unsigned char *data;
+
+ info = (PxInfo *)malloc(sizeof(PxInfo));
+ past = (internalPortAudioStream *) pa_stream;
+ macInfo = (PaHostSoundControl *) past->past_DeviceData;
+
+ info->input = &macInfo->pahsc_InputParams;
+ info->inputRefNum = macInfo->pahsc_InputRefNum;
+ info->output = macInfo->pahsc_Channel;
+
+ info->numSources = 0;
+ info->sources = NULL;
+
+ err = SPBGetDeviceInfo (info->inputRefNum, siInputSourceNames, &h);
+ if (err)
+ return (PxMixer *)info;
+
+ HLock(h);
+ HNoPurge(h);
+
+ data = (unsigned char *)*h;
+ info->numSources = ((short *)data)[0];
+ if (info->numSources <= 0 || info->numSources > 50) {
+ HUnlock(h);
+ return (PxMixer *)info;
+ }
+
+ info->sources = (PxSource *)malloc(info->numSources * sizeof(PxSource));
+ data += 2;
+ for(i=0; i<info->numSources; i++) {
+ int len = *data++;
+
+ if (len > 63) {
+ info->numSources = 0;
+ free(info->sources);
+ info->sources = NULL;
+ HUnlock(h);
+ return (PxMixer *)info;
+ }
+
+ for(j=0; j<len; j++)
+ info->sources[i].name[j] = *data++;
+
+ info->sources[i].name[len] = 0;
+ }
+ HUnlock(h);
+
+ return (PxMixer *)info;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ if (info->sources)
+ free(info->sources);
+ free(info);
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0.0;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ PCM output volume
+*/
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer )
+{
+ return 1 ;
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSErr err;
+ long packedVol;
+ SndCommand cmd;
+
+ cmd.cmd = getVolumeCmd;
+ cmd.param1 = 0;
+ cmd.param2 = (long)&packedVol;
+
+ err = SndDoImmediate(info->output, &cmd);
+ if (err)
+ return 0.0;
+
+ return ((packedVol & 0xFFFF) + ((packedVol & 0xFFFF0000) >> 16) / 2.0) / 256.0;
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSErr err;
+ long packedVol;
+ SndCommand cmd;
+
+ packedVol = (unsigned long)volume * 256.0;
+ packedVol += (packedVol << 16);
+
+ cmd.cmd = volumeCmd;
+ cmd.param1 = 0;
+ cmd.param2 = packedVol;
+ err = SndDoImmediate(info->output, &cmd);
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return NULL;
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return NULL;
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return info->numSources;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ if (i >= 0 && i < info->numSources)
+ return info->sources[i].name;
+ else
+ return "";
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ short selected;
+ OSErr err;
+
+ err = SPBGetDeviceInfo (info->inputRefNum, siInputSource, &selected);
+ if (err)
+ return 0;
+
+ return selected - 1;
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ short selected = i+1;
+ OSErr err;
+
+ err = SPBSetDeviceInfo (info->inputRefNum, siInputSource, &selected);
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ Fixed fixedGain;
+ PxVolume vol;
+ OSErr err;
+
+ if (info->input) {
+ err = SPBGetDeviceInfo(info->inputRefNum, siInputGain, (Ptr)&fixedGain);
+ if (err)
+ return 0.0;
+
+ vol = (fixedGain / 65536.0) - 0.5;
+ return vol;
+ }
+
+ return 0.0;
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ Fixed fixedGain;
+ OSErr err;
+
+ if (info->input) {
+ fixedGain = (Fixed)((volume + 0.5) * 65536.0);
+ err = SPBSetDeviceInfo(info->inputRefNum, siInputGain, (Ptr)&fixedGain);
+ }
+}
+
+/*
+ Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+ Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return (info->input != NULL);
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSErr err;
+ short level;
+
+ err = SPBGetDeviceInfo(info->inputRefNum, siPlayThruOnOff, (Ptr)&level);
+ if (err)
+ return 0.0;
+
+ if (level < 0)
+ level = 0;
+ if (level > 7)
+ level = 7;
+
+ return (PxVolume)(level / 7.0);
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSErr err;
+ short level = (int)(volume * 7.0 + 0.5);
+
+ err = SPBSetDeviceInfo(info->inputRefNum, siPlayThruOnOff, (Ptr)&level);
+}
Added: freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,3 @@
+/Makefile/1.3/Sat Jun 10 21:39:08 2006//
+/px_mac_core.c/1.8/Sat Aug 26 06:45:54 2006//
+D
Added: freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/px_mac_core
Added: freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac_core/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/px_mac_core/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac_core/Makefile Fri Aug 24 13:53:53 2007
@@ -0,0 +1,25 @@
+# Make PortMixer Library for Mac OS X / CoreAudio
+
+CC = cc
+CFLAGS = -g -I../px_common
+PA = ../../portaudio$(PA_VER)
+
+ifeq ($(PA_VER),-v19)
+CFLAGS += -I$(PA)/include -I$(PA)/src/common -I$(PA)/src/hostapi/coreaudio
+else
+CFLAGS += -I$(PA)/pa_common
+endif
+
+PASRC = px_mac_core.c
+PAINC = ../px_common/portmixer.h
+PAOBJ = px_mac_core.o
+
+portmixer.a: $(PAOBJ)
+ ar ruv portmixer.a $(PAOBJ)
+ ranlib portmixer.a
+
+clean:
+ rm -f portmixer.a *.o
+
+%.o: %.c $(PAINC) Makefile
+ $(CC) -c $(CFLAGS) $< -o $@
Added: freeswitch/branches/cseket/libs/portmixer/px_mac_core/px_mac_core.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_mac_core/px_mac_core.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,528 @@
+/*
+ * PortMixer
+ * Mac OS X / CoreAudio implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/CoreAudio.h>
+#include <AudioToolbox/AudioConverter.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "portaudio.h"
+#include "portmixer.h"
+
+#if defined(PaStream)
+#define PA_V18
+#include "pa_host.h"
+#else
+#define PA_V19
+#include "pa_mac_core_internal.h"
+#endif
+
+typedef enum PaDeviceMode
+{
+ PA_MODE_OUTPUT_ONLY,
+ PA_MODE_INPUT_ONLY,
+ PA_MODE_IO_ONE_DEVICE,
+ PA_MODE_IO_TWO_DEVICES
+} PaDeviceMode;
+
+typedef struct PaHostInOut_s
+{
+ AudioDeviceID audioDeviceID; /* CoreAudio specific ID */
+ int bytesPerUserNativeBuffer; /* User buffer size in native host format. Depends on numChannels. */
+ AudioConverterRef converter;
+ void *converterBuffer;
+ int numChannels;
+} PaHostInOut;
+
+/**************************************************************
+ * Structure for internal host specific stream data.
+ * This is allocated on a per stream basis.
+ */
+typedef struct PaHostSoundControl
+{
+ PaHostInOut input;
+ PaHostInOut output;
+ AudioDeviceID primaryDeviceID;
+} PaHostSoundControl;
+
+// define value of isInput passed to CoreAudio routines
+#define IS_INPUT (true)
+#define IS_OUTPUT (false)
+
+typedef struct PxInfo
+{
+ AudioDeviceID input;
+ AudioDeviceID output;
+ UInt32 *srcids;
+ char **srcnames;
+ int numsrcs;
+} PxInfo;
+
+static PxInfo *Px_FreeInfo( PxInfo *info )
+{
+ int i;
+
+ if (info) {
+ if (info->srcids) {
+ free(info->srcids);
+ }
+
+ if (info->srcnames) {
+ for (i = 0; i < info->numsrcs; i++) {
+ if (info->srcnames[i]) {
+ free(info->srcnames[i]);
+ }
+ }
+ free(info->srcnames);
+ }
+ free(info);
+ }
+
+ return NULL;
+}
+
+int Px_GetNumMixers( void *pa_stream )
+{
+ return 1;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+ return "CoreAudio";
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+ PxInfo *info;
+ PaHostSoundControl *macInfo;
+ OSStatus err;
+ UInt32 outSize;
+ UInt32 inID;
+ int i;
+
+ info = (PxInfo *)calloc(1, sizeof(PxInfo));
+ if (!info) {
+ return (PxMixer *)info;
+ }
+
+#if defined(PA_V18)
+ internalPortAudioStream *past;
+
+ past = (internalPortAudioStream *) pa_stream;
+ macInfo = (PaHostSoundControl *) past->past_DeviceData;
+
+ info->input = macInfo->input.audioDeviceID;
+ info->output = macInfo->output.audioDeviceID;
+#endif
+
+#if defined(PA_V19)
+ PaMacCoreStream *pamcs;
+
+ pamcs = (PaMacCoreStream *) pa_stream;
+
+ info->input = pamcs->inputDevice;
+ info->output = pamcs->outputDevice;
+#endif
+
+ if (info->input == kAudioDeviceUnknown) {
+ outSize = sizeof(AudioDeviceID);
+ err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+ &outSize,
+ &info->input);
+ if (err) {
+ return Px_FreeInfo(info);
+ }
+ }
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetPropertyInfo(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSources,
+ &outSize,
+ NULL);
+ if (err) {
+ return Px_FreeInfo(info);
+ }
+
+ info->numsrcs = outSize / sizeof(UInt32);
+ info->srcids = (UInt32 *)malloc(outSize);
+ info->srcnames = (char **)calloc(info->numsrcs, sizeof(char *));
+
+ if (info->srcids == NULL || info->srcnames == NULL) {
+ return Px_FreeInfo(info);
+ }
+
+ err = AudioDeviceGetProperty(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSources,
+ &outSize,
+ info->srcids);
+ if (err) {
+ return Px_FreeInfo(info);
+ }
+
+ for (i = 0; i < info->numsrcs; i++) {
+ AudioValueTranslation trans;
+ CFStringRef name;
+ Boolean ok;
+
+ trans.mInputData = &info->srcids[i];
+ trans.mInputDataSize = sizeof(UInt32);
+ trans.mOutputData = &name;
+ trans.mOutputDataSize = sizeof(CFStringRef);
+
+ outSize = sizeof(AudioValueTranslation);
+ err = AudioDeviceGetProperty(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSourceNameForIDCFString,
+ &outSize,
+ &trans);
+ if (err) {
+ return Px_FreeInfo(info);
+ }
+
+ info->srcnames[i] = malloc(CFStringGetLength(name)+1);
+ if (info->srcnames[i] == NULL) {
+ return Px_FreeInfo(info);
+ }
+
+ ok = CFStringGetCString(name,
+ info->srcnames[i],
+ CFStringGetLength(name)+1,
+ kCFStringEncodingISOLatin1);
+ if (!ok) {
+ return Px_FreeInfo(info);
+ }
+ }
+
+ return (PxMixer *)info;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ Px_FreeInfo(info);
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0.0;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ PCM output volume
+*/
+
+static PxVolume Px_GetVolume(AudioDeviceID device, Boolean isInput)
+{
+ OSStatus err;
+ UInt32 outSize;
+ Float32 vol, maxvol=0.0;
+ UInt32 mute, anymuted=0;
+ int ch;
+ PxVolume max;
+
+ for(ch=0; ch<=2; ch++) {
+ outSize = sizeof(Float32);
+ err = AudioDeviceGetProperty(device, ch, isInput,
+ kAudioDevicePropertyVolumeScalar,
+ &outSize, &vol);
+ if (!err) {
+ if (vol > maxvol)
+ maxvol = vol;
+ }
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetProperty(device, ch, isInput,
+ kAudioDevicePropertyMute,
+ &outSize, &mute);
+
+ if (!err) {
+ if (mute)
+ anymuted = 1;
+ }
+ }
+
+ if (anymuted)
+ maxvol = 0.0;
+
+ return maxvol;
+}
+
+static void Px_SetVolume(AudioDeviceID device, Boolean isInput,
+ PxVolume volume)
+{
+ Float32 vol = volume;
+ UInt32 mute = 0;
+ int ch;
+ OSStatus err;
+
+ /* Implement a passive attitude towards muting. If they
+ drag the volume above 0.05, unmute it. But if they
+ drag the volume down below that, just set the volume,
+ don't actually mute.
+ */
+
+ for(ch=0; ch<=2; ch++) {
+ err = AudioDeviceSetProperty(device, 0, ch, isInput,
+ kAudioDevicePropertyVolumeScalar,
+ sizeof(Float32), &vol);
+ if (vol > 0.05) {
+ err = AudioDeviceSetProperty(device, 0, ch, isInput,
+ kAudioDevicePropertyMute,
+ sizeof(UInt32), &mute);
+ }
+ }
+}
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer )
+{
+ return 1 ;
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return Px_GetVolume(info->output, IS_OUTPUT);
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ Px_SetVolume(info->output, IS_OUTPUT, volume);
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 1;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+ if (i == 0)
+ return "PCM";
+ else
+ return "";
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+ return Px_GetPCMOutputVolume(mixer);
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+ Px_SetPCMOutputVolume(mixer, volume);
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSStatus err;
+ UInt32 outSize;
+
+ return info->numsrcs;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ if (i >= info->numsrcs)
+ return "";
+
+ return info->srcnames[i];
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSStatus err;
+ UInt32 outSize;
+ UInt32 outID = 0;
+ int i;
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetProperty(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSource,
+ &outSize,
+ &outID);
+
+ if (!err) {
+ for (i = 0; i < info->numsrcs; i++) {
+ if (info->srcids[i] == outID) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSStatus err;
+
+ if (i >= info->numsrcs) {
+ return;
+ }
+
+ err = AudioDeviceSetProperty(info->input,
+ 0,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSource,
+ sizeof(UInt32),
+ &info->srcids[i]);
+
+ return;
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return Px_GetVolume(info->input, IS_INPUT);
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ Px_SetVolume(info->input, IS_INPUT, volume);
+}
+
+/*
+ Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+ Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+ return 1;
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ OSStatus err;
+ UInt32 outSize;
+ UInt32 flag;
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetProperty(info->output, 0, IS_OUTPUT,
+ kAudioDevicePropertyPlayThru,
+ &outSize, &flag);
+ if (err)
+ return 0.0;
+
+ if (flag)
+ return 1.0;
+ else
+ return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ UInt32 flag = (volume > 0.01);
+ OSStatus err;
+
+ err = AudioDeviceSetProperty(info->output, 0, 0, IS_OUTPUT,
+ kAudioDevicePropertyPlayThru,
+ sizeof(UInt32), &flag);
+}
+
Added: freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,3 @@
+/Makefile/1.1.1.1/Mon Dec 2 01:14:03 2002//
+/px_none.c/1.1.1.1/Mon Dec 2 01:14:03 2002//
+D
Added: freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/px_none
Added: freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_none/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/px_none/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_none/Makefile Fri Aug 24 13:53:53 2007
@@ -0,0 +1,18 @@
+# Make PortMixer Library for Mac OS X / CoreMixer
+
+CC = cc
+
+CFLAGS = -g -I../px_common -I../../portaudio/pa_common
+PASRC = px_none.c
+PAINC = ../px_common/portmixer.h
+PAOBJ = px_none.o
+
+portmixer.a: $(PAOBJ)
+ ar ruv portmixer.a $(PAOBJ)
+ ranlib portmixer.a
+
+clean:
+ rm -f portmixer.a *.o
+
+%.o: %.c $(PAINC) Makefile
+ $(CC) -c $(CFLAGS) $< -o $@
Added: freeswitch/branches/cseket/libs/portmixer/px_none/px_none.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_none/px_none.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,216 @@
+/*
+ * PortMixer
+ * Empty implementation (as a placeholder on platforms where
+ * it hasn't been implemented yet)
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <stdlib.h>
+
+#include "portaudio.h"
+#include "portmixer.h"
+
+typedef struct PxInfo
+{
+ int dummy;
+} PxInfo;
+
+int Px_GetNumMixers( void *pa_stream )
+{
+ return 0;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+ return NULL;
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+ return NULL;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0.0;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ PCM output volume
+*/
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0.0;
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return NULL;
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return NULL;
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return NULL;
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return -1; /* none */
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 0.0;
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+ Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxBalance Px_GetPlaythrough( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxBalance balance )
+{
+}
+
Added: freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,3 @@
+/Makefile/1.2/Sun Mar 9 04:04:53 2003//
+/px_test.c/1.2/Sun Mar 9 04:04:53 2003//
+D
Added: freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/px_tests
Added: freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_tests/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/px_tests/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_tests/Makefile Fri Aug 24 13:53:53 2007
@@ -0,0 +1,16 @@
+all: px_test
+
+CFLAGS = -g -Wall -O -I../../portaudio/pa_common -I../px_common
+
+px_test: px_test.o px_unix_oss.o ../px_common/portmixer.h
+ gcc -g -o px_test px_test.o px_unix_oss.o -lm \
+ -L../../portaudio/pa_unix_oss -lportaudio -lpthread
+
+px_test.o: px_test.c ../px_common/portmixer.h
+ gcc $(CFLAGS) -c px_test.c
+
+
+px_unix_oss.o: ../px_unix_oss/px_unix_oss.c ../px_common/portmixer.h
+ gcc $(CFLAGS) -c ../px_unix_oss/px_unix_oss.c
+
+
Added: freeswitch/branches/cseket/libs/portmixer/px_tests/px_test.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_tests/px_test.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,80 @@
+#include <stdio.h>
+
+#include "portmixer.h"
+#include "portaudio.h"
+
+static int DummyCallbackFunc(void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer,
+ PaTimestamp outTime, void *userData)
+{
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int num_mixers;
+ int i;
+ PaError error;
+ PortAudioStream *stream;
+ int recDeviceNum;
+ int playDeviceNum;
+ int inputChannels = 2;
+
+ recDeviceNum = Pa_GetDefaultInputDeviceID();
+ playDeviceNum = Pa_GetDefaultOutputDeviceID();
+
+ error = Pa_OpenStream(&stream, recDeviceNum, inputChannels, paFloat32, NULL,
+ paNoDevice, 0, paFloat32, NULL,
+ 44101, 512, 1, paClipOff | paDitherOff,
+ DummyCallbackFunc, NULL);
+
+ if (error) {
+ printf("PortAudio error %d: %s\n", error,
+ Pa_GetErrorText(error));
+ return -1;
+ }
+
+ num_mixers = Px_GetNumMixers(stream);
+ printf("Number of mixers: %d\n", num_mixers);
+ for(i=0; i<num_mixers; i++) {
+ PxMixer *mixer;
+ int num;
+ int j;
+
+ printf("Mixer %d: %s\n", i, Px_GetMixerName(stream, i));
+ mixer = Px_OpenMixer(stream, i);
+ if (!mixer) {
+ printf(" Could not open mixer!\n");
+ continue;
+ }
+
+ printf(" Master volume: %.2f\n", Px_GetMasterVolume(mixer));
+ printf(" PCM output volume: %.2f\n", Px_GetPCMOutputVolume(mixer));
+
+ num = Px_GetNumOutputVolumes(mixer);
+ printf(" Num outputs: %d\n", num);
+ for(j=0; j<num; j++) {
+ printf(" Output %d (%s): %.2f\n",
+ j,
+ Px_GetOutputVolumeName(mixer, j),
+ Px_GetOutputVolume(mixer, j));
+ }
+
+ num = Px_GetNumInputSources(mixer);
+ printf(" Num input sources: %d\n", num);
+ for(j=0; j<num; j++) {
+ printf(" Input %d (%s) %s\n",
+ j,
+ Px_GetInputSourceName(mixer, j),
+ (Px_GetCurrentInputSource(mixer)==j?
+ "SELECTED": ""));
+ }
+ printf(" Input volume: %.2f\n", Px_GetInputVolume(mixer));
+
+ Px_CloseMixer(mixer);
+ }
+
+ Pa_CloseStream(stream);
+
+ return 0;
+}
Added: freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,3 @@
+/Makefile/1.1/Mon Dec 2 06:22:32 2002//
+/px_unix_oss.c/1.5/Fri Dec 2 10:23:45 2005//
+D
Added: freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/px_unix_oss
Added: freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_unix_oss/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/px_unix_oss/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_unix_oss/Makefile Fri Aug 24 13:53:53 2007
@@ -0,0 +1,18 @@
+# Make PortMixer Library for Unix / OSS
+
+CC = gcc
+
+CFLAGS = -g -I../px_common -I../../portaudio/pa_common
+PASRC = px_unix_oss.c
+PAINC = ../px_common/portmixer.h
+PAOBJ = px_unix_oss.o
+
+portmixer.a: $(PAOBJ)
+ ar ruv portmixer.a $(PAOBJ)
+ ranlib portmixer.a
+
+clean:
+ rm -f portmixer.a *.o
+
+%.o: %.c $(PAINC) Makefile
+ $(CC) -c $(CFLAGS) $< -o $@
Added: freeswitch/branches/cseket/libs/portmixer/px_unix_oss/px_unix_oss.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_unix_oss/px_unix_oss.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,385 @@
+/*
+ * PortMixer
+ * Unix OSS Implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#if defined(__linux__)
+#include <linux/soundcard.h>
+#elif defined(__FreeBSD__)
+#include <sys/soundcard.h>
+#else
+#include <machine/soundcard.h> /* JH20010905 */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include "portaudio.h"
+#include "portmixer.h"
+
+typedef struct PxInfo
+{
+ int index;
+ int fd;
+
+ int num_out;
+ int outs[SOUND_MIXER_NRDEVICES];
+ int num_rec;
+ int recs[SOUND_MIXER_NRDEVICES];
+} PxInfo;
+
+char PxDevice[20] = "/dev/mixerX";
+
+int PxNumDevices = 0;
+int PxDevices[10];
+
+int Px_GetNumMixers( void *pa_stream )
+{
+ int i;
+ int fd;
+
+ PxNumDevices = 0;
+
+ for(i=0; i<11; i++) {
+ if (i==0)
+ PxDevice[10] = 0;
+ else
+ PxDevice[10] = '0'+(i-1);
+ fd = open(PxDevice, O_RDWR);
+ if (fd >= 0) {
+ PxDevices[PxNumDevices] = i;
+ PxNumDevices++;
+ close(fd);
+ }
+ }
+
+ return PxNumDevices;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+ if (PxNumDevices <= 0)
+ Px_GetNumMixers(pa_stream);
+
+ if (index < 0 || index >= PxNumDevices)
+ return NULL;
+
+ if (PxDevices[index]==0)
+ PxDevice[10] = 0;
+ else
+ PxDevice[10] = '0'+(PxDevices[index]-1);
+ return PxDevice;
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+ PxInfo *info;
+ int devmask, recmask, outmask;
+ int i;
+
+ if (PxNumDevices <= 0)
+ Px_GetNumMixers(pa_stream);
+
+ if (index < 0 || index >= PxNumDevices)
+ return NULL;
+
+ info = (PxInfo *)malloc(sizeof(PxInfo));
+ info->index = PxDevice[index];
+
+ if (PxDevices[index]==0)
+ PxDevice[10] = 0;
+ else
+ PxDevice[10] = '0'+(PxDevices[index]-1);
+ info->fd = open(PxDevice, O_RDWR);
+ if (info->fd < 0)
+ goto bad;
+
+ if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_DEVMASK),
+ &devmask) == -1)
+ goto bad;
+ if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_RECMASK),
+ &recmask) == -1)
+ goto bad;
+ outmask = devmask ^ recmask;
+
+ info->num_out = 0;
+ info->num_rec = 0;
+
+ for(i=0; i<SOUND_MIXER_NRDEVICES; i++)
+ if (recmask & (1<<i))
+ info->recs[info->num_rec++] = i;
+ else if (devmask & (1<<i))
+ info->outs[info->num_out++] = i;
+
+ return (PxMixer *)info;
+
+ bad:
+ free(info);
+ return NULL;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ close(info->fd);
+
+ free(info);
+}
+
+PxVolume GetVolume(int fd, int channel)
+{
+ int vol;
+ int stereo;
+
+ if (ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == 0)
+ stereo = ((stereo & (1 << channel)) != 0);
+ else
+ stereo = 0;
+
+ if (ioctl(fd, MIXER_READ(channel), &vol) == -1)
+ return 0.0;
+
+ if (stereo)
+ return ((vol & 0xFF)/200.0) + (((vol>>8) & 0xFF)/200.0);
+ else
+ return (vol & 0xFF)/100.0;
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return GetVolume(info->fd, SOUND_MIXER_VOLUME);
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ int vol = (int)((volume * 100.0) + 0.5);
+ vol = (vol | (vol<<8));
+ ioctl(info->fd, MIXER_WRITE(SOUND_MIXER_VOLUME), &vol);
+}
+
+/*
+ PCM output volume
+*/
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer )
+{
+ return 1 ;
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return GetVolume(info->fd, SOUND_MIXER_PCM);
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ int vol = (int)((volume * 100.0) + 0.5);
+ vol = (vol | (vol<<8));
+ ioctl(info->fd, MIXER_WRITE(SOUND_MIXER_PCM), &vol);
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return info->num_out;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ const char *labels[] = SOUND_DEVICE_LABELS;
+
+ return labels[info->outs[i]];
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return GetVolume(info->fd, info->outs[i]);
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ int vol = (int)((volume * 100.0) + 0.5);
+ vol = (vol | (vol<<8));
+ ioctl(info->fd, MIXER_WRITE(info->outs[i]), &vol);
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return info->num_rec;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ const char *labels[] = SOUND_DEVICE_LABELS;
+ return labels[info->recs[i]];
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ int recmask;
+ int i;
+
+ /* Note that there may be more than one in OSS; we pick
+ the first one */
+
+ if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_RECSRC),
+ &recmask) == -1)
+ return -1; /* none / error */
+
+ for(i=0; i<info->num_rec; i++)
+ if (recmask & (1 << (info->recs[i])))
+ return i;
+
+ return -1; /* none */
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ int newrecsrcmask = (1 << (info->recs[i]));
+
+ ioctl(info->fd, MIXER_WRITE(SOUND_MIXER_READ_RECSRC),
+ &newrecsrcmask);
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ int i;
+
+ i = Px_GetCurrentInputSource(mixer);
+ if (i < 0)
+ return 0.0;
+
+ return GetVolume(info->fd, info->recs[i]);
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ int vol;
+ int i;
+
+ i = Px_GetCurrentInputSource(mixer);
+ if (i < 0)
+ return;
+
+ vol = (int)((volume * 100.0) + 0.5);
+ vol = (vol | (vol<<8));
+ ioctl(info->fd, MIXER_WRITE(info->recs[i]), &vol);
+}
+
+/*
+ Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+ Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+}
+
Added: freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,3 @@
+/Makefile/1.1/Mon Sep 22 09:01:06 2003//
+/px_win_wmme.c/1.8/Sat Jun 10 21:39:08 2006//
+D
Added: freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/px_win_wmme
Added: freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_win_wmme/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/px_win_wmme/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_win_wmme/Makefile Fri Aug 24 13:53:53 2007
@@ -0,0 +1,18 @@
+# Make PortMixer Library for Windows / Cygwin
+
+CC = gcc
+
+override CFLAGS = -g -I../px_common -I../../portaudio/pa_common
+PASRC = px_win_wmme.c
+PAINC = ../px_common/portmixer.h
+PAOBJ = px_win_wmme.o
+
+portmixer.a: $(PAOBJ)
+ ar ruv portmixer.a $(PAOBJ)
+ ranlib portmixer.a
+
+clean:
+ rm -f portmixer.a *.o
+
+%.o: %.c $(PAINC) Makefile
+ $(CC) -c $(CFLAGS) $< -o $@
Added: freeswitch/branches/cseket/libs/portmixer/px_win_wmme/px_win_wmme.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/px_win_wmme/px_win_wmme.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,622 @@
+/*
+ * PortMixer
+ * Windows WMME Implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni and Augustus Saunders
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <Windows.h>
+
+#include "portaudio.h"
+#include "portmixer.h"
+
+#if defined(PaStream)
+#define PA_V18
+#else
+#define PA_V19
+#endif
+
+#if defined(PA_V18)
+#include "pa_host.h"
+
+typedef struct PaWMMEStreamData
+{
+ /* Input -------------- */
+ HWAVEIN hWaveIn;
+ WAVEHDR *inputBuffers;
+ int currentInputBuffer;
+ int bytesPerHostInputBuffer;
+ int bytesPerUserInputBuffer; /* native buffer size in bytes */
+ /* Output -------------- */
+ HWAVEOUT hWaveOut;
+} PaWMMEStreamData;
+#endif
+
+#if defined(PA_V19)
+#include "pa_cpuload.h"
+#include "pa_process.h"
+#include "pa_stream.h"
+
+typedef struct
+{
+ HANDLE bufferEvent;
+ void *waveHandles;
+ unsigned int deviceCount;
+ /* unsigned int channelCount; */
+ WAVEHDR **waveHeaders; /* waveHeaders[device][buffer] */
+ unsigned int bufferCount;
+ unsigned int currentBufferIndex;
+ unsigned int framesPerBuffer;
+ unsigned int framesUsedInCurrentBuffer;
+}PaWinMmeSingleDirectionHandlesAndBuffers;
+
+/* PaWinMmeStream - a stream data structure specifically for this implementation */
+/* note that struct PaWinMmeStream is typedeffed to PaWinMmeStream above. */
+struct PaWinMmeStream
+{
+ PaUtilStreamRepresentation streamRepresentation;
+ PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+ PaUtilBufferProcessor bufferProcessor;
+
+ int primeStreamUsingCallback;
+
+ PaWinMmeSingleDirectionHandlesAndBuffers input;
+ PaWinMmeSingleDirectionHandlesAndBuffers output;
+
+ /* Processing thread management -------------- */
+ HANDLE abortEvent;
+ HANDLE processingThread;
+ DWORD processingThreadId;
+
+ char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */
+ int processingThreadPriority;
+ int highThreadPriority;
+ int throttledThreadPriority;
+ unsigned long throttledSleepMsecs;
+
+ int isStopped;
+ volatile int isActive;
+ volatile int stopProcessing; /* stop thread once existing buffers have been returned */
+ volatile int abortProcessing; /* stop thread immediately */
+
+ DWORD allBuffersDurationMs; /* used to calculate timeouts */
+};
+#endif
+
+typedef struct PxSrcInfo
+{
+ char name[256];
+ DWORD lineID;
+ DWORD controlID;
+} PxSrcInfo;
+
+typedef struct PxInfo
+{
+ HMIXEROBJ hInputMixer;
+ HMIXEROBJ hOutputMixer;
+ int numInputs;
+ PxSrcInfo src[32];
+ DWORD muxID;
+ DWORD speakerID;
+ DWORD waveID;
+} PxInfo;
+
+int Px_GetNumMixers( void *pa_stream )
+{
+ return 1;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+ return "Mixer";
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+#if defined(PA_V18)
+ internalPortAudioStream *past;
+ PaWMMEStreamData *wmmeStreamData;
+#endif
+
+#if defined(PA_V19)
+ struct PaWinMmeStream *past;
+#endif
+
+ HWAVEIN hWaveIn;
+ HWAVEOUT hWaveOut;
+ PxInfo *mixer;
+ MMRESULT result;
+ MIXERLINE line;
+ MIXERLINECONTROLS controls;
+ MIXERCONTROL control;
+ MIXERCONTROLDETAILS details;
+ MIXERCONTROLDETAILS_LISTTEXT mixList[32];
+ int j;
+
+ if (!pa_stream)
+ return NULL;
+
+ mixer = (PxMixer *)malloc(sizeof(PxInfo));
+ mixer->hInputMixer = NULL;
+ mixer->hOutputMixer = NULL;
+
+#if defined(PA_V18)
+ past = (internalPortAudioStream *) pa_stream;
+ wmmeStreamData = (PaWMMEStreamData *) past->past_DeviceData;
+
+ hWaveIn = wmmeStreamData->hWaveIn;
+ hWaveOut = wmmeStreamData->hWaveOut;
+#endif
+
+#if defined(PA_V19)
+ past = (struct PaWinMmeStream *) pa_stream;
+
+ hWaveIn = 0;
+ if (past->input.waveHandles) {
+ hWaveIn = ((HWAVEIN *)past->input.waveHandles)[0];
+ }
+
+ hWaveOut = 0;
+ if (past->output.waveHandles) {
+ hWaveOut = ((HWAVEOUT *)past->output.waveHandles)[0];
+ }
+#endif
+
+ if (hWaveIn) {
+ result = mixerOpen((HMIXER *)&mixer->hInputMixer, (UINT)hWaveIn, 0, 0, MIXER_OBJECTF_HWAVEIN);
+ if (result != MMSYSERR_NOERROR) {
+ free(mixer);
+ return NULL;
+ }
+ }
+
+ if (hWaveOut) {
+ result = mixerOpen((HMIXER *)&mixer->hOutputMixer, (UINT)hWaveOut, 0, 0, MIXER_OBJECTF_HWAVEOUT);
+ if (result != MMSYSERR_NOERROR) {
+ free(mixer);
+ return NULL;
+ }
+ }
+
+ mixer->numInputs = 0;
+ mixer->muxID = 0;
+
+ /* ??? win32 default for wave control seems to be 0 ??? */
+ mixer->waveID = 0 ;
+
+ /*
+ * Find the input source selector (mux or mixer) and
+ * get the names and IDs of all of the input sources
+ */
+
+ if (mixer->hInputMixer) {
+ line.cbStruct = sizeof(MIXERLINE);
+ line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
+ result = mixerGetLineInfo(mixer->hInputMixer,
+ &line,
+ MIXER_GETLINEINFOF_COMPONENTTYPE);
+ if (result == MMSYSERR_NOERROR) {
+
+ controls.cbStruct = sizeof(MIXERLINECONTROLS);
+ controls.dwLineID = line.dwLineID;
+ controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX;
+ controls.cbmxctrl = sizeof(MIXERCONTROL);
+ controls.pamxctrl = &control;
+
+ control.cbStruct = sizeof(MIXERCONTROL);
+
+ result = mixerGetLineControls(mixer->hInputMixer,
+ &controls,
+ MIXER_GETLINECONTROLSF_ONEBYTYPE);
+
+ if (result != MMSYSERR_NOERROR) {
+ controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER;
+ result = mixerGetLineControls(mixer->hInputMixer,
+ &controls,
+ MIXER_GETLINECONTROLSF_ONEBYTYPE);
+ }
+
+ if (result == MMSYSERR_NOERROR) {
+ mixer->numInputs = control.cMultipleItems;
+ mixer->muxID = control.dwControlID;
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = mixer->muxID;
+ details.cChannels = 1;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
+ details.paDetails = (LPMIXERCONTROLDETAILS_LISTTEXT)&mixList[0];
+ details.cMultipleItems = mixer->numInputs;
+
+ result = mixerGetControlDetails(mixer->hInputMixer,
+ (LPMIXERCONTROLDETAILS)&details,
+ MIXER_GETCONTROLDETAILSF_LISTTEXT);
+
+ if (result != MMSYSERR_NOERROR)
+ mixer->numInputs = 0;
+
+ for(j=0; j<mixer->numInputs; j++) {
+ mixer->src[j].lineID = mixList[j].dwParam1;
+ strcpy(mixer->src[j].name, mixList[j].szName);
+ }
+ }
+
+ /*
+ * We've found the names - now we need to find the volume
+ * controls for each one
+ */
+
+ for(j=0; j<mixer->numInputs; j++) {
+ controls.cbStruct = sizeof(MIXERLINECONTROLS);
+ controls.dwLineID = mixer->src[j].lineID;
+ controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
+ controls.cbmxctrl = sizeof(MIXERCONTROL);
+ controls.pamxctrl = &control;
+
+ control.cbStruct = sizeof(MIXERCONTROL);
+
+ result = mixerGetLineControls(mixer->hInputMixer,
+ &controls,
+ MIXER_GETLINECONTROLSF_ONEBYTYPE);
+ if (result == MMSYSERR_NOERROR)
+ mixer->src[j].controlID = control.dwControlID;
+ else
+ mixer->src[j].controlID = 0;
+ }
+ }
+ }
+
+ /*
+ * Find the ID of the output speaker volume control
+ */
+
+ mixer->speakerID = 0;
+
+ if (mixer->hOutputMixer) {
+ line.cbStruct = sizeof(MIXERLINE);
+ line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
+ result = mixerGetLineInfo(mixer->hOutputMixer,
+ &line,
+ MIXER_GETLINEINFOF_COMPONENTTYPE);
+ if (result == MMSYSERR_NOERROR) {
+ controls.cbStruct = sizeof(MIXERLINECONTROLS);
+ controls.dwLineID = line.dwLineID;
+ controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
+ controls.cbmxctrl = sizeof(MIXERCONTROL);
+ controls.pamxctrl = &control;
+
+ control.cbStruct = sizeof(MIXERCONTROL);
+
+ result = mixerGetLineControls(mixer->hOutputMixer,
+ &controls,
+ MIXER_GETLINECONTROLSF_ONEBYTYPE);
+
+ if (result == MMSYSERR_NOERROR)
+ mixer->speakerID = control.dwControlID;
+ }
+ }
+
+ return (PxMixer *)mixer;
+}
+
+void VolumeFunction(HMIXEROBJ hMixer, DWORD controlID, PxVolume *volume)
+{
+ MIXERCONTROLDETAILS details;
+ MMRESULT result;
+ MIXERCONTROLDETAILS_UNSIGNED value;
+
+ memset(&value, 0, sizeof(MIXERCONTROLDETAILS_UNSIGNED));
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = controlID;
+ details.cChannels = 1; /* all channels */
+ details.cMultipleItems = 0;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
+ details.paDetails = &value;
+
+ result = mixerGetControlDetails(hMixer, &details,
+ MIXER_GETCONTROLDETAILSF_VALUE);
+
+ if (*volume < 0.0) {
+ *volume = (PxVolume)(value.dwValue / 65535.0);
+ }
+ else {
+ if (result != MMSYSERR_NOERROR)
+ return;
+ value.dwValue = (unsigned short)(*volume * 65535.0);
+ mixerSetControlDetails(hMixer, &details,
+ MIXER_GETCONTROLDETAILSF_VALUE);
+ }
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ if (info->hInputMixer)
+ mixerClose((HMIXER)info->hInputMixer);
+ if (info->hOutputMixer)
+ mixerClose((HMIXER)info->hOutputMixer);
+ free( mixer );
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ PxVolume vol;
+
+ vol = -1.0;
+ VolumeFunction(info->hOutputMixer, info->speakerID, &vol);
+ return vol;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ VolumeFunction(info->hOutputMixer, info->speakerID, &volume);
+}
+
+/*
+ PCM output volume
+*/
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer )
+{
+ PxInfo* info = ( PxInfo* )( mixer ) ;
+ return ( info->waveID == -1 ) ? 0 : 1 ;
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+ MMRESULT result;
+ DWORD vol = 0;
+ unsigned short mono_vol = 0;
+ PxInfo *info = (PxInfo *)mixer;
+
+ /* invalid waveID, return zero */
+ if ( info->waveID == -1 )
+ return 0.0 ;
+
+ /* get the wave output volume */
+ result = waveOutGetVolume( (HWAVEOUT)( info->waveID ), &vol);
+
+ /* on failure, mark waveID as invalid and return zero */
+ if ( result != MMSYSERR_NOERROR )
+ {
+ info->waveID = -1 ;
+ return 0.0 ;
+ }
+
+ mono_vol = (unsigned short)vol;
+ return (PxVolume)mono_vol/65535.0;
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+ MMRESULT result;
+ PxInfo *info = (PxInfo *)mixer;
+
+ /* invalid waveID */
+ if ( info->waveID == -1 )
+ return ;
+
+ /* set the wave output volume */
+ result = waveOutSetVolume( (HWAVEOUT)( info->waveID ), MAKELONG(volume*0xFFFF, volume*0xFFFF));
+
+ /* on failure, mark waveID as invalid */
+ if ( result != MMSYSERR_NOERROR )
+ {
+ info->waveID = -1 ;
+ }
+
+ return ;
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return 2;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ if (i==1)
+ return "Wave Out";
+ else
+ return "Master Volume";
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ if (i==1)
+ return Px_GetPCMOutputVolume(mixer);
+ else
+ return Px_GetMasterVolume(mixer);
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ if (i==1)
+ Px_SetPCMOutputVolume(mixer, volume);
+ else
+ Px_SetMasterVolume(mixer, volume);
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return info->numInputs;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+ PxInfo *info = (PxInfo *)mixer;
+
+ return info->src[i].name;
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ MIXERCONTROLDETAILS details;
+ MIXERCONTROLDETAILS_BOOLEAN flags[32];
+ MMRESULT result;
+ int i;
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = info->muxID;
+ details.cMultipleItems = info->numInputs;
+ details.cChannels = 1;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
+ details.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&flags[0];
+
+ result = mixerGetControlDetails(info->hInputMixer,
+ (LPMIXERCONTROLDETAILS)&details,
+ MIXER_GETCONTROLDETAILSF_VALUE);
+
+ if (result == MMSYSERR_NOERROR) {
+ for(i=0; i<info->numInputs; i++)
+ if (flags[i].fValue)
+ return i;
+ }
+
+ return 0;
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ MIXERCONTROLDETAILS details;
+ MIXERCONTROLDETAILS_BOOLEAN flags[32];
+ MMRESULT result;
+ int j;
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = info->muxID;
+ details.cMultipleItems = info->numInputs;
+ details.cChannels = 1;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
+ details.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&flags[0];
+
+ for(j=0; j<info->numInputs; j++)
+ flags[j].fValue = (i == j);
+
+ result = mixerSetControlDetails(info->hInputMixer,
+ (LPMIXERCONTROLDETAILS)&details,
+ MIXER_SETCONTROLDETAILSF_VALUE);
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ PxVolume vol;
+ int src = Px_GetCurrentInputSource(mixer);
+
+ vol = -1.0;
+ VolumeFunction(info->hInputMixer, info->src[src].controlID, &vol);
+ return vol;
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+ PxInfo *info = (PxInfo *)mixer;
+ int src = Px_GetCurrentInputSource(mixer);
+
+ VolumeFunction(info->hInputMixer, info->src[src].controlID, &volume);
+}
+
+/*
+ Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+ Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+ return 0;
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+ return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+}
+
Added: freeswitch/branches/cseket/libs/portmixer/src/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,11 @@
+/px_example_api.c/1.1/Mon Oct 2 00:27:52 2006//
+/px_linux_alsa.c/1.2/Sun Jun 3 08:30:36 2007//
+/px_mac_coreaudio.c/1.1/Mon Oct 2 00:27:52 2006//
+/px_mixer.c/1.4/Wed Jul 11 06:16:16 2007//
+/px_mixer.h/1.1/Mon Oct 2 00:27:52 2006//
+/px_unix_oss.c/1.3/Sun Jun 3 09:39:32 2007//
+/px_win_common.c/1.2/Thu Oct 5 22:59:44 2006//
+/px_win_common.h/1.1/Mon Oct 2 00:27:52 2006//
+/px_win_ds.c/1.2/Sun Oct 22 05:55:10 2006//
+/px_win_wmme.c/1.2/Thu Oct 5 22:59:44 2006//
+D
Added: freeswitch/branches/cseket/libs/portmixer/src/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/src
Added: freeswitch/branches/cseket/libs/portmixer/src/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/src/px_example_api.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_example_api.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,304 @@
+/*
+ * PortMixer
+ * Example API Implementation
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+#include "portaudio.h"
+
+#include "portmixer.h"
+#include "px_mixer.h"
+
+typedef struct PxInfo
+{
+ int example;
+} PxInfo;
+
+int OpenMixer_Platform_API(px_mixer *Px, int index)
+{
+ PxInfo *info;
+
+ if (!initialize(Px)) {
+ return FALSE;
+ }
+
+ info = (PxInfo *) Px->info;
+
+ return TRUE;
+}
+
+static int initialize(px_mixer *Px)
+{
+ Px->info = calloc(1, sizeof(PxInfo));
+ if (Px->info == NULL) {
+ return FALSE;
+ }
+
+ Px->CloseMixer = close_mixer;
+ Px->GetNumMixers = get_num_mixers;
+ Px->GetMixerName = get_mixer_name;
+ Px->GetMasterVolume = get_master_volume;
+ Px->SetMasterVolume = set_master_volume;
+ Px->SupportsPCMOutputVolume = supports_pcm_output_volume;
+ Px->GetPCMOutputVolume = get_pcm_output_volume;
+ Px->SetPCMOutputVolume = set_pcm_output_volume;
+ Px->GetNumOutputVolumes = get_num_output_volumes;
+ Px->GetOutputVolumeName = get_output_volume_name;
+ Px->GetOutputVolume = get_output_volume;
+ Px->SetOutputVolume = set_output_volume;
+ Px->GetNumInputSources = get_num_input_sources;
+ Px->GetInputSourceName = get_input_source_name;
+ Px->GetCurrentInputSource = get_current_input_source;
+ Px->SetCurrentInputSource = set_current_input_source;
+ Px->GetInputVolume = get_input_volume;
+ Px->SetInputVolume = set_input_volume;
+
+ Px->SupportsOutputBalance = supports_output_balance;
+ Px->GetOutputBalance = get_output_balance;
+ Px->SetOutputBalance = set_output_balance;
+
+ Px->SupportsPlaythrough = supports_play_through;
+ Px->GetPlaythrough = get_play_through;
+ Px->SetPlaythrough = set_play_through;
+
+ return TRUE;
+}
+
+static int cleanup(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info) {
+ free(info);
+ Px->info = NULL;
+ }
+
+ return FALSE;
+}
+
+static void close_mixer(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
+
+static int get_num_mixers(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0;
+}
+
+static const char *get_mixer_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return NULL;
+}
+
+/*
+|| Master volume
+*/
+
+static PxVolume get_master_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0.0;
+}
+
+static void set_master_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
+
+/*
+|| Main output volume
+*/
+
+static int supports_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return FALSE;
+}
+
+static PxVolume get_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0.0;
+}
+
+static void set_pcm_output_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
+
+/*
+|| All output volumes
+*/
+
+static int get_num_output_volumes(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0;
+}
+
+static const char *get_output_volume_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return NULL;
+}
+
+static PxVolume get_output_volume(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0.0;
+}
+
+static void set_output_volume(px_mixer *Px, int i, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
+
+/*
+|| Input source
+*/
+
+static int get_num_input_sources(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0;
+}
+
+static const char *get_input_source_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return NULL;
+}
+
+static int get_current_input_source(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return -1;
+}
+
+static void set_current_input_source(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
+
+/*
+|| Input volume
+*/
+
+static PxVolume get_input_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0.0;
+}
+
+static void set_input_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
+
+/*
+|| Balance
+*/
+
+static int supports_output_balance(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return FALSE;
+}
+
+static PxBalance get_output_balance(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0.0;
+}
+
+static void set_output_balance(px_mixer *Px, PxBalance balance)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
+
+/*
+|| Playthrough
+*/
+
+static int supports_play_through(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return FALSE;
+}
+
+static PxVolume get_play_through(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return 0.0;
+}
+
+void set_play_through(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return;
+}
Added: freeswitch/branches/cseket/libs/portmixer/src/px_linux_alsa.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_linux_alsa.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,671 @@
+/*
+ * PortMixer
+ * Linux ALSA Implementation
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <alsa/asoundlib.h>
+
+#include "portaudio.h"
+#include "pa_unix_oss.h"
+
+#include "portmixer.h"
+#include "px_mixer.h"
+
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+
+#if !defined(TRUE)
+#define TRUE 1
+#endif
+
+typedef struct PxSelem
+{
+ snd_mixer_selem_id_t *sid;
+ snd_mixer_elem_t *elem;
+ char *name;
+} PxSelem;
+
+typedef struct PxDev
+{
+ snd_mixer_t *handle;
+ int card;
+
+ int numselems;
+ PxSelem *selems;
+} PxDev;
+
+typedef struct PxInfo
+{
+ int numMixers;
+ char *mixers;
+
+ PxDev capture;
+ PxDev playback;
+} PxInfo;
+
+static int open_mixer(PxDev *dev, int card, int playback)
+{
+ snd_mixer_elem_t *elem;
+ char name[256];
+ int err;
+ int i;
+
+ sprintf(name, "hw:%d", card);
+
+ dev->card = card;
+ dev->handle = NULL;
+
+ do {
+ err = snd_mixer_open(&dev->handle, 0);
+ if (err < 0) {
+ break;
+ }
+
+ err = snd_mixer_attach(dev->handle, name);
+ if (err < 0) {
+ break;
+ }
+
+ err = snd_mixer_selem_register(dev->handle, NULL, NULL);
+ if (err < 0) {
+ break;
+ }
+
+ err = snd_mixer_load(dev->handle);
+ if (err < 0) {
+ break;
+ }
+
+ for (elem = snd_mixer_first_elem(dev->handle);
+ elem != NULL;
+ elem = snd_mixer_elem_next(elem))
+ {
+ if (!playback) {
+ if (!snd_mixer_selem_has_capture_volume(elem) &&
+ !snd_mixer_selem_has_capture_switch(elem) &&
+ !snd_mixer_selem_has_common_volume(elem)) {
+ continue;
+ }
+ }
+ else {
+ if (!snd_mixer_selem_has_playback_volume(elem) &&
+ !snd_mixer_selem_has_playback_switch(elem) &&
+ !snd_mixer_selem_has_common_volume(elem)) {
+ continue;
+ }
+ }
+ dev->numselems++;
+ }
+
+ dev->selems = calloc(dev->numselems, sizeof(PxSelem));
+ if (dev->selems == NULL) {
+ break;
+ }
+
+ i = 0;
+ for (elem = snd_mixer_first_elem(dev->handle);
+ elem != NULL;
+ elem = snd_mixer_elem_next(elem))
+ {
+ if (!playback) {
+ if (!snd_mixer_selem_has_capture_volume(elem) &&
+ !snd_mixer_selem_has_capture_switch(elem) &&
+ !snd_mixer_selem_has_common_volume(elem)) {
+ continue;
+ }
+ }
+ else {
+ if (!snd_mixer_selem_has_playback_volume(elem) &&
+ !snd_mixer_selem_has_playback_switch(elem) &&
+ !snd_mixer_selem_has_common_volume(elem)) {
+ continue;
+ }
+ }
+
+ if (snd_mixer_selem_id_malloc(&dev->selems[i].sid) < 0) {
+ break;
+ }
+
+ snd_mixer_selem_get_id(elem, dev->selems[i].sid);
+ dev->selems[i].elem = elem;
+
+ snprintf(name,
+ sizeof(name),
+ "%s:%d",
+ snd_mixer_selem_id_get_name(dev->selems[i].sid),
+ snd_mixer_selem_id_get_index(dev->selems[i].sid));
+
+ dev->selems[i].name = strdup(name);
+ if (!dev->selems[i].name) {
+ break;
+ }
+ i++;
+ }
+
+ if (i == dev->numselems) {
+ return TRUE;
+ }
+
+ } while (FALSE);
+
+ if (dev->selems) {
+ for (i = 0; i < dev->numselems; i++) {
+ if (dev->selems[i].sid) {
+ snd_mixer_selem_id_free(dev->selems[i].sid);
+ }
+ if (dev->selems[i].name) {
+ free(dev->selems[i].name);
+ }
+ }
+ free(dev->selems);
+ dev->selems = NULL;
+ }
+
+ if (dev->handle) {
+ snd_mixer_close(dev->handle);
+ dev->handle = NULL;
+ }
+
+ return FALSE;
+}
+
+int OpenMixer_Linux_ALSA(px_mixer *Px, int index)
+{
+ PxInfo *info;
+ int card;
+
+ if (!initialize(Px)) {
+ return FALSE;
+ }
+
+ info = (PxInfo *) Px->info;
+
+ if (PaAlsa_GetStreamInputCard(Px->pa_stream, &card) == paNoError) {
+ if (!open_mixer(&info->capture, card, FALSE)) {
+ return cleanup(Px);
+ }
+ }
+
+ if (PaAlsa_GetStreamOutputCard(Px->pa_stream, &card) == paNoError) {
+ if (!open_mixer(&info->playback, card, TRUE)) {
+ return cleanup(Px);
+ }
+ }
+
+ return TRUE;
+}
+
+static int initialize(px_mixer *Px)
+{
+ Px->info = calloc(1, sizeof(PxInfo));
+ if (Px->info == NULL) {
+ return FALSE;
+ }
+
+ Px->CloseMixer = close_mixer;
+ Px->GetNumMixers = get_num_mixers;
+ Px->GetMixerName = get_mixer_name;
+ Px->GetMasterVolume = get_master_volume;
+ Px->SetMasterVolume = set_master_volume;
+ Px->SupportsPCMOutputVolume = supports_pcm_output_volume;
+ Px->GetPCMOutputVolume = get_pcm_output_volume;
+ Px->SetPCMOutputVolume = set_pcm_output_volume;
+ Px->GetNumOutputVolumes = get_num_output_volumes;
+ Px->GetOutputVolumeName = get_output_volume_name;
+ Px->GetOutputVolume = get_output_volume;
+ Px->SetOutputVolume = set_output_volume;
+ Px->GetNumInputSources = get_num_input_sources;
+ Px->GetInputSourceName = get_input_source_name;
+ Px->GetCurrentInputSource = get_current_input_source;
+ Px->SetCurrentInputSource = set_current_input_source;
+ Px->GetInputVolume = get_input_volume;
+ Px->SetInputVolume = set_input_volume;
+
+// Px->SupportsOutputBalance = supports_output_balance;
+// Px->GetOutputBalance = get_output_balance;
+// Px->SetOutputBalance = set_output_balance;
+// Px->SupportsPlaythrough = supports_play_through;
+// Px->GetPlaythrough = get_play_through;
+// Px->SetPlaythrough = set_play_through;
+
+ return TRUE;
+}
+
+static int cleanup(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int i;
+
+ if (info->capture.selems) {
+ for (i = 0; i < info->capture.numselems; i++) {
+ if (info->capture.selems[i].sid) {
+ snd_mixer_selem_id_free(info->capture.selems[i].sid);
+ }
+ if (info->capture.selems[i].name) {
+ free(info->capture.selems[i].name);
+ }
+ }
+ free(info->capture.selems);
+ }
+
+ if (info->capture.handle) {
+ snd_mixer_close(info->capture.handle);
+ }
+
+ if (info->playback.selems) {
+ for (i = 0; i < info->playback.numselems; i++) {
+ if (info->playback.selems[i].sid) {
+ snd_mixer_selem_id_free(info->playback.selems[i].sid);
+ }
+ if (info->playback.selems[i].name) {
+ free(info->playback.selems[i].name);
+ }
+ }
+ free(info->playback.selems);
+ }
+
+ if (info->playback.handle) {
+ snd_mixer_close(info->playback.handle);
+ }
+
+ if (info) {
+ free(info);
+ Px->info = NULL;
+ }
+
+ return FALSE;
+}
+
+static PxVolume get_volume_indexed(PxDev *dev, int i, int playback)
+{
+ snd_mixer_elem_t *elem;
+ long vol, min, max;
+
+ if (!dev->handle) {
+ return 0.0;
+ }
+
+ if (i < 0 || i > dev->numselems) {
+ return 0.0;
+ }
+
+ elem = dev->selems[i].elem;
+ if (playback) {
+ snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
+ if (snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) {
+ snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &vol);
+ return (PxVolume) vol / (max - min);
+ }
+ }
+ else {
+ snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
+ if (snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) {
+ snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &vol);
+ return (PxVolume) vol / (max - min);
+ }
+ }
+
+ return 0.0;
+}
+
+static PxVolume get_volume(PxDev *dev, const char *name, int playback)
+{
+ const char *sname;
+ int i;
+
+ if (!dev->handle) {
+ return 0.0;
+ }
+
+ for (i = 0; i < dev->numselems; i++) {
+ sname = snd_mixer_selem_id_get_name(dev->selems[i].sid);
+ if (strcmp(sname, name) == 0) {
+ return get_volume_indexed(dev, i, playback);
+ }
+ }
+
+ return 0.0;
+}
+
+static void set_volume_indexed(PxDev *dev, int i, PxVolume volume, int playback)
+{
+ snd_mixer_elem_t *elem;
+ long vol, min, max;
+ int j;
+
+ if (!dev->handle) {
+ return;
+ }
+
+ if (i < 0 || i > dev->numselems) {
+ return;
+ }
+
+ elem = dev->selems[i].elem;
+ if (playback) {
+ snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
+ for (j = 0; j < SND_MIXER_SCHN_LAST; j++) {
+ if (snd_mixer_selem_has_playback_channel(elem, j)) {
+ vol = (long) (volume * (max - min) + 0.5);
+ snd_mixer_selem_set_playback_volume(elem, j, vol);
+ }
+ }
+ }
+ else {
+ snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
+ for (j = 0; j < SND_MIXER_SCHN_LAST; j++) {
+ if (snd_mixer_selem_has_capture_channel(elem, j)) {
+ vol = (long) (volume * (max - min) + 0.5);
+ snd_mixer_selem_set_capture_volume(elem, j, vol);
+ }
+ }
+ }
+
+ return;
+}
+
+static void set_volume(PxDev *dev, const char *name, PxVolume volume, int playback)
+{
+ const char *sname;
+ int i;
+
+ if (!dev->handle) {
+ return;
+ }
+
+ for (i = 0; i < dev->numselems; i++) {
+ sname = snd_mixer_selem_id_get_name(dev->selems[i].sid);
+ if (strcmp(sname, name) == 0) {
+ set_volume_indexed(dev, i, volume, playback);
+ break;
+ }
+ }
+
+ return;
+}
+
+static void close_mixer(px_mixer *Px)
+{
+ cleanup(Px);
+
+ return;
+}
+
+static int get_num_mixers(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int i;
+ int fd;
+
+ info->numMixers = 0;
+#if 0
+ for (i = 0; i < MIXER_COUNT_MAX; i++) {
+ strcpy(info->mixers[i], MIXER_NAME_BASE);
+
+ if (i == 0)
+ info->mixers[i][strlen(MIXER_NAME_BASE)] = 0;
+ else
+ info->mixers[i][strlen(MIXER_NAME_BASE)] = '0' + (i - 1);
+
+ fd = open(info->mixers[i], O_RDWR);
+ if (fd >= 0) {
+ info->mixerIndexes[info->numMixers] = i;
+ info->numMixers++;
+ close(fd);
+ }
+ }
+#endif
+ return info->numMixers;
+}
+
+static const char *get_mixer_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+#if 0
+ if (info->numMixers <= 0)
+ get_num_mixers(Px);
+
+ if (i >= 0 && i < info->numMixers) {
+ return info->mixers[info->mixerIndexes[i]];
+ }
+#endif
+ return NULL;
+}
+
+/*
+|| Master volume
+*/
+
+static PxVolume get_master_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return get_volume(&info->playback, "Master", TRUE);
+}
+
+static void set_master_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ set_volume(&info->playback, "Master", volume, TRUE);
+
+ return;
+}
+
+/*
+|| Main output volume
+*/
+
+static int supports_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ snd_mixer_selem_id_t *id;
+
+ if (info->playback.handle) {
+ snd_mixer_selem_id_alloca(&id);
+ snd_mixer_selem_id_set_name(id, "PCM");
+
+ if (snd_mixer_find_selem(info->playback.handle, id)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static PxVolume get_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return get_volume(&info->playback, "PCM", TRUE);
+}
+
+static void set_pcm_output_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ set_volume(&info->playback, "PCM", volume, TRUE);
+
+ return;
+}
+
+/*
+|| All output volumes
+*/
+
+static int get_num_output_volumes(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->playback.handle) {
+ return info->playback.numselems;
+ }
+
+ return 0;
+}
+
+static const char *get_output_volume_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ snd_mixer_elem_t *elem;
+ char name[64];
+ int ndx = 0;
+
+ if (info->playback.handle) {
+ if (i >= 0 && i < info->playback.numselems) {
+ return info->playback.selems[i].name;
+ }
+ }
+
+ return NULL;
+}
+
+static PxVolume get_output_volume(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return get_volume_indexed(&info->playback, i, TRUE);
+}
+
+static void set_output_volume(px_mixer *Px, int i, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ set_volume_indexed(&info->playback, i, volume, TRUE);
+
+ return;
+}
+
+/*
+|| Input source
+*/
+
+static int get_num_input_sources(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->capture.handle) {
+ return info->capture.numselems;
+ }
+
+ return 0;
+}
+
+static const char *get_input_source_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->capture.handle) {
+ if (i >= 0 && i < info->capture.numselems) {
+ return info->capture.selems[i].name;
+ }
+ }
+
+ return NULL;
+}
+
+static int get_current_input_source(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ snd_mixer_elem_t *elem;
+ int sw;
+ int i, j;
+
+ if (!info->capture.handle) {
+ return -1;
+ }
+
+ for (i = 0; i < info->capture.numselems; i++) {
+ elem = info->capture.selems[i].elem;
+ for (j = 0; j <= SND_MIXER_SCHN_LAST; j++) {
+ if (snd_mixer_selem_has_capture_switch(elem)) {
+ snd_mixer_selem_get_capture_switch(elem, j, &sw);
+ if (sw) {
+ return i;
+ }
+ }
+ }
+ }
+
+ return -1; /* none */
+}
+
+static void set_current_input_source(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ snd_mixer_elem_t *elem;
+ int j;
+
+ if (!info->capture.handle) {
+ return;
+ }
+
+ if (i < 0 || i >= info->capture.numselems) {
+ return;
+ }
+
+ elem = info->capture.selems[i].elem;
+ for (j = 0; j <= SND_MIXER_SCHN_LAST; j++) {
+ if (snd_mixer_selem_has_capture_switch(elem)) {
+ snd_mixer_selem_set_capture_switch(elem, j, TRUE);
+ }
+ }
+
+ return;
+}
+
+/*
+|| Input volume
+*/
+
+static PxVolume get_input_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return get_volume(&info->capture, "Capture", FALSE);
+}
+
+static void set_input_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ set_volume(&info->capture, "Capture", volume, FALSE);
+
+ return;
+}
Added: freeswitch/branches/cseket/libs/portmixer/src/px_mac_coreaudio.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_mac_coreaudio.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,507 @@
+/*
+ * PortMixer
+ * Mac OS X / CoreAudio implementation
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/CoreAudio.h>
+#include <AudioToolbox/AudioConverter.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "portaudio.h"
+#include "pa_mac_core.h"
+
+#include "portmixer.h"
+#include "px_mixer.h"
+
+// define value of isInput passed to CoreAudio routines
+#define IS_INPUT (TRUE)
+#define IS_OUTPUT (FALSE)
+
+typedef struct PxInfo
+{
+ AudioDeviceID input;
+ AudioDeviceID output;
+ UInt32 *srcids;
+ char **srcnames;
+ int numsrcs;
+} PxInfo;
+
+int OpenMixer_Mac_CoreAudio(px_mixer *Px, int index)
+{
+ PxInfo *info;
+ OSStatus err;
+ UInt32 outSize;
+ UInt32 inID;
+ int i;
+
+ if (!initialize(Px)) {
+ return FALSE;
+ }
+
+ info = (PxInfo *) Px->info;
+
+ info->input = PaMacCore_GetStreamInputDevice(Px->pa_stream);;
+ info->output = PaMacCore_GetStreamOutputDevice(Px->pa_stream);
+
+ if (info->input == kAudioDeviceUnknown) {
+ outSize = sizeof(AudioDeviceID);
+ err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
+ &outSize,
+ &info->input);
+ if (err) {
+ return cleanup(Px);
+ }
+ }
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetPropertyInfo(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSources,
+ &outSize,
+ NULL);
+ if (err) {
+ return cleanup(Px);
+ }
+
+ info->numsrcs = outSize / sizeof(UInt32);
+ info->srcids = (UInt32 *)malloc(outSize);
+ info->srcnames = (char **)calloc(info->numsrcs, sizeof(char *));
+
+ if (info->srcids == NULL || info->srcnames == NULL) {
+ return cleanup(Px);
+ }
+
+ err = AudioDeviceGetProperty(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSources,
+ &outSize,
+ info->srcids);
+ if (err) {
+ return cleanup(Px);
+ }
+
+ for (i = 0; i < info->numsrcs; i++) {
+ AudioValueTranslation trans;
+ CFStringRef name;
+ Boolean ok;
+
+ trans.mInputData = &info->srcids[i];
+ trans.mInputDataSize = sizeof(UInt32);
+ trans.mOutputData = &name;
+ trans.mOutputDataSize = sizeof(CFStringRef);
+
+ outSize = sizeof(AudioValueTranslation);
+ err = AudioDeviceGetProperty(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSourceNameForIDCFString,
+ &outSize,
+ &trans);
+ if (err) {
+ return cleanup(Px);
+ }
+
+ info->srcnames[i] = malloc(CFStringGetLength(name)+1);
+ if (info->srcnames[i] == NULL) {
+ return cleanup(Px);
+ }
+
+ ok = CFStringGetCString(name,
+ info->srcnames[i],
+ CFStringGetLength(name)+1,
+ kCFStringEncodingISOLatin1);
+ if (!ok) {
+ return cleanup(Px);
+ }
+ }
+
+ return TRUE;
+}
+
+static int initialize(px_mixer *Px)
+{
+ Px->info = calloc(1, sizeof(PxInfo));
+ if (Px->info == NULL) {
+ return FALSE;
+ }
+
+ Px->CloseMixer = close_mixer;
+ Px->GetNumMixers = get_num_mixers;
+ Px->GetMixerName = get_mixer_name;
+
+// Px->GetMasterVolume = get_master_volume;
+// Px->SetMasterVolume = set_master_volume;
+
+ Px->SupportsPCMOutputVolume = supports_pcm_output_volume;
+ Px->GetPCMOutputVolume = get_pcm_output_volume;
+ Px->SetPCMOutputVolume = set_pcm_output_volume;
+ Px->GetNumOutputVolumes = get_num_output_volumes;
+ Px->GetOutputVolumeName = get_output_volume_name;
+ Px->GetOutputVolume = get_output_volume;
+ Px->SetOutputVolume = set_output_volume;
+ Px->GetNumInputSources = get_num_input_sources;
+ Px->GetInputSourceName = get_input_source_name;
+ Px->GetCurrentInputSource = get_current_input_source;
+ Px->SetCurrentInputSource = set_current_input_source;
+ Px->GetInputVolume = get_input_volume;
+ Px->SetInputVolume = set_input_volume;
+
+// Px->SupportsOutputBalance = supports_output_balance;
+// Px->GetOutputBalance = get_output_balance;
+// Px->SetOutputBalance = set_output_balance;
+
+ Px->SupportsPlaythrough = supports_play_through;
+ Px->GetPlaythrough = get_play_through;
+ Px->SetPlaythrough = set_play_through;
+
+ return TRUE;
+}
+
+static int cleanup(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int i;
+
+ if (info) {
+ if (info->srcids) {
+ free(info->srcids);
+ }
+
+ if (info->srcnames) {
+ for (i = 0; i < info->numsrcs; i++) {
+ if (info->srcnames[i]) {
+ free(info->srcnames[i]);
+ }
+ }
+ free(info->srcnames);
+ }
+
+ free(info);
+ Px->info = NULL;
+ }
+
+ return FALSE;
+}
+
+static int get_num_mixers(px_mixer *Px)
+{
+ return 1;
+}
+
+static const char *get_mixer_name(px_mixer *Px, int index)
+{
+ return "CoreAudio";
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+static void close_mixer(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ cleanup(Px);
+}
+
+/*
+|| PCM output volume
+*/
+
+static PxVolume get_volume(AudioDeviceID device, Boolean isInput)
+{
+ OSStatus err;
+ UInt32 outSize;
+ Float32 vol, maxvol = 0.0;
+ UInt32 mute, anymuted = 0;
+ int ch;
+ PxVolume max;
+
+ for (ch = 0; ch <= 2; ch++) {
+ outSize = sizeof(Float32);
+ err = AudioDeviceGetProperty(device,
+ ch,
+ isInput,
+ kAudioDevicePropertyVolumeScalar,
+ &outSize,
+ &vol);
+ if (!err) {
+ if (vol > maxvol)
+ maxvol = vol;
+ }
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetProperty(device,
+ ch,
+ isInput,
+ kAudioDevicePropertyMute,
+ &outSize,
+ &mute);
+
+ if (!err) {
+ if (mute)
+ anymuted = 1;
+ }
+ }
+
+ if (anymuted)
+ maxvol = 0.0;
+
+ return maxvol;
+}
+
+static void set_volume(AudioDeviceID device, Boolean isInput, PxVolume volume)
+{
+ Float32 vol = volume;
+ UInt32 mute = 0;
+ int ch;
+ OSStatus err;
+
+ /* Implement a passive attitude towards muting. If they
+ drag the volume above 0.05, unmute it. But if they
+ drag the volume down below that, just set the volume,
+ don't actually mute.
+ */
+
+ for (ch = 0; ch <= 2; ch++) {
+ err = AudioDeviceSetProperty(device,
+ 0,
+ ch,
+ isInput,
+ kAudioDevicePropertyVolumeScalar,
+ sizeof(Float32),
+ &vol);
+ if (vol > 0.05) {
+ err = AudioDeviceSetProperty(device,
+ 0,
+ ch,
+ isInput,
+ kAudioDevicePropertyMute,
+ sizeof(UInt32),
+ &mute);
+ }
+ }
+}
+
+static int supports_pcm_output_volume(px_mixer *Px)
+{
+ return 1 ;
+}
+
+static PxVolume get_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return get_volume(info->output, IS_OUTPUT);
+}
+
+static void set_pcm_output_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ set_volume(info->output, IS_OUTPUT, volume);
+}
+
+/*
+|| All output volumes
+*/
+
+int get_num_output_volumes(px_mixer *Px)
+{
+ return 1;
+}
+
+const char *get_output_volume_name(px_mixer *Px, int i)
+{
+ if (i == 0)
+ return "PCM";
+ else
+ return "";
+}
+
+static PxVolume get_output_volume(px_mixer *Px, int i)
+{
+ return get_pcm_output_volume(Px);
+}
+
+static void set_output_volume(px_mixer *Px, int i, PxVolume volume)
+{
+ set_pcm_output_volume(Px, volume);
+
+ return;
+}
+
+/*
+|| Input sources
+*/
+
+static int get_num_input_sources(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return info->numsrcs;
+}
+
+static const char *get_input_source_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (i >= info->numsrcs)
+ return NULL;
+
+ return info->srcnames[i];
+}
+
+static int get_current_input_source(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ OSStatus err;
+ UInt32 outSize;
+ UInt32 outID = 0;
+ int i;
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetProperty(info->input,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSource,
+ &outSize,
+ &outID);
+
+ if (!err) {
+ for (i = 0; i < info->numsrcs; i++) {
+ if (info->srcids[i] == outID) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
+static void set_current_input_source(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ OSStatus err;
+
+ if (i >= info->numsrcs) {
+ return;
+ }
+
+ err = AudioDeviceSetProperty(info->input,
+ 0,
+ 0,
+ IS_INPUT,
+ kAudioDevicePropertyDataSource,
+ sizeof(UInt32),
+ &info->srcids[i]);
+
+ return;
+}
+
+/*
+|| Input volume
+*/
+
+static PxVolume get_input_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return get_volume(info->input, IS_INPUT);
+}
+
+static void set_input_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ set_volume(info->input, IS_INPUT, volume);
+
+ return;
+}
+
+/*
+|| Playthrough
+*/
+
+static int supports_play_through(px_mixer *Px)
+{
+ return TRUE;
+}
+
+static PxVolume get_play_through(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ OSStatus err;
+ UInt32 outSize;
+ UInt32 flag;
+
+ outSize = sizeof(UInt32);
+ err = AudioDeviceGetProperty(info->output,
+ 0,
+ IS_OUTPUT,
+ kAudioDevicePropertyPlayThru,
+ &outSize,
+ &flag);
+ if (err)
+ return 0.0;
+
+ if (flag)
+ return 1.0;
+ else
+ return 0.0;
+}
+
+static void set_play_through(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ UInt32 flag = (volume > 0.01);
+ OSStatus err;
+
+ err = AudioDeviceSetProperty(info->output,
+ 0,
+ 0,
+ IS_OUTPUT,
+ kAudioDevicePropertyPlayThru,
+ sizeof(UInt32),
+ &flag);
+}
Added: freeswitch/branches/cseket/libs/portmixer/src/px_mixer.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_mixer.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,628 @@
+/*
+ * PortMixer
+ * PortMixer core
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+#include "portaudio.h"
+#include "portmixer.h"
+#include "px_mixer.h"
+
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+#if defined(__LINUX__) || defined(__APPLE__)
+#include <stdlib.h>
+#endif
+#include <stdlib.h>
+
+#if defined(PX_USE_WIN_MME)
+int OpenMixer_Win_MME(px_mixer *Px, int index);
+#endif
+
+#if defined(PX_USE_WIN_DSOUND)
+int OpenMixer_Win_DirectSound(px_mixer *Px, int index);
+#endif
+
+#if defined(PX_USE_MAC_COREAUDIO)
+int OpenMixer_Mac_CoreAudio(px_mixer *Px, int index);
+#endif
+
+#if defined(PX_USE_UNIX_OSS)
+int OpenMixer_Unix_OSS(px_mixer *Px, int index);
+#endif
+
+#if defined(PX_USE_LINUX_ALSA)
+int OpenMixer_Linux_ALSA(px_mixer *Px, int index);
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(_DEBUG)
+#include <stdio.h>
+#include <stdlib.h>
+static void dprintf(const char *format, ...)
+{
+ char buf[4096];
+ va_list args;
+ int cnt;
+
+ va_start(args, format);
+ cnt = _vsnprintf(buf, sizeof(buf) - 1, format, args);
+ va_end(args);
+
+ if (cnt > 0) {
+ buf[cnt] = '\0';
+ OutputDebugString(buf);
+ }
+}
+#endif
+
+static px_mixer *verify_mixer(PxMixer *mixer)
+{
+ px_mixer *Px = (px_mixer *)mixer;
+
+ if (Px == NULL || Px->magic != PX_MIXER_MAGIC)
+ return NULL;
+
+ return Px;
+}
+
+/*
+ Px_OpenMixer() returns a mixer which will work with the given PortAudio
+ audio device. Pass 0 as the index for the first (default) mixer.
+*/
+
+PxMixer *Px_OpenMixer(PaStream *pa_stream, int i)
+{
+ px_mixer *Px;
+ int good = TRUE;
+
+ Px = (px_mixer *) malloc(sizeof(px_mixer));
+ if (Px == NULL) {
+ return NULL;
+ }
+
+ Px->magic = PX_MIXER_MAGIC;
+ Px->pa_stream = pa_stream;
+ Px->info = NULL;
+
+ if (!initialize(Px)) {
+ free(Px);
+ return NULL;
+ }
+
+ switch (Pa_GetStreamHostApiType(pa_stream))
+ {
+#if defined(PX_USE_WIN_MME)
+ case paMME:
+ good = OpenMixer_Win_MME(Px, i);
+ break;
+#endif
+
+#if defined(PX_USE_WIN_DSOUND)
+ case paDirectSound:
+ good = OpenMixer_Win_DirectSound(Px, i);
+ break;
+#endif
+
+#if defined(PX_USE_MAC_COREAUDIO)
+ case paCoreAudio:
+ good = OpenMixer_Mac_CoreAudio(Px, i);
+ break;
+#endif
+
+#if defined(PX_USE_UNIX_OSS)
+ case paOSS:
+ good = OpenMixer_Unix_OSS(Px, i);
+ break;
+#endif
+
+#if defined(PX_USE_LINUX_ALSA)
+ case paALSA:
+ good = OpenMixer_Linux_ALSA(Px, i);
+ break;
+#endif
+ }
+
+ if (!good) {
+ free(Px);
+ return NULL;
+ }
+
+ return Px;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->CloseMixer(Px);
+
+ free(Px);
+
+ return;
+}
+
+/*
+|| Mixer info
+*/
+int Px_GetNumMixers(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ int cnt;
+
+ if (!Px) {
+ return 0;
+ }
+
+ cnt = Px->GetNumMixers(Px);
+
+ return cnt;
+}
+
+const char *Px_GetMixerName(PxMixer *mixer, int i)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ const char *name;
+
+ if (!Px) {
+ return 0;
+ }
+
+ name = Px->GetMixerName(Px, i);
+
+ return name;
+}
+
+/*
+|| Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0.0;
+
+ return Px->GetMasterVolume(Px);
+}
+
+void Px_SetMasterVolume(PxMixer *mixer, PxVolume volume)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->SetMasterVolume(Px, volume);
+
+ return;
+}
+
+/*
+|| Main output volume
+*/
+
+PxVolume Px_GetPCMOutputVolume(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0.0;
+
+ return Px->GetPCMOutputVolume(Px);
+}
+
+void Px_SetPCMOutputVolume(PxMixer *mixer, PxVolume volume)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->SetPCMOutputVolume(Px, volume);
+
+ return;
+}
+
+int Px_SupportsPCMOutputVolume(PxMixer* mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return FALSE;
+
+ return Px->SupportsPCMOutputVolume(Px);
+}
+
+/*
+|| Output info
+*/
+
+int Px_GetNumOutputVolumes(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0;
+
+ return Px->GetNumOutputVolumes(Px);
+}
+
+const char *Px_GetOutputVolumeName(PxMixer *mixer, int i)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return NULL;
+
+ return Px->GetOutputVolumeName(Px, i);
+}
+
+/*
+|| Output volume
+*/
+
+PxVolume Px_GetOutputVolume(PxMixer *mixer, int i)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0.0;
+
+ return Px->GetOutputVolume(Px, i);
+}
+
+void Px_SetOutputVolume(PxMixer *mixer, int i, PxVolume volume)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->SetOutputVolume(Px, i, volume);
+
+ return;
+}
+
+/*
+|| Input source
+*/
+
+int Px_GetNumInputSources(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0;
+
+ return Px->GetNumInputSources(Px);
+}
+
+const char *Px_GetInputSourceName(PxMixer *mixer, int i)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return NULL;
+
+ return Px->GetInputSourceName(Px, i);
+}
+
+int Px_GetCurrentInputSource(PxMixer *mixer) /* may return -1 == none */
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return -1;
+
+ return Px->GetCurrentInputSource(Px);
+}
+
+void Px_SetCurrentInputSource(PxMixer *mixer, int i)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->SetCurrentInputSource(Px, i);
+
+ return;
+}
+
+/*
+|| Input volume
+*/
+
+PxVolume Px_GetInputVolume(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0.0;
+
+ return Px->GetInputVolume(Px);
+}
+
+void Px_SetInputVolume(PxMixer *mixer, PxVolume volume)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->SetInputVolume(Px, volume);
+
+ return;
+}
+
+/*
+|| Balance
+*/
+
+int Px_SupportsOutputBalance(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return FALSE;
+
+ return Px->SupportsOutputBalance(Px);
+}
+
+PxBalance Px_GetOutputBalance(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0.0;
+
+ return Px->GetOutputBalance(Px);
+}
+
+void Px_SetOutputBalance(PxMixer *mixer, PxBalance balance)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->SetOutputBalance(Px, balance);
+
+ return;
+}
+
+/*
+|| Playthrough
+*/
+
+int Px_SupportsPlaythrough(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return FALSE;
+
+ return Px->SupportsPlaythrough(Px);
+}
+
+PxVolume Px_GetPlaythrough(PxMixer *mixer)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return 0.0;
+
+ return Px->GetPlaythrough(Px);
+}
+
+void Px_SetPlaythrough(PxMixer *mixer, PxVolume volume)
+{
+ px_mixer *Px = verify_mixer(mixer);
+ if (!Px)
+ return;
+
+ Px->SetPlaythrough(Px, volume);
+
+ return;
+}
+
+/* ----------------------------------------------------------------------------
+|| Default API routines ||
+-----------------------------------------------------------------------------*/
+
+static int initialize(px_mixer *Px)
+{
+ Px->CloseMixer = close_mixer;
+ Px->GetNumMixers = get_num_mixers;
+ Px->GetMixerName = get_mixer_name;
+ Px->GetMasterVolume = get_master_volume;
+ Px->SetMasterVolume = set_master_volume;
+ Px->SupportsPCMOutputVolume = supports_pcm_output_volume;
+ Px->GetPCMOutputVolume = get_pcm_output_volume;
+ Px->SetPCMOutputVolume = set_pcm_output_volume;
+ Px->GetNumOutputVolumes = get_num_output_volumes;
+ Px->GetOutputVolumeName = get_output_volume_name;
+ Px->GetOutputVolume = get_output_volume;
+ Px->SetOutputVolume = set_output_volume;
+ Px->GetNumInputSources = get_num_input_sources;
+ Px->GetInputSourceName = get_input_source_name;
+ Px->GetCurrentInputSource = get_current_input_source;
+ Px->SetCurrentInputSource = set_current_input_source;
+ Px->GetInputVolume = get_input_volume;
+ Px->SetInputVolume = set_input_volume;
+ Px->SupportsOutputBalance = supports_output_balance;
+ Px->GetOutputBalance = get_output_balance;
+ Px->SetOutputBalance = set_output_balance;
+ Px->SupportsPlaythrough = supports_play_through;
+ Px->GetPlaythrough = get_play_through;
+ Px->SetPlaythrough = set_play_through;
+
+ return TRUE;
+}
+
+static void close_mixer(px_mixer *Px)
+{
+ return;
+}
+
+static int get_num_mixers(px_mixer *Px)
+{
+ return 0;
+}
+
+static const char *get_mixer_name(px_mixer *Px, int i)
+{
+ return NULL;
+}
+
+static PxVolume get_master_volume(px_mixer *Px)
+{
+ return 0.0;
+}
+
+static void set_master_volume(px_mixer *Px, PxVolume volume)
+{
+ return;
+}
+
+/*
+|| Main output volume
+*/
+
+static int supports_pcm_output_volume(px_mixer *Px)
+{
+ return FALSE;
+}
+
+static PxVolume get_pcm_output_volume(px_mixer *Px)
+{
+ return 0.0;
+}
+
+static void set_pcm_output_volume(px_mixer *Px, PxVolume volume)
+{
+ return;
+}
+
+/*
+|| All output volumes
+*/
+
+static int get_num_output_volumes(px_mixer *Px)
+{
+ return 0;
+}
+
+static const char *get_output_volume_name(px_mixer *Px, int i)
+{
+ return NULL;
+}
+
+static PxVolume get_output_volume(px_mixer *Px, int i)
+{
+ return 0.0;
+}
+
+static void set_output_volume(px_mixer *Px, int i, PxVolume volume)
+{
+ return;
+}
+
+/*
+|| Input source
+*/
+
+static int get_num_input_sources(px_mixer *Px)
+{
+ return 0;
+}
+
+static const char *get_input_source_name(px_mixer *Px, int i)
+{
+ return NULL;
+}
+
+static int get_current_input_source(px_mixer *Px)
+{
+ return -1;
+}
+
+static void set_current_input_source(px_mixer *Px, int i)
+{
+ return;
+}
+
+/*
+|| Input volume
+*/
+
+static PxVolume get_input_volume(px_mixer *Px)
+{
+ return 0.0;
+}
+
+static void set_input_volume(px_mixer *Px, PxVolume volume)
+{
+ return;
+}
+
+/*
+|| Balance
+*/
+
+static int supports_output_balance(px_mixer *Px)
+{
+ return FALSE;
+}
+
+static PxBalance get_output_balance(px_mixer *Px)
+{
+ return 0.0;
+}
+
+static void set_output_balance(px_mixer *Px, PxBalance balance)
+{
+ return;
+}
+
+/*
+|| Playthrough
+*/
+
+static int supports_play_through(px_mixer *Px)
+{
+ return FALSE;
+}
+
+static PxVolume get_play_through(px_mixer *Px)
+{
+ return 0.0;
+}
+
+static void set_play_through(px_mixer *Px, PxVolume volume)
+{
+ return;
+}
Added: freeswitch/branches/cseket/libs/portmixer/src/px_mixer.h
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_mixer.h Fri Aug 24 13:53:53 2007
@@ -0,0 +1,200 @@
+#ifndef PX_MIXER_H
+#define PX_MIXER_H
+/*
+ * PortMixer
+ * PortMixer core header
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define PX_MIXER_MAGIC 0x50544D52
+
+#if !defined(NULL)
+#define NULL 0
+#endif
+
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+
+#if !defined(TRUE)
+#define TRUE 1
+#endif
+
+typedef struct px_mixer px_mixer;
+
+struct px_mixer
+{
+ unsigned long magic;
+ void *pa_stream;
+ void *info;
+
+ PxMixer (*OpenMixer) (void *pa_stream, int i);
+ void (*CloseMixer) (px_mixer *Px);
+
+ /*
+ || Mixer info
+ */
+ int (*GetNumMixers) (px_mixer *Px);
+ const char *(*GetMixerName) (px_mixer *Px, int i);
+
+ /*
+ || Master (output) volume
+ */
+
+ PxVolume (*GetMasterVolume) (px_mixer *Px);
+ void (*SetMasterVolume) (px_mixer *Px, PxVolume volume);
+
+ /*
+ || Main output volume
+ */
+
+ int (*SupportsPCMOutputVolume) (px_mixer *Px);
+ PxVolume (*GetPCMOutputVolume) (px_mixer *Px);
+ void (*SetPCMOutputVolume) (px_mixer *Px, PxVolume volume);
+
+ /*
+ || Output info
+ */
+
+ int (*GetNumOutputVolumes) (px_mixer *Px);
+ const char *(*GetOutputVolumeName) (px_mixer *Px, int i);
+
+ /*
+ || Output volume
+ */
+
+ PxVolume (*GetOutputVolume) (px_mixer *Px, int i);
+ void (*SetOutputVolume) (px_mixer *Px, int i, PxVolume volume);
+
+ /*
+ || Input source
+ */
+
+ int (*GetNumInputSources) (px_mixer *Px);
+ const char *(*GetInputSourceName) (px_mixer *Px, int i);
+ int (*GetCurrentInputSource) (px_mixer *Px); /* may return -1 == none */
+ void (*SetCurrentInputSource) (px_mixer *Px, int i);
+
+ /*
+ || Input volume
+ */
+
+ PxVolume (*GetInputVolume) (px_mixer *Px);
+ void (*SetInputVolume) (px_mixer *Px, PxVolume volume);
+
+ /*
+ || Balance
+ */
+
+ int (*SupportsOutputBalance) (px_mixer *Px);
+ PxBalance (*GetOutputBalance) (px_mixer *Px);
+ void (*SetOutputBalance) (px_mixer *Px, PxBalance balance);
+
+ /*
+ || Playthrough
+ */
+
+ int (*SupportsPlaythrough) (px_mixer *Px);
+ PxVolume (*GetPlaythrough) (px_mixer *Px);
+ void (*SetPlaythrough) (px_mixer *Px, PxVolume volume);
+};
+
+static int initialize(px_mixer *Px);
+static int cleanup(px_mixer *Px);
+
+static void close_mixer(px_mixer *Px);
+static int get_num_mixers(px_mixer *Px);
+static const char *get_mixer_name(px_mixer *Px, int i);
+static PxVolume get_master_volume(px_mixer *Px);
+static void set_master_volume(px_mixer *Px, PxVolume volume);
+
+/*
+|| Main output volume
+*/
+
+static PxVolume get_pcm_output_volume(px_mixer *Px);
+static void set_pcm_output_volume(px_mixer *Px, PxVolume volume);
+static int supports_pcm_output_volume(px_mixer *Px);
+
+/*
+|| All output volumes
+*/
+
+static int get_num_output_volumes(px_mixer *Px);
+static const char *get_output_volume_name(px_mixer *Px, int i);
+static PxVolume get_output_volume(px_mixer *Px, int i);
+static void set_output_volume(px_mixer *Px, int i, PxVolume volume);
+
+/*
+|| Input source
+*/
+
+static int get_num_input_sources(px_mixer *Px);
+static const char *get_input_source_name(px_mixer *Px, int i);
+static int get_current_input_source(px_mixer *Px);
+static void set_current_input_source(px_mixer *Px, int i);
+
+/*
+|| Input volume
+*/
+
+static PxVolume get_input_volume(px_mixer *Px);
+static void set_input_volume(px_mixer *Px, PxVolume volume);
+
+/*
+|| Balance
+*/
+
+static int supports_output_balance(px_mixer *Px);
+static PxBalance get_output_balance(px_mixer *Px);
+static void set_output_balance(px_mixer *Px, PxBalance balance);
+
+/*
+|| Playthrough
+*/
+
+static int supports_play_through(px_mixer *Px);
+static PxVolume get_play_through(px_mixer *Px);
+static void set_play_through(px_mixer *Px, PxVolume volume);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Added: freeswitch/branches/cseket/libs/portmixer/src/px_unix_oss.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_unix_oss.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,531 @@
+/*
+ * PortMixer
+ * Unix OSS Implementation
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#if defined(__linux__)
+#include <linux/soundcard.h>
+#elif defined(__FreeBSD__)
+#include <sys/soundcard.h>
+#else
+#include <machine/soundcard.h> /* JH20010905 */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include "portaudio.h"
+#include "pa_unix_oss.h"
+
+#include "portmixer.h"
+#include "px_mixer.h"
+
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+
+#if !defined(TRUE)
+#define TRUE 1
+#endif
+
+#define MIXER_NAME_BASE "/dev/mixer"
+#define MIXER_COUNT_MAX 10
+
+typedef struct PxDev
+{
+ const char *name;
+ int fd;
+ int num;
+ int chans[SOUND_MIXER_NRDEVICES];
+} PxDev;
+
+typedef struct PxInfo
+{
+ int numMixers;
+ int mixerIndexes[MIXER_COUNT_MAX];
+ char mixers[MIXER_COUNT_MAX][sizeof(MIXER_NAME_BASE) + 1];
+
+ PxDev capture;
+ PxDev playback;
+} PxInfo;
+
+static const char *labels[] = SOUND_DEVICE_LABELS;
+
+static int open_mixer(PxDev *dev, int cmd)
+{
+ char name[sizeof(MIXER_NAME_BASE) + 1];
+ int mask;
+ int i;
+ int id = 0;
+
+ for (i = strlen(dev->name) - 1; i >= 0; i++) {
+ if (!isdigit(dev->name[i])) {
+ break;
+ }
+ }
+
+ id = atoi(&dev->name[i + 1]);
+ if (id < 0 || id >= MIXER_COUNT_MAX) {
+ return -1;
+ }
+
+ strcpy(name, MIXER_NAME_BASE);
+ if (id == 0)
+ name[strlen(MIXER_NAME_BASE)] = 0;
+ else
+ name[strlen(MIXER_NAME_BASE)] = '0' + (id - 1);
+
+ do {
+ dev->fd = open(name, O_RDWR);
+ if (dev->fd < 0) {
+ break;
+ }
+
+ if (ioctl(dev->fd, cmd, &mask) == -1) {
+ break;
+ }
+
+ dev->num = 0;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if (mask & (1 << i)) {
+ dev->chans[dev->num++] = i;
+ }
+ }
+ return TRUE;
+
+ } while (FALSE);
+
+ if (dev->fd >= 0) {
+ close(dev->fd);
+ dev->fd = -1;
+ }
+
+ return FALSE;
+}
+
+int OpenMixer_Unix_OSS(px_mixer *Px, int index)
+{
+ PxInfo *info;
+
+ if (!initialize(Px)) {
+ return FALSE;
+ }
+
+ get_num_mixers(Px);
+
+ info = (PxInfo *) Px->info;
+ info->capture.fd = -1;
+ info->capture.num = 0;
+ info->playback.fd = -1;
+ info->playback.num = 0;
+
+ do {
+ info->capture.name = PaOSS_GetStreamInputDevice(Px->pa_stream);
+
+ if (info->capture.name) {
+ if (!open_mixer(&info->capture, SOUND_MIXER_READ_RECMASK)) {
+ break;
+ }
+ }
+
+ info->playback.name = PaOSS_GetStreamOutputDevice(Px->pa_stream);
+ if (info->playback.name) {
+ if (!open_mixer(&info->playback, SOUND_MIXER_READ_DEVMASK)) {
+ break;
+ }
+ }
+
+ return TRUE;
+
+ } while (FALSE);
+
+ return cleanup(Px);
+}
+
+static PxVolume get_volume(int fd, int channel)
+{
+ int vol;
+ int stereo;
+
+ if (ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == 0)
+ stereo = ((stereo & (1 << channel)) != 0);
+ else
+ stereo = 0;
+
+ if (ioctl(fd, MIXER_READ(channel), &vol) == -1)
+ return 0.0;
+
+ if (stereo)
+ return ((vol & 0xFF)/200.0) + (((vol>>8) & 0xFF)/200.0);
+ else
+ return (vol & 0xFF)/100.0;
+}
+
+static int initialize(px_mixer *Px)
+{
+ Px->info = calloc(1, sizeof(PxInfo));
+ if (Px->info == NULL) {
+ return FALSE;
+ }
+
+ Px->CloseMixer = close_mixer;
+ Px->GetNumMixers = get_num_mixers;
+ Px->GetMixerName = get_mixer_name;
+ Px->GetMasterVolume = get_master_volume;
+ Px->SetMasterVolume = set_master_volume;
+ Px->SupportsPCMOutputVolume = supports_pcm_output_volume;
+ Px->GetPCMOutputVolume = get_pcm_output_volume;
+ Px->SetPCMOutputVolume = set_pcm_output_volume;
+ Px->GetNumOutputVolumes = get_num_output_volumes;
+ Px->GetOutputVolumeName = get_output_volume_name;
+ Px->GetOutputVolume = get_output_volume;
+ Px->SetOutputVolume = set_output_volume;
+ Px->GetNumInputSources = get_num_input_sources;
+ Px->GetInputSourceName = get_input_source_name;
+ Px->GetCurrentInputSource = get_current_input_source;
+ Px->SetCurrentInputSource = set_current_input_source;
+ Px->GetInputVolume = get_input_volume;
+ Px->SetInputVolume = set_input_volume;
+
+// Px->SupportsOutputBalance = supports_output_balance;
+// Px->GetOutputBalance = get_output_balance;
+// Px->SetOutputBalance = set_output_balance;
+// Px->SupportsPlaythrough = supports_play_through;
+// Px->GetPlaythrough = get_play_through;
+// Px->SetPlaythrough = set_play_through;
+
+ return TRUE;
+}
+
+static int cleanup(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->capture.fd >= 0) {
+ close(info->capture.fd);
+ }
+
+ if (info->playback.fd >= 0) {
+ close(info->playback.fd);
+ }
+
+ if (info) {
+ free(info);
+ Px->info = NULL;
+ }
+
+ return FALSE;
+}
+
+static void close_mixer(px_mixer *Px)
+{
+ cleanup(Px);
+
+ return;
+}
+
+static int get_num_mixers(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int i;
+ int fd;
+
+ info->numMixers = 0;
+
+ for (i = 0; i < MIXER_COUNT_MAX; i++) {
+ strcpy(info->mixers[i], MIXER_NAME_BASE);
+
+ if (i == 0)
+ info->mixers[i][strlen(MIXER_NAME_BASE)] = 0;
+ else
+ info->mixers[i][strlen(MIXER_NAME_BASE)] = '0' + (i - 1);
+
+ fd = open(info->mixers[i], O_RDWR);
+ if (fd >= 0) {
+ info->mixerIndexes[info->numMixers] = i;
+ info->numMixers++;
+ close(fd);
+ }
+ }
+
+ return info->numMixers;
+}
+
+static const char *get_mixer_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->numMixers <= 0)
+ get_num_mixers(Px);
+
+ if (i >= 0 && i < info->numMixers) {
+ return info->mixers[info->mixerIndexes[i]];
+ }
+
+ return NULL;
+}
+
+/*
+|| Master volume
+*/
+
+static PxVolume get_master_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->playback.fd >= 0) {
+ return get_volume(info->playback.fd, SOUND_MIXER_READ_VOLUME);
+ }
+
+ return 0.0;
+}
+
+static void set_master_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int vol = (int) ((volume * 100.0) + 0.5);
+
+ if (info->playback.fd >= 0) {
+ vol = (vol | (vol << 8));
+ ioctl(info->playback.fd, SOUND_MIXER_WRITE_VOLUME, &vol);
+ }
+
+ return;
+}
+
+/*
+|| Main output volume
+*/
+
+static int supports_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int i;
+
+ if (info->playback.fd >= 0) {
+ for (i = 0; i < info->playback.num; i++) {
+ if (info->playback.chans[i] == SOUND_MIXER_PCM) {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+static PxVolume get_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (supports_pcm_output_volume(Px)) {
+ return get_volume(info->playback.fd, SOUND_MIXER_READ_PCM);
+ }
+
+ return 0.0;
+}
+
+static void set_pcm_output_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int vol = (int) ((volume * 100.0) + 0.5);
+
+ if (supports_pcm_output_volume(Px)) {
+ vol = (vol | (vol << 8));
+ ioctl(info->playback.fd, SOUND_MIXER_WRITE_PCM, &vol);
+ }
+
+ return;
+}
+
+/*
+|| All output volumes
+*/
+
+static int get_num_output_volumes(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return info->playback.num;
+}
+
+static const char *get_output_volume_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->playback.fd >= 0) {
+ if (i >= 0 && i < info->playback.num) {
+ return labels[info->playback.chans[i]];
+ }
+ }
+
+ return NULL;
+}
+
+static PxVolume get_output_volume(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->playback.fd >= 0) {
+ if (i >= 0 && i < info->playback.num) {
+ return get_volume(info->playback.fd, info->playback.chans[i]);
+ }
+ }
+
+ return 0.0;
+}
+
+static void set_output_volume(px_mixer *Px, int i, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int vol = (int) ((volume * 100.0) + 0.5);
+
+ if (info->playback.fd >= 0) {
+ if (i >= 0 && i < info->playback.num) {
+ vol = (vol | (vol << 8));
+ ioctl(info->playback.fd, MIXER_WRITE(info->playback.chans[i]), &vol);
+ }
+ }
+
+ return;
+}
+
+/*
+|| Input source
+*/
+
+static int get_num_input_sources(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return info->capture.num;
+}
+
+static const char *get_input_source_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (info->capture.fd >= 0) {
+ if (i >= 0 && i < info->capture.num) {
+ return labels[info->capture.chans[i]];
+ }
+ }
+
+ return NULL;
+}
+
+static int get_current_input_source(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int mask;
+ int i;
+
+ /* Note that there may be more than one in OSS; we pick
+ the first one */
+ if (info->capture.fd >= 0) {
+ if (ioctl(info->capture.fd, SOUND_MIXER_READ_RECSRC, &mask) == -1) {
+ return -1; /* none / error */
+ }
+
+ for (i = 0; i < info->capture.num; i++) {
+ if (mask & (1 << info->capture.chans[i])) {
+ return i;
+ }
+ }
+ }
+
+ return -1; /* none */
+}
+
+static void set_current_input_source(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int mask;
+
+ if (info->capture.fd >= 0) {
+ if (i >= 0 && i < info->capture.num) {
+ mask = (1 << info->capture.chans[i]);
+
+ ioctl(info->capture.fd, SOUND_MIXER_WRITE_RECSRC, &mask);
+ }
+ }
+
+ return;
+}
+
+/*
+|| Input volume
+*/
+
+static PxVolume get_input_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int i;
+
+ if (info->capture.fd >= 0) {
+ i = get_current_input_source(Px);
+ if (i >= 0) {
+ return get_volume(info->capture.fd, info->capture.chans[i]);
+ }
+ }
+
+ return 0.0;
+}
+
+static void set_input_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int vol;
+ int i;
+
+ if (info->capture.fd >= 0) {
+ i = get_current_input_source(Px);
+ if (i >= 0) {
+ vol = (int) ((volume * 100.0) + 0.5);
+ vol = (vol | (vol << 8));
+
+ ioctl(info->capture.fd, MIXER_WRITE(info->capture.chans[i]), &vol);
+ }
+ }
+
+ return;
+}
Added: freeswitch/branches/cseket/libs/portmixer/src/px_win_common.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_win_common.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,744 @@
+/*
+ * PortMixer
+ * Common Windows routines
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni and Augustus Saunders
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <windows.h>
+
+#include "portaudio.h"
+
+#include "portmixer.h"
+#include "px_mixer.h"
+#include "px_win_common.h"
+
+static UINT get_ctrls(HMIXEROBJ mixer, DWORD lineID, PxCtrl **pctrls);
+static DWORD find_ctrl(HMIXEROBJ mixer, DWORD lineID, DWORD ctrlID);
+
+#if defined(_DEBUG)
+#include <stdio.h>
+#include <stdlib.h>
+static void dprintf(const char *format, ...)
+{
+ char buf[4096];
+ va_list args;
+ int cnt;
+
+ va_start(args, format);
+ cnt = _vsnprintf(buf, sizeof(buf) - 1, format, args);
+ va_end(args);
+
+ if (cnt > 0) {
+ buf[cnt] = '\0';
+ OutputDebugString(buf);
+ }
+}
+#endif
+
+int open_mixers(px_mixer *Px, UINT deviceIn, UINT deviceOut)
+{
+ PxInfo*info;
+ MMRESULT res;
+
+ if (deviceIn == UINT_MAX && deviceOut == UINT_MAX) {
+ return FALSE;
+ }
+
+ if (!initialize(Px)) {
+ return FALSE;
+ }
+
+ info = (PxInfo *) Px->info;
+ info->hInputMixer = NULL;
+ info->hOutputMixer = NULL;
+ info->numInputs = 0;
+ info->muxID = 0;
+ info->speakerID = 0;
+ info->waveID = 0;
+
+ if (deviceIn != UINT_MAX) {
+ res = mixerOpen((LPHMIXER) &info->hInputMixer,
+ deviceIn,
+ 0,
+ 0,
+ MIXER_OBJECTF_WAVEIN);
+ if (res != MMSYSERR_NOERROR) {
+ return cleanup(Px);
+ }
+
+ info->muxID = find_ctrl(info->hInputMixer,
+ MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
+ MIXERCONTROL_CONTROLTYPE_MUX);
+ if (info->muxID == -1) {
+ info->muxID = find_ctrl(info->hInputMixer,
+ MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
+ MIXERCONTROL_CONTROLTYPE_MIXER);
+ }
+
+ info->numInputs = get_ctrls(info->hInputMixer,
+ MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
+ &info->src);
+
+ if (info->numInputs == 0) {
+ return cleanup(Px);
+ }
+ }
+
+ if (deviceOut != UINT_MAX) {
+ res = mixerOpen((LPHMIXER) &info->hOutputMixer,
+ deviceOut,
+ 0,
+ 0,
+ MIXER_OBJECTF_WAVEOUT);
+ if (res != MMSYSERR_NOERROR) {
+ return cleanup(Px);
+ }
+
+ info->speakerID = find_ctrl(info->hOutputMixer,
+ MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
+ MIXERCONTROL_CONTROLTYPE_VOLUME);
+
+ info->waveID = find_ctrl(info->hOutputMixer,
+ MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,
+ MIXERCONTROL_CONTROLTYPE_VOLUME);
+
+ info->numOutputs = get_ctrls(info->hOutputMixer,
+ MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
+ &info->dst);
+
+ if (info->numOutputs == 0) {
+ return cleanup(Px);
+ }
+ }
+
+ return TRUE;
+}
+
+static UINT get_ctrls(HMIXEROBJ mixer, DWORD lineID, PxCtrl **pctrls)
+{
+ MMRESULT res;
+ MIXERLINE line;
+ MIXERLINECONTROLS controls;
+ MIXERCONTROL control;
+ PxCtrl *ctrls = NULL;
+ UINT num;
+ UINT s;
+
+ do {
+ line.cbStruct = sizeof(MIXERLINE);
+ line.dwComponentType = lineID;
+
+ res = mixerGetLineInfo(mixer,
+ &line,
+ MIXER_GETLINEINFOF_COMPONENTTYPE);
+
+ if (res != MMSYSERR_NOERROR) {
+ break;
+ }
+
+ num = (UINT) line.cConnections;
+
+ ctrls = calloc(num, sizeof(PxInfo));
+ if (ctrls == NULL) {
+ break;
+ }
+
+ for (s = 0; s < num; s++)
+ {
+ line.dwSource = s;
+
+ res = mixerGetLineInfo(mixer,
+ &line,
+ MIXER_GETLINEINFOF_SOURCE);
+
+ if (res != MMSYSERR_NOERROR) {
+ break;
+ }
+
+ ctrls[s].lineID = line.dwLineID;
+ ctrls[s].name = strdup(line.szName);
+ if (ctrls[s].name == NULL) {
+ break;
+ }
+
+ controls.cbStruct = sizeof(MIXERLINECONTROLS);
+ controls.dwLineID = line.dwLineID;
+ controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
+ controls.cbmxctrl = sizeof(MIXERCONTROL);
+ controls.pamxctrl = &control;
+
+ control.cbStruct = sizeof(MIXERCONTROL);
+
+ res = mixerGetLineControls(mixer,
+ &controls,
+ MIXER_GETLINECONTROLSF_ONEBYTYPE);
+
+ if (res == MMSYSERR_NOERROR)
+ ctrls[s].controlID = control.dwControlID;
+ else
+ ctrls[s].controlID = 0;
+ }
+
+ if (s != num) {
+ break;
+ }
+
+ *pctrls = ctrls;
+
+ return num;
+
+ } while (FALSE);
+
+ if (ctrls) {
+ for (s = 0; s < num; s++) {
+ if (ctrls[s].name) {
+ free(ctrls[s].name);
+ }
+ }
+
+ free(ctrls);
+ }
+
+ return 0;
+}
+
+static DWORD find_ctrl(HMIXEROBJ mixer, DWORD lineID, DWORD ctrlID)
+{
+ MMRESULT res;
+ MIXERLINE line;
+ MIXERLINECONTROLS controls;
+ MIXERCONTROL control;
+
+ line.cbStruct = sizeof(MIXERLINE);
+ line.dwComponentType = lineID;
+
+ res = mixerGetLineInfo(mixer,
+ &line,
+ MIXER_GETLINEINFOF_COMPONENTTYPE);
+
+ if (res != MMSYSERR_NOERROR) {
+ return -1;
+ }
+
+ controls.cbStruct = sizeof(MIXERLINECONTROLS);
+ controls.dwLineID = line.dwLineID;
+ controls.dwControlType = ctrlID;
+ controls.cbmxctrl = sizeof(MIXERCONTROL);
+ controls.pamxctrl = &control;
+
+ control.cbStruct = sizeof(MIXERCONTROL);
+
+ res = mixerGetLineControls(mixer,
+ &controls,
+ MIXER_GETLINECONTROLSF_ONEBYTYPE);
+
+ if (res != MMSYSERR_NOERROR) {
+ return -1;
+ }
+
+ return control.dwControlID;
+}
+
+static int initialize(px_mixer *Px)
+{
+ Px->info = calloc(1, sizeof(PxInfo));
+ if (Px->info == NULL) {
+ return FALSE;
+ }
+
+ Px->CloseMixer = close_mixer;
+ Px->GetNumMixers = get_num_mixers;
+ Px->GetMixerName = get_mixer_name;
+ Px->GetMasterVolume = get_master_volume;
+ Px->SetMasterVolume = set_master_volume;
+ Px->SupportsPCMOutputVolume = supports_pcm_output_volume;
+ Px->GetPCMOutputVolume = get_pcm_output_volume;
+ Px->SetPCMOutputVolume = set_pcm_output_volume;
+ Px->GetNumOutputVolumes = get_num_output_volumes;
+ Px->GetOutputVolumeName = get_output_volume_name;
+ Px->GetOutputVolume = get_output_volume;
+ Px->SetOutputVolume = set_output_volume;
+ Px->GetNumInputSources = get_num_input_sources;
+ Px->GetInputSourceName = get_input_source_name;
+ Px->GetCurrentInputSource = get_current_input_source;
+ Px->SetCurrentInputSource = set_current_input_source;
+ Px->GetInputVolume = get_input_volume;
+ Px->SetInputVolume = set_input_volume;
+
+// Px->SupportsOutputBalance = supports_output_balance;
+// Px->GetOutputBalance = get_output_balance;
+// Px->SetOutputBalance = set_output_balance;
+
+// Px->SupportsPlaythrough = supports_play_through;
+// Px->GetPlaythrough = get_play_through;
+// Px->SetPlaythrough = set_play_through;
+
+ return TRUE;
+}
+
+static int cleanup(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int i;
+
+ if (info) {
+ if (info->hInputMixer) {
+ mixerClose((HMIXER) info->hInputMixer);
+ }
+
+ if (info->hOutputMixer) {
+ mixerClose((HMIXER) info->hOutputMixer);
+ }
+
+ if (info->inName) {
+ free(info->inName);
+ }
+
+ if (info->outName) {
+ free(info->outName);
+ }
+
+ if (info->src) {
+ for (i = 0; i < info->numInputs; i++) {
+ if (info->src[i].name) {
+ free(info->src[i].name);
+ }
+ }
+
+ free(info->src);
+ }
+
+ if (info->dst) {
+ for (i = 0; i < info->numOutputs; i++) {
+ if (info->dst[i].name) {
+ free(info->dst[i].name);
+ }
+ }
+
+ free(info->dst);
+ }
+
+ free(info);
+ Px->info = NULL;
+ }
+
+ return FALSE;
+}
+
+static void close_mixer(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ cleanup(Px);
+}
+
+static int get_num_mixers(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return (info->hInputMixer != NULL) + (info->hOutputMixer != NULL);
+}
+
+static const char *get_mixer_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ MIXERCAPS caps;
+ MMRESULT res;
+
+ if (i > 1) {
+ return NULL;
+ }
+
+ if (i == 0) {
+ if (!info->inName) {
+ res = mixerGetDevCaps((UINT) info->hInputMixer, &caps, sizeof(caps));
+ if (res == MMSYSERR_NOERROR) {
+ info->inName = strdup(caps.szPname);
+ }
+ }
+ return info->inName;
+ }
+
+ if (!info->outName) {
+ res = mixerGetDevCaps((UINT) info->hOutputMixer, &caps, sizeof(caps));
+ if (res == MMSYSERR_NOERROR) {
+ info->outName = strdup(caps.szPname);
+ }
+ }
+
+ return info->outName;
+}
+
+static PxVolume VolumeFunction(HMIXEROBJ hMixer, DWORD controlID, PxVolume volume)
+{
+ MIXERCONTROLDETAILS details;
+ MMRESULT result;
+ MIXERCONTROLDETAILS_UNSIGNED value;
+
+ if (hMixer == NULL) {
+ return -1.0;
+ }
+
+ memset(&value, 0, sizeof(MIXERCONTROLDETAILS_UNSIGNED));
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = controlID;
+ details.cChannels = 1; /* all channels */
+ details.cMultipleItems = 0;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
+ details.paDetails = &value;
+
+ if (volume < 0.0) {
+ result = mixerGetControlDetails(hMixer,
+ &details,
+ MIXER_GETCONTROLDETAILSF_VALUE);
+ if (result != MMSYSERR_NOERROR)
+ return -1.0;
+
+ return (PxVolume)(value.dwValue / 65535.0);
+ }
+
+ value.dwValue = (unsigned short)(volume * 65535.0);
+ result = mixerSetControlDetails(hMixer,
+ &details,
+ MIXER_GETCONTROLDETAILSF_VALUE);
+
+ if (result != MMSYSERR_NOERROR)
+ return -1.0;
+
+ return 0.0;
+}
+
+static PxVolume get_master_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return VolumeFunction(info->hOutputMixer, info->speakerID, -1.0);
+}
+
+static void set_master_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ VolumeFunction(info->hOutputMixer, info->speakerID, volume);
+
+ return;
+}
+
+/*
+|| Main output volume
+*/
+
+static int supports_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return (info->waveID != -1);
+}
+
+static PxVolume get_pcm_output_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return VolumeFunction(info->hOutputMixer, info->waveID, -1.0);
+}
+
+static void set_pcm_output_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ VolumeFunction(info->hOutputMixer, info->waveID, volume);
+
+ return;
+}
+
+/*
+|| Output info
+*/
+
+static int get_num_output_volumes(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return info->numOutputs;
+}
+
+static const char *get_output_volume_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (i < info->numOutputs) {
+ return info->dst[i].name;
+ }
+
+ return NULL;
+}
+
+/*
+|| Output volume
+*/
+
+static PxVolume get_output_volume(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (i < info->numOutputs) {
+ return VolumeFunction(info->hOutputMixer,
+ info->src[i].controlID,
+ -1.0);
+ }
+
+ return -1.0;
+}
+
+static void set_output_volume(px_mixer *Px, int i, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (i < info->numOutputs) {
+ VolumeFunction(info->hOutputMixer,
+ info->src[i].controlID,
+ volume);
+ }
+
+ return;
+}
+
+/*
+|| Input source
+*/
+
+static int get_num_input_sources(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ return info->numInputs;
+}
+
+static const char *get_input_source_name(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+
+ if (i < info->numInputs) {
+ return info->src[i].name;
+ }
+
+ return NULL;
+}
+
+static int get_current_input_source(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ MIXERCONTROLDETAILS details;
+ MIXERCONTROLDETAILS_LISTTEXT *list;
+ MIXERCONTROLDETAILS_BOOLEAN *flags;
+ MMRESULT res;
+ int i = -1;
+ int j;
+
+ if (!info->hInputMixer) {
+ return -1;
+ }
+
+ do {
+ list = calloc(info->numInputs, sizeof(MIXERCONTROLDETAILS_LISTTEXT));
+ flags = calloc(info->numInputs, sizeof(MIXERCONTROLDETAILS_BOOLEAN));
+ if (list == NULL || flags == NULL) {
+ break;
+ }
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = info->muxID;
+ details.cMultipleItems = info->numInputs;
+ details.cChannels = 1;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
+ details.paDetails = &list[0];
+
+ res = mixerGetControlDetails(info->hInputMixer,
+ &details,
+ MIXER_GETCONTROLDETAILSF_LISTTEXT);
+
+ if (res != MMSYSERR_NOERROR) {
+ break;
+ }
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = info->muxID;
+ details.cMultipleItems = info->numInputs;
+ details.cChannels = 1;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
+ details.paDetails = &flags[0];
+
+ res = mixerGetControlDetails(info->hInputMixer,
+ &details,
+ MIXER_SETCONTROLDETAILSF_VALUE);
+
+ if (res != MMSYSERR_NOERROR) {
+ break;
+ }
+
+ for (j = 0; j < info->numInputs; j++) {
+ if (flags[j].fValue) {
+ i = j;
+ break;
+ }
+ }
+
+ for (j = 0; j < info->numInputs; j++) {
+ if (info->src[j].lineID == list[i].dwParam1 ) {
+ i = j;
+ break;
+ }
+ }
+
+ } while(FALSE);
+
+ if (list) {
+ free(list);
+ }
+
+ if (flags) {
+ free(flags);
+ }
+
+ return i;
+}
+
+static void set_current_input_source(px_mixer *Px, int i)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ MIXERCONTROLDETAILS details;
+ MIXERCONTROLDETAILS_LISTTEXT *list;
+ MIXERCONTROLDETAILS_BOOLEAN *flags;
+ MMRESULT res;
+ int j;
+
+ if (!info->hInputMixer) {
+ return;
+ }
+
+ do {
+ list = calloc(info->numInputs, sizeof(MIXERCONTROLDETAILS_LISTTEXT));
+ flags = calloc(info->numInputs, sizeof(MIXERCONTROLDETAILS_BOOLEAN));
+ if (list == NULL || flags == NULL) {
+ break;
+ }
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = info->muxID;
+ details.cMultipleItems = info->numInputs;
+ details.cChannels = 1;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
+ details.paDetails = &list[0];
+
+ res = mixerGetControlDetails(info->hInputMixer,
+ &details,
+ MIXER_GETCONTROLDETAILSF_LISTTEXT);
+
+ if (res != MMSYSERR_NOERROR) {
+ break;
+ }
+
+ for (j = 0; j < info->numInputs; j++) {
+ if (list[j].dwParam1 == info->src[i].lineID) {
+ flags[j].fValue = TRUE;
+ break;
+ }
+ }
+
+ details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ details.dwControlID = info->muxID;
+ details.cMultipleItems = info->numInputs;
+ details.cChannels = 1;
+ details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
+ details.paDetails = &flags[0];
+
+ res = mixerSetControlDetails(info->hInputMixer,
+ &details,
+ MIXER_SETCONTROLDETAILSF_VALUE);
+
+ if (res != MMSYSERR_NOERROR) {
+ break;
+ }
+ } while(FALSE);
+
+ if (list) {
+ free(list);
+ }
+
+ if (flags) {
+ free(flags);
+ }
+
+ return;
+}
+
+/*
+|| Input volume
+*/
+
+static PxVolume get_input_volume(px_mixer *Px)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int src;
+
+ if (info->hInputMixer) {
+ src = get_current_input_source(Px);
+ if (src < info->numInputs) {
+ return VolumeFunction(info->hInputMixer,
+ info->src[src].controlID,
+ -1.0);
+ }
+ }
+
+ return -1.0;
+}
+
+static void set_input_volume(px_mixer *Px, PxVolume volume)
+{
+ PxInfo *info = (PxInfo *)Px->info;
+ int src;
+
+ if (info->hInputMixer) {
+ src = get_current_input_source(Px);
+ if (src < info->numInputs) {
+ VolumeFunction(info->hInputMixer,
+ info->src[src].controlID,
+ volume);
+ }
+ }
+
+ return;
+}
Added: freeswitch/branches/cseket/libs/portmixer/src/px_win_common.h
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_win_common.h Fri Aug 24 13:53:53 2007
@@ -0,0 +1,75 @@
+#ifndef PX_WIN_COMMON_H
+#define PX_WIN_COMMON_H
+/*
+ * PortMixer
+ * Windows Common Header
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+typedef struct PxCtrl
+{
+ char *name;
+ DWORD lineID;
+ DWORD controlID;
+} PxCtrl;
+
+typedef struct PxInfo
+{
+ HMIXEROBJ hInputMixer;
+ char *inName;
+ int numInputs;
+ PxCtrl *src;
+
+ HMIXEROBJ hOutputMixer;
+ char *outName;
+ int numOutputs;
+ PxCtrl *dst;
+
+ DWORD muxID;
+ DWORD speakerID;
+ DWORD waveID;
+} PxInfo;
+
+int open_mixers(px_mixer *Px, UINT deviceIn, UINT deviceOut);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Added: freeswitch/branches/cseket/libs/portmixer/src/px_win_ds.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_win_ds.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,179 @@
+/*
+ * PortMixer
+ * Windows DirectSound Implementation
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni and Augustus Saunders
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+#define COBJMACROS
+#define DIRECTSOUND_VERSION 0x0300
+
+#include <windows.h>
+#include <dsound.h>
+#include <dsconf.h>
+#include <objbase.h>
+#include <unknwn.h>
+
+#include "portaudio.h"
+#include "pa_win_ds.h"
+
+#include "portmixer.h"
+#include "px_mixer.h"
+#include "px_win_common.h"
+
+const GUID FAR DSPROPSETID_DirectSoundDevice =
+{0x84624f82, 0x25ec, 0x11d1, {0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca}};
+
+const GUID FAR CLSID_DirectSoundPrivate =
+{0x11ab3ec0, 0x25ec, 0x11d1, {0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca}};
+
+typedef HRESULT (CALLBACK *GCO) (REFCLSID, REFIID, LPVOID *);
+
+#if defined(_DEBUG)
+#include <stdio.h>
+static void dprintf(const char *format, ...)
+{
+ char buf[4096];
+ va_list args;
+ int cnt;
+
+ va_start(args, format);
+ cnt = _vsnprintf(buf, sizeof(buf) - 1, format, args);
+ va_end(args);
+
+ if (cnt > 0) {
+ buf[cnt] = '\0';
+ OutputDebugString(buf);
+ }
+}
+#endif
+
+int OpenMixer_Win_DirectSound(px_mixer *Px, int index)
+{
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA desc;
+ HMODULE hDsound = INVALID_HANDLE_VALUE;
+ GCO DllGetClassObject;
+ IClassFactory *pcf = NULL;
+ IKsPropertySet *pps = NULL;
+ HRESULT hr;
+ ULONG bytes;
+ LPGUID guidIn;
+ LPGUID guidOut;
+ UINT deviceIn = -1;
+ UINT deviceOut = -1;
+
+ guidIn = PaWinDS_GetStreamInputGUID(Px->pa_stream);
+ guidOut = PaWinDS_GetStreamOutputGUID(Px->pa_stream);
+
+ do {
+ hDsound = LoadLibrary("dsound.dll");
+ if (hDsound == NULL) {
+ break;
+ }
+
+ DllGetClassObject = (GCO) GetProcAddress(hDsound, "DllGetClassObject");
+ if (DllGetClassObject == NULL) {
+ break;
+ }
+
+ hr = DllGetClassObject(&CLSID_DirectSoundPrivate,
+ &IID_IClassFactory,
+ (void **)(&pcf));
+ if (hr || pcf == NULL) {
+ break;
+ }
+
+ hr = IClassFactory_CreateInstance(pcf,
+ NULL,
+ &IID_IKsPropertySet,
+ (void **)(&pps));
+ if (hr || pps == NULL) {
+ break;
+ }
+
+ if (guidIn) {
+ memcpy(&desc.DeviceId, guidIn, sizeof(desc.DeviceId));
+ desc.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
+ hr = IKsPropertySet_Get(pps,
+ &DSPROPSETID_DirectSoundDevice,
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION,
+ NULL,
+ 0,
+ &desc,
+ sizeof(desc),
+ &bytes);
+ if (FAILED(hr)) {
+ break;
+ }
+
+ deviceIn = desc.WaveDeviceId;
+ }
+
+ if (guidOut) {
+ memcpy(&desc.DeviceId, guidOut, sizeof(desc.DeviceId));
+ desc.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
+ hr = IKsPropertySet_Get(pps,
+ &DSPROPSETID_DirectSoundDevice,
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION,
+ NULL,
+ 0,
+ &desc,
+ sizeof(desc),
+ &bytes);
+ if (FAILED(hr)) {
+ break;
+ }
+
+ deviceOut = desc.WaveDeviceId;
+ }
+
+ if (open_mixers(Px, deviceIn, deviceOut))
+ {
+ return TRUE;
+ }
+ } while( FALSE );
+
+ if (pps) {
+ IUnknown_Release(pps);
+ }
+
+ if (pcf) {
+ IUnknown_Release(pcf);
+ }
+
+ if (hDsound != INVALID_HANDLE_VALUE) {
+ FreeLibrary(hDsound);
+ }
+
+ return FALSE;
+}
Added: freeswitch/branches/cseket/libs/portmixer/src/px_win_wmme.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/src/px_win_wmme.c Fri Aug 24 13:53:53 2007
@@ -0,0 +1,82 @@
+/*
+ * PortMixer
+ * Windows WMME Implementation
+ *
+ * Copyright (c) 2002, 2006
+ *
+ * Written by Dominic Mazzoni and Augustus Saunders
+ * and Leland Lucius
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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.
+ *
+ */
+
+#include <windows.h>
+
+#include "portaudio.h"
+#include "pa_win_wmme.h"
+
+#include "portmixer.h"
+#include "px_mixer.h"
+#include "px_win_common.h"
+
+int OpenMixer_Win_MME(px_mixer *Px, int index)
+{
+ HWAVEIN hWaveIn;
+ HWAVEOUT hWaveOut;
+ MMRESULT res;
+ UINT deviceIn = UINT_MAX;
+ UINT deviceOut = UINT_MAX;
+
+ hWaveIn = PaWinMME_GetStreamInputHandle(Px->pa_stream, 0);
+ hWaveOut = PaWinMME_GetStreamOutputHandle(Px->pa_stream, 0);
+
+ if (hWaveIn) {
+ res = mixerGetID((HMIXEROBJ) hWaveIn,
+ &deviceIn,
+ MIXER_OBJECTF_HWAVEIN);
+ if (res != MMSYSERR_NOERROR) {
+ return FALSE;
+ }
+ }
+
+ if (hWaveOut) {
+ res = mixerGetID((HMIXEROBJ) hWaveOut,
+ &deviceOut,
+ MIXER_OBJECTF_HWAVEOUT);
+ if (res != MMSYSERR_NOERROR) {
+ return FALSE;
+ }
+ }
+
+ if (open_mixers(Px, deviceIn, deviceOut)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
Added: freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Entries Fri Aug 24 13:53:53 2007
@@ -0,0 +1,2 @@
+/portmixer.vcproj/1.13/Mon Jun 18 16:10:53 2007//
+D
Added: freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Repository Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+lib-src/portmixer/winproj
Added: freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/winproj/CVS/Root Fri Aug 24 13:53:53 2007
@@ -0,0 +1 @@
+:pserver:anonymous@audacity.cvs.sourceforge.net:/cvsroot/audacity
Added: freeswitch/branches/cseket/libs/portmixer/winproj/portmixer.vcproj
==============================================================================
--- (empty file)
+++ freeswitch/branches/cseket/libs/portmixer/winproj/portmixer.vcproj Fri Aug 24 13:53:53 2007
@@ -0,0 +1,582 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="portmixer"
+ ProjectGUID="{3A76129B-55AB-4D54-BAA7-08F63ED52569}"
+ RootNamespace="portmixer"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\$(ConfigurationName)"
+ IntermediateDirectory=".\$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF NOT "%DXSDK_DIR%" == "" echo #define PX_USE_WIN_DSOUND 1 >>".\$(ConfigurationName)\config.h"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/O2"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\include;"..\..\portaudio-v19\include""
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;PX_USE_WIN_MME"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+ AssemblerListingLocation=".\$(ConfigurationName)/"
+ ObjectFile=".\$(ConfigurationName)/"
+ ProgramDataBaseFileName=".\$(ConfigurationName)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\portmixer.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl /O2 /Ob1 /I "..\..\portaudio-v19\include" /I "..\include" /I"%DXSDK_DIR%include" /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_MBCS" /GF /FD /EHsc /MT /Gy /Fo".\$(OutDir)/" /Fd".\$(OutDir)/" /W3 /c /wd4996 "..\src\px_win_ds.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\$(ConfigurationName)"
+ IntermediateDirectory=".\$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF NOT "%DXSDK_DIR%" == "" echo #define PX_USE_WIN_DSOUND 1 >>".\$(ConfigurationName)\config.h"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include;"..\..\portaudio-v19\include""
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;PX_USE_WIN_MME"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+ AssemblerListingLocation=".\$(ConfigurationName)/"
+ ObjectFile=".\$(ConfigurationName)/"
+ ProgramDataBaseFileName=".\$(ConfigurationName)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\portmixerd.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl /Od /I "..\..\portaudio-v19\include" /I "..\include" /I"%DXSDK_DIR%include" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_MBCS" /FD /EHsc /RTC1 /MTd /Fo".\$(OutDir)/" /Fd".\$(OutDir)/" /W3 /c /ZI /wd4996 "..\src\px_win_ds.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
+ />
+ </Configuration>
+ <Configuration
+ Name="Unicode_Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF NOT "%DXSDK_DIR%" == "" echo #define PX_USE_WIN_DSOUND 1 >>".\$(ConfigurationName)\config.h"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include;"..\..\portaudio-v19\include""
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;PX_USE_WIN_MME"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+ AssemblerListingLocation=".\$(ConfigurationName)/"
+ ObjectFile=".\$(ConfigurationName)/"
+ ProgramDataBaseFileName=".\$(ConfigurationName)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\portmixerud.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl /Od /I "..\..\portaudio-v19\include" /I "..\include" /I"%DXSDK_DIR%include" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_MBCS" /FD /EHsc /RTC1 /MTd /Fo".\$(OutDir)/" /Fd".\$(OutDir)/" /W3 /c /ZI /wd4996 "..\src\px_win_ds.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
+ />
+ </Configuration>
+ <Configuration
+ Name="Unicode_Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF NOT "%DXSDK_DIR%" == "" echo #define PX_USE_WIN_DSOUND 1 >>".\$(ConfigurationName)\config.h"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/O2"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\include;"..\..\portaudio-v19\include""
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;PX_USE_WIN_MME"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+ AssemblerListingLocation=".\$(ConfigurationName)/"
+ ObjectFile=".\$(ConfigurationName)/"
+ ProgramDataBaseFileName=".\$(ConfigurationName)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\portmixeru.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl /O2 /Ob1 /I "..\..\portaudio-v19\include" /I "..\include" /I"%DXSDK_DIR%include" /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_MBCS" /GF /FD /EHsc /MT /Gy /Fo".\$(OutDir)/" /Fd".\$(OutDir)/" /W3 /c /wd4996 "..\src\px_win_ds.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug DLL|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF NOT "%DXSDK_DIR%" == "" echo #define PX_USE_WIN_DSOUND 1 >>".\$(ConfigurationName)\config.h"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include;"..\..\portaudio-v19\include""
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;PX_USE_WIN_MME"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+ AssemblerListingLocation=".\$(ConfigurationName)/"
+ ObjectFile=".\$(ConfigurationName)/"
+ ProgramDataBaseFileName=".\$(ConfigurationName)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\portmixerd.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl /Od /I "..\..\portaudio-v19\include" /I "..\include" /I"%DXSDK_DIR%include" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_MBCS" /FD /EHsc /RTC1 /MTd /Fo".\$(OutDir)/" /Fd".\$(OutDir)/" /W3 /c /ZI /wd4996 "..\src\px_win_ds.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug wx284|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine="echo // Automatically generated file >".\$(ConfigurationName)\config.h"
IF NOT "%DXSDK_DIR%" == "" echo #define PX_USE_WIN_DSOUND 1 >>".\$(ConfigurationName)\config.h"
"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include;"..\..\portaudio-v19\include""
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;PX_USE_WIN_MME"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+ AssemblerListingLocation=".\$(ConfigurationName)/"
+ ObjectFile=".\$(ConfigurationName)/"
+ ProgramDataBaseFileName=".\$(ConfigurationName)/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ ForcedIncludeFiles="$(ProjectDir)\$(ConfigurationName)\config.h"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=".\portmixerd.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="set LIBS=

if "%DXSDK_DIR%"=="" goto NoDX

cl /Od /I "..\..\portaudio-v19\include" /I "..\include" /I"%DXSDK_DIR%include" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "_MBCS" /FD /EHsc /RTC1 /MTd /Fo".\$(OutDir)/" /Fd".\$(OutDir)/" /W3 /c /ZI /wd4996 "..\src\px_win_ds.c"

set LIBS="%DXSDK_DIR%lib\x86\dxguid.lib"

:NoDX

lib /OUT:"$(TargetPath)" ".\$(OutDir)\*.obj" %LIBS%
"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\src\px_mixer.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\px_mixer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\px_win_common.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\px_win_common.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\px_win_ds.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode_Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode_Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug DLL|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug wx284|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\src\px_win_wmme.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="..\include\portmixer.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
1
0
[Freeswitch-branches] [commit] r5662 - freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio
by Freeswitch SVN 24 Aug '07
by Freeswitch SVN 24 Aug '07
24 Aug '07
Author: cseket
Date: Fri Aug 24 13:50:56 2007
New Revision: 5662
Modified:
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/ (props changed)
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c
freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h
Log:
merge from trunk and try to fix MODENDP-20
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/Makefile Fri Aug 24 13:50:56 2007
@@ -1,22 +1,29 @@
-CFLAGS += -I.
-LDFLAGS += -lportaudio -L$(PREFIX)
-MYOBJS = pablio.o pa_ringbuffer.o
+BASE=../../../..
-all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
+PA_DIR=$(BASE)/libs/portaudio
-depends:
- MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install portaudio --prefix=$(PREFIX) --with-pic
-%.o: %.c
- $(CC) -fPIC $(CFLAGS) -c -o $@ $<
+PALA=$(PA_DIR)/lib/libportaudio.la
+LOCAL_CFLAGS=-I. -I$(PA_DIR)/include -D__EXTENSION__=1
-$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c $(MYOBJS)
- $(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o
- $(CC) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(MODNAME).o $(MYOBJS) $(LDFLAGS)
+LOCAL_INSERT_LDFLAGS=if test $$osarch = "Darwin" ; then echo "-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon" ; fi ;
+LOCAL_LIBADD=$(PALA)
+LOCAL_OBJS=pablio.o pa_ringbuffer.o
+LOCAL_SOURCES=pablio.c pa_ringbuffer.c
+PX_DIR=$(BASE)/libs/portmixer
+PXA=$(PX_DIR)/libportmixer.a
+LOCAL_CFLAGS+=-I$(PX_DIR)/include
+LOCAL_LIBADD+=$(PXA)
-clean:
- rm -fr *.$(DYNAMIC_LIB_EXTEN) *.o *~
+include $(BASE)/build/modmake.rules
-install:
- cp -f $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(PREFIX)/mod
+$(PALA): $(PA_DIR) $(PA_DIR)/.update
+ cd $(PA_DIR) && $(MAKE)
+ $(TOUCH_TARGET)
+
+$(PXA): $(PX_DIR) $(PX_DIR)/.update
+ cd $(PX_DIR) && $(MAKE)
+ $(TOUCH_TARGET)
+
+$(LOCAL_OBJS): $(LOCAL_SOURCES)
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/mod_portaudio.c Fri Aug 24 13:50:56 2007
@@ -6,7 +6,7 @@
*
* 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
+ * the License. You may obtain a copy of the License `
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
@@ -29,32 +29,34 @@
* mod_portaudio.c -- PortAudio Endpoint Module
*
*/
-#include <switch.h>
+#include "switch.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "pablio.h"
#include <string.h>
+#include <portmixer.h>
#define MY_EVENT_RINGING "portaudio::ringing"
-static const char modname[] = "mod_portaudio";
+SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown);
+SWITCH_MODULE_DEFINITION(mod_portaudio, mod_portaudio_load, mod_portaudio_shutdown, NULL);
static switch_memory_pool_t *module_pool = NULL;
-//static int running = 1;
+static switch_endpoint_interface_t *channel_endpoint_interface;
#define SAMPLE_TYPE paInt16
-//#define SAMPLE_TYPE paFloat32
-typedef short SAMPLE;
+typedef int16_t SAMPLE;
-typedef switch_status_t (*pa_command_t)(char **argv, int argc, switch_stream_handle_t *stream);
+typedef switch_status_t (*pa_command_t) (char **argv, int argc, switch_stream_handle_t *stream);
typedef enum {
- GFLAG_NONE = 0,
- GFLAG_EAR = (1 << 0),
- GFLAG_MOUTH = (1 << 1),
- GFLAG_RING = (1 << 2)
+ GFLAG_NONE = 0,
+ GFLAG_EAR = (1 << 0),
+ GFLAG_MOUTH = (1 << 1),
+ GFLAG_RING = (1 << 2)
} GFLAGS;
typedef enum {
@@ -75,17 +77,16 @@
switch_core_session_t *session;
switch_caller_profile_t *caller_profile;
char call_id[50];
- int sample_rate;
- int codec_ms;
+ int sample_rate;
+ int codec_ms;
switch_mutex_t *flag_mutex;
- char *hold_file;
- switch_file_handle_t fh;
- switch_file_handle_t *hfh;
+ char *hold_file;
+ switch_file_handle_t fh;
+ switch_file_handle_t *hfh;
switch_frame_t hold_frame;
- unsigned char holdbuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
+ unsigned char holdbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_codec_t write_codec;
- switch_timer_t timer;
- struct private_object *next;
+ struct private_object *next;
};
typedef struct private_object private_t;
@@ -96,9 +97,9 @@
char *cid_name;
char *cid_num;
char *dialplan;
- char *ring_file;
- char *hold_file;
- char *timer_name;
+ char *ring_file;
+ char *hold_file;
+ char *timer_name;
int ringdev;
int indev;
int outdev;
@@ -114,12 +115,14 @@
switch_codec_t read_codec;
switch_codec_t write_codec;
switch_frame_t read_frame;
- switch_frame_t cng_frame;
- unsigned char databuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
- unsigned char cngbuf[SWITCH_RECCOMMENDED_BUFFER_SIZE];
- private_t *call_list;
- int ring_interval;
- GFLAGS flags;
+ switch_frame_t cng_frame;
+ unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+ unsigned char cngbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+ private_t *call_list;
+ int ring_interval;
+ GFLAGS flags;
+ switch_timer_t timer;
+ PxMixer *mixer;
} globals;
@@ -128,126 +131,125 @@
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_name, globals.cid_name)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_num, globals.cid_num)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ring_file, globals.ring_file)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_hold_file, globals.hold_file)
-SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_timer_name, globals.timer_name)
-
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_name, globals.cid_name)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_cid_num, globals.cid_num)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ring_file, globals.ring_file)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_hold_file, globals.hold_file)
+ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_timer_name, globals.timer_name)
#define is_master(t) switch_test_flag(t, TFLAG_MASTER)
-static void add_pvt(private_t *tech_pvt, int master);
-static void remove_pvt(private_t *tech_pvt);
-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_ring(switch_core_session_t *session);
-static switch_status_t channel_on_loopback(switch_core_session_t *session);
-static switch_status_t channel_on_transmit(switch_core_session_t *session);
-static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
- switch_caller_profile_t *outbound_profile,
- switch_core_session_t **new_session, switch_memory_pool_t **pool);
-static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
- switch_io_flag_t flags, int stream_id);
-static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
- switch_io_flag_t flags, int stream_id);
-static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
-static switch_status_t engage_device(int samplerate, int codec_ms);
-static switch_status_t engage_ring_device(int sample_rate, int channels);
-static void deactivate_ring_device(void);
-static int dump_info(void);
-static switch_status_t load_config(void);
-static int get_dev_by_name(char *name, int in);
-static int get_dev_by_number(int number, int in);
-static switch_status_t pa_cmd(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
-static switch_status_t padep(char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
-
+ static void add_pvt(private_t * tech_pvt, int master);
+ static void remove_pvt(private_t * tech_pvt);
+ 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_ring(switch_core_session_t *session);
+ static switch_status_t channel_on_loopback(switch_core_session_t *session);
+ static switch_status_t channel_on_transmit(switch_core_session_t *session);
+ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
+ switch_caller_profile_t *outbound_profile,
+ switch_core_session_t **new_session, switch_memory_pool_t **pool);
+ static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id);
+ static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id);
+ static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
+ static switch_status_t engage_device(int samplerate, int codec_ms);
+ static switch_status_t engage_ring_device(int sample_rate, int channels);
+ static void deactivate_ring_device(void);
+ static int dump_info(void);
+ static switch_status_t load_config(void);
+ static int get_dev_by_name(char *name, int in);
+ static int get_dev_by_number(int number, int in);
+ static switch_status_t pa_cmd(const char *dest, switch_core_session_t *session, switch_stream_handle_t *stream);
/*
State methods they get called when the state changes to the specific state
returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
*/
-static switch_status_t channel_on_init(switch_core_session_t *session)
+ static switch_status_t channel_on_init(switch_core_session_t *session)
{
switch_channel_t *channel;
private_t *tech_pvt = NULL;
switch_time_t last;
int waitsec = globals.ring_interval * 1000000;
- switch_file_handle_t fh = {0};
- char *val, *ring_file = NULL, *hold_file = NULL;
- int16_t abuf[2048];
+ switch_file_handle_t fh = { 0 };
+ char *val, *ring_file = NULL, *hold_file = NULL;
+ int16_t abuf[2048];
- tech_pvt = switch_core_session_get_private(session);
+ tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
-
+
last = switch_time_now() - waitsec;
- if ((val = switch_channel_get_variable(channel, "pa_hold_file"))) {
- hold_file = val;
- } else {
- hold_file = globals.hold_file;
- }
-
- if (hold_file) {
- tech_pvt->hold_file = switch_core_session_strdup(session, hold_file);
- }
+
+ if ((val = switch_channel_get_variable(channel, "pa_hold_file"))) {
+ hold_file = val;
+ } else {
+ hold_file = globals.hold_file;
+ }
+
+ if (hold_file) {
+ tech_pvt->hold_file = switch_core_session_strdup(session, hold_file);
+ }
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n", switch_channel_get_name(channel),
- switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER));
-
-
-
- if (engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms) != SWITCH_STATUS_SUCCESS) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- return SWITCH_STATUS_FALSE;
- }
-
- if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- add_pvt(tech_pvt, PA_SLAVE);
-
- ring_file = globals.ring_file;
- if ((val = switch_channel_get_variable(channel, "pa_ring_file"))) {
- ring_file = val;
- }
-
- if (switch_test_flag((&globals), GFLAG_RING)) {
- ring_file = NULL;
- }
- switch_set_flag_locked((&globals), GFLAG_RING);
- if (ring_file) {
- if (switch_core_file_open(&fh,
- ring_file,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
- NULL) == SWITCH_STATUS_SUCCESS) {
-
- if (engage_ring_device(fh.samplerate, fh.channels) != SWITCH_STATUS_SUCCESS) {
- switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ring Error!\n");
- switch_core_file_close(&fh);
- return SWITCH_STATUS_GENERR;
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open %s, disabling ring file!\n", ring_file);
- ring_file = NULL;
- }
- }
- }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n",
+ switch_channel_get_name(channel), switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER));
+
+
+
+ if (engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
+ add_pvt(tech_pvt, PA_SLAVE);
+
+ ring_file = globals.ring_file;
+ if ((val = switch_channel_get_variable(channel, "pa_ring_file"))) {
+ ring_file = val;
+ }
+
+ if (switch_test_flag((&globals), GFLAG_RING)) {
+ ring_file = NULL;
+ }
+ switch_set_flag_locked((&globals), GFLAG_RING);
+ if (ring_file) {
+ if (switch_core_file_open(&fh,
+ ring_file,
+ globals.read_codec.implementation->number_of_channels,
+ globals.read_codec.implementation->samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
+
+ if (engage_ring_device(fh.samplerate, fh.channels) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ring Error!\n");
+ switch_core_file_close(&fh);
+ return SWITCH_STATUS_GENERR;
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open %s, disabling ring file!\n", ring_file);
+ ring_file = NULL;
+ }
+ }
+ }
switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
switch_channel_mark_ring_ready(channel);
-
+
while (switch_channel_get_state(channel) == CS_INIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
+ switch_size_t olen = globals.timer.samples;
+
if (switch_time_now() - last >= waitsec) {
char buf[512];
switch_event_t *event;
-
+
snprintf(buf, sizeof(buf), "BRRRRING! BRRRRING! call %s\n", tech_pvt->call_id);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) {
@@ -256,49 +258,46 @@
switch_channel_event_set_data(channel, event);
switch_event_fire(&event);
}
-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", buf);
last = switch_time_now();
- if (ring_file) {
- unsigned int pos = 0;
- switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
- for (;;) {
- switch_size_t olen = 1024;
- switch_core_file_read(&fh, abuf, &olen);
- if (olen == 0) {
- break;
- }
- WriteAudioStream(globals.ring_stream, abuf, (long)olen);
- }
- }
- }
-
- switch_yield(globals.read_codec.implementation->microseconds_per_frame);
-
- }
- switch_clear_flag_locked((&globals), GFLAG_RING);
- }
-
- if (ring_file) {
- deactivate_ring_device();
- switch_core_file_close(&fh);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- switch_core_timer_destroy(&tech_pvt->timer);
- }
+ }
+
+ if (ring_file) {
+ if (switch_core_timer_next(&globals.timer) != SWITCH_STATUS_SUCCESS) {
+ switch_core_file_close(&fh);
+ break;
+ }
+ switch_core_file_read(&fh, abuf, &olen);
+ if (olen == 0) {
+ unsigned int pos = 0;
+ switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
+ }
+ if (globals.ring_stream) {
+ WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.timer);
+ }
+ }
+ }
+ switch_clear_flag_locked((&globals), GFLAG_RING);
+ }
+
+ if (ring_file) {
+ deactivate_ring_device();
+ switch_core_file_close(&fh);
+ }
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- if (!switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
- switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER);
- return SWITCH_STATUS_SUCCESS;
- }
+ if (!switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER);
+ return SWITCH_STATUS_SUCCESS;
+ }
}
- switch_set_flag_locked(tech_pvt, TFLAG_IO);
-
- /* Move Channel's State Machine to RING */
- switch_channel_set_state(channel, CS_RING);
-
- return SWITCH_STATUS_SUCCESS;
+ switch_set_flag_locked(tech_pvt, TFLAG_IO);
+
+ /* Move Channel's State Machine to RING */
+ switch_channel_set_state(channel, CS_RING);
+
+ return SWITCH_STATUS_SUCCESS;
}
@@ -344,6 +343,11 @@
globals.audio_stream = NULL;
}
switch_mutex_unlock(globals.device_lock);
+ if (globals.mixer) {
+ Px_CloseMixer(globals.mixer);
+ globals.mixer = NULL;
+ }
+
}
@@ -359,72 +363,72 @@
-static void add_pvt(private_t *tech_pvt, int master)
+static void add_pvt(private_t * tech_pvt, int master)
{
- private_t *tp;
- uint8_t in_list = 0;
+ private_t *tp;
+ uint8_t in_list = 0;
+
+ switch_mutex_lock(globals.pvt_lock);
+
+ if (switch_strlen_zero(tech_pvt->call_id)) {
+ snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id);
+ switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
+ switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec);
+ switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec);
+ }
+
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ if (tp == tech_pvt) {
+ in_list = 1;
+ }
+ if (master) {
+ switch_clear_flag_locked(tp, TFLAG_MASTER);
+ }
+ }
- switch_mutex_lock(globals.pvt_lock);
- if (switch_strlen_zero(tech_pvt->call_id)) {
- snprintf(tech_pvt->call_id, sizeof(tech_pvt->call_id), "%d", ++globals.call_id);
- switch_core_hash_insert(globals.call_hash, tech_pvt->call_id, tech_pvt);
- switch_core_session_set_read_codec(tech_pvt->session, &globals.read_codec);
- switch_core_session_set_write_codec(tech_pvt->session, &globals.write_codec);
- }
-
- for (tp = globals.call_list; tp; tp = tp->next) {
- if (tp == tech_pvt) {
- in_list = 1;
- }
- if (master) {
- switch_clear_flag_locked(tp, TFLAG_MASTER);
- }
- }
-
-
- if (master) {
- if (!in_list) {
- tech_pvt->next = globals.call_list;
- globals.call_list = tech_pvt;
- }
- switch_set_flag_locked(tech_pvt, TFLAG_MASTER);
-
- } else if (!in_list) {
- for (tp = globals.call_list; tp && tp->next; tp = tp->next);
- if (tp) {
- tp->next = tech_pvt;
- } else {
- globals.call_list = tech_pvt;
- }
- }
+ if (master) {
+ if (!in_list) {
+ tech_pvt->next = globals.call_list;
+ globals.call_list = tech_pvt;
+ }
+ switch_set_flag_locked(tech_pvt, TFLAG_MASTER);
+
+ } else if (!in_list) {
+ for (tp = globals.call_list; tp && tp->next; tp = tp->next);
+ if (tp) {
+ tp->next = tech_pvt;
+ } else {
+ globals.call_list = tech_pvt;
+ }
+ }
switch_mutex_unlock(globals.pvt_lock);
}
-static void remove_pvt(private_t *tech_pvt)
+static void remove_pvt(private_t * tech_pvt)
{
- private_t *tp, *last = NULL;
+ private_t *tp, *last = NULL;
switch_mutex_lock(globals.pvt_lock);
- for (tp = globals.call_list; tp; tp = tp->next) {
- switch_clear_flag_locked(tp, TFLAG_MASTER);
- if (tp == tech_pvt) {
- if (last) {
- last->next = tp->next;
- } else {
- globals.call_list = tp->next;
- }
- }
- last = tp;
- }
-
- if (globals.call_list) {
- switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No more channels, deactivating audio\n");
- deactivate_audio_device();
- }
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ switch_clear_flag_locked(tp, TFLAG_MASTER);
+ if (tp == tech_pvt) {
+ if (last) {
+ last->next = tp->next;
+ } else {
+ globals.call_list = tp->next;
+ }
+ }
+ last = tp;
+ }
+
+ if (globals.call_list) {
+ switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No more channels, deactivating audio\n");
+ deactivate_audio_device();
+ }
switch_mutex_unlock(globals.pvt_lock);
}
@@ -440,17 +444,17 @@
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
- remove_pvt(tech_pvt);
+ remove_pvt(tech_pvt);
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
switch_set_flag_locked(tech_pvt, TFLAG_HUP);
switch_core_hash_delete(globals.call_hash, tech_pvt->call_id);
- if (tech_pvt->hfh) {
- tech_pvt->hfh = NULL;
- switch_core_file_close(&tech_pvt->fh);
- }
+ if (tech_pvt->hfh) {
+ tech_pvt->hfh = NULL;
+ switch_core_file_close(&tech_pvt->fh);
+ }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
@@ -468,14 +472,14 @@
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
- switch (sig) {
- case SWITCH_SIG_KILL:
- switch_set_flag_locked(tech_pvt, TFLAG_HUP);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- break;
- default:
- break;
- }
+ switch (sig) {
+ case SWITCH_SIG_KILL:
+ switch_set_flag_locked(tech_pvt, TFLAG_HUP);
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ break;
+ default:
+ break;
+ }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
@@ -538,8 +542,7 @@
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout,
- switch_io_flag_t flags, int stream_id)
+static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id)
{
switch_channel_t *channel = NULL;
private_t *tech_pvt = NULL;
@@ -553,109 +556,90 @@
assert(tech_pvt != NULL);
if (!globals.audio_stream) {
- return SWITCH_STATUS_FALSE;
- }
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+ goto cng;
+ }
- if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
- goto cng;
- }
-
- if (!is_master(tech_pvt)) {
- if (tech_pvt->hold_file) {
- if (!tech_pvt->hfh) {
- int codec_ms = tech_pvt->codec_ms ? tech_pvt->codec_ms : globals.codec_ms;
- int sample_rate = tech_pvt->sample_rate ? tech_pvt->sample_rate : globals.sample_rate;
-
- if (switch_core_codec_init(&tech_pvt->write_codec,
- "L16",
- NULL,
- sample_rate,
- codec_ms,
- 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(&globals.read_codec);
- tech_pvt->hold_file = NULL;
- goto cng;
- }
-
- if (switch_core_file_open(&tech_pvt->fh,
- tech_pvt->hold_file,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_core_codec_destroy(&tech_pvt->write_codec);
- tech_pvt->hold_file = NULL;
- goto cng;
- }
-
- if (switch_core_timer_init(&tech_pvt->timer,
- globals.timer_name,
- codec_ms,
- globals.read_codec.implementation->samples_per_frame,
- switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
- switch_core_file_close(&tech_pvt->fh);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- goto cng;
- }
-
- tech_pvt->hfh = &tech_pvt->fh;
- tech_pvt->hold_frame.data = tech_pvt->holdbuf;
- tech_pvt->hold_frame.buflen = sizeof(tech_pvt->holdbuf);
- tech_pvt->hold_frame.rate = sample_rate;
- tech_pvt->hold_frame.codec = &tech_pvt->write_codec;
- }
-
- goto hold;
- }
- cng:
- switch_yield(globals.read_codec.implementation->microseconds_per_frame);
- *frame = &globals.cng_frame;
+ if (!is_master(tech_pvt)) {
+ if (tech_pvt->hold_file) {
+ if (!tech_pvt->hfh) {
+ int sample_rate = tech_pvt->sample_rate ? tech_pvt->sample_rate : globals.sample_rate;
+ if (switch_core_file_open(&tech_pvt->fh,
+ tech_pvt->hold_file,
+ globals.read_codec.implementation->number_of_channels,
+ globals.read_codec.implementation->samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
+ switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
+ tech_pvt->hold_file = NULL;
+ goto cng;
+ }
+
+ tech_pvt->hfh = &tech_pvt->fh;
+ tech_pvt->hold_frame.data = tech_pvt->holdbuf;
+ tech_pvt->hold_frame.buflen = sizeof(tech_pvt->holdbuf);
+ tech_pvt->hold_frame.rate = sample_rate;
+ tech_pvt->hold_frame.codec = &globals.write_codec;
+ }
+
+ goto hold;
+ }
+ cng:
+ switch_yield(globals.read_codec.implementation->microseconds_per_frame);
+ *frame = &globals.cng_frame;
return SWITCH_STATUS_SUCCESS;
- hold:
+ hold:
- {
- switch_size_t olen = globals.read_codec.implementation->samples_per_frame;
- if (switch_core_timer_next(&tech_pvt->timer) != SWITCH_STATUS_SUCCESS) {
- switch_core_file_close(&tech_pvt->fh);
- switch_core_codec_destroy(&tech_pvt->write_codec);
- goto cng;
+ {
+ switch_size_t olen = globals.read_codec.implementation->samples_per_frame;
+ if (switch_core_timer_next(&globals.timer) != SWITCH_STATUS_SUCCESS) {
+ switch_core_file_close(&tech_pvt->fh);
+ goto cng;
+ }
+ switch_core_file_read(tech_pvt->hfh, tech_pvt->hold_frame.data, &olen);
+
+ if (olen == 0) {
+ unsigned int pos = 0;
+ switch_core_file_seek(tech_pvt->hfh, &pos, 0, SEEK_SET);
+ goto cng;
}
- switch_core_file_read(tech_pvt->hfh, tech_pvt->hold_frame.data, &olen);
-
- if (olen == 0) {
- unsigned int pos = 0;
- switch_core_file_seek(tech_pvt->hfh, &pos, 0, SEEK_SET);
- goto cng;
- }
-
-
- tech_pvt->hold_frame.datalen = (uint32_t)(olen * sizeof(int16_t));
- tech_pvt->hold_frame.samples = (uint32_t)olen;
- *frame = &tech_pvt->hold_frame;
-
- }
- return SWITCH_STATUS_SUCCESS;
- }
+
+ tech_pvt->hold_frame.datalen = (uint32_t) (olen * sizeof(int16_t));
+ tech_pvt->hold_frame.samples = (uint32_t) olen;
+ tech_pvt->hold_frame.timestamp = globals.timer.samplecount;
+ *frame = &tech_pvt->hold_frame;
+
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+ }
switch_mutex_lock(globals.device_lock);
- if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_frame)) != 0) {
+ if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data,
+ globals.read_codec.implementation->samples_per_frame,
+ &globals.timer)) == 0) {
+ switch_mutex_unlock(globals.device_lock);
+ goto cng;
+ } else {
globals.read_frame.datalen = samples * 2;
globals.read_frame.samples = samples;
+
+ switch_core_timer_check(&globals.timer);
+ globals.read_frame.timestamp = globals.timer.samplecount;
*frame = &globals.read_frame;
- if (!switch_test_flag((&globals), GFLAG_MOUTH)) {
- memset(globals.read_frame.data, 255, globals.read_frame.datalen);
- }
+ if (!switch_test_flag((&globals), GFLAG_MOUTH)) {
+ memset(globals.read_frame.data, 255, globals.read_frame.datalen);
+ }
status = SWITCH_STATUS_SUCCESS;
}
@@ -664,8 +648,7 @@
return status;
}
-static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
- switch_io_flag_t flags, int stream_id)
+static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id)
{
switch_channel_t *channel = NULL;
private_t *tech_pvt = NULL;
@@ -677,21 +660,22 @@
assert(tech_pvt != NULL);
if (!globals.audio_stream) {
- return SWITCH_STATUS_FALSE;
- }
+ return SWITCH_STATUS_FALSE;
+ }
- if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
- return SWITCH_STATUS_FALSE;
- }
-
- if (!is_master(tech_pvt) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
- return SWITCH_STATUS_SUCCESS;
- }
+ if (switch_test_flag(tech_pvt, TFLAG_HUP)) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (!is_master(tech_pvt) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
+ return SWITCH_STATUS_SUCCESS;
+ }
if (globals.audio_stream) {
- if (switch_test_flag((&globals), GFLAG_EAR)) {
- WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)));
- }
+ if (switch_test_flag((&globals), GFLAG_EAR)) {
+ WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)),
+ &globals.timer);
+ }
status = SWITCH_STATUS_SUCCESS;
}
@@ -717,16 +701,19 @@
{
switch_channel_t *channel;
private_t *tech_pvt;
-
+
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
-
+
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
switch (msg->message_id) {
- case SWITCH_MESSAGE_INDICATE_PROGRESS:
+ case SWITCH_MESSAGE_INDICATE_ANSWER:
+ channel_answer_channel(session);
+ break;
+ case SWITCH_MESSAGE_INDICATE_PROGRESS:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage Early Media\n");
switch_set_flag_locked(tech_pvt, TFLAG_IO);
@@ -737,55 +724,7 @@
return SWITCH_STATUS_SUCCESS;
}
-static switch_api_interface_t send_dtmf_interface = {
- /*.interface_name */ "padtmf",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ NULL
-};
-
-static switch_api_interface_t answer_call_interface = {
- /*.interface_name */ "paoffhook",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &send_dtmf_interface
-};
-
-static switch_api_interface_t channel_info_interface = {
- /*.interface_name */ "painfo",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &answer_call_interface
-};
-
-static switch_api_interface_t channel_hup_interface = {
- /*.interface_name */ "pahup",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &channel_info_interface
-};
-
-static switch_api_interface_t channel_call_interface = {
- /*.interface_name */ "pacall",
- /*.desc */ "DEPRICATED (see 'pa')",
- /*.function */ padep,
- /*.syntax */ "DEPRICATED (see 'pa')",
- /*.next */ &channel_hup_interface
-};
-
-static switch_api_interface_t channel_api_interface = {
- /*.interface_name */ "pa",
- /*.desc */ "PortAudio",
- /*.function */ pa_cmd,
- /*.syntax */ "<command> [<args>]",
- /*.next */ &channel_call_interface
-};
-
-static const switch_state_handler_table_t channel_event_handlers = {
+static switch_state_handler_table_t channel_event_handlers = {
/*.on_init */ channel_on_init,
/*.on_ring */ channel_on_ring,
/*.on_execute */ channel_on_execute,
@@ -794,56 +733,38 @@
/*.on_transmit */ channel_on_transmit
};
-static const switch_io_routines_t channel_io_routines = {
+static switch_io_routines_t channel_io_routines = {
/*.outgoing_channel */ channel_outgoing_channel,
- /*.answer_channel */ channel_answer_channel,
/*.read_frame */ channel_read_frame,
/*.write_frame */ channel_write_frame,
/*.kill_channel */ channel_kill_channel,
/*.waitfor_read */ channel_waitfor_read,
/*.waitfor_write */ channel_waitfor_write,
/*.send_dtmf */ channel_send_dtmf,
- /*.receive_message*/ channel_receive_message
-};
-
-static const switch_endpoint_interface_t channel_endpoint_interface = {
- /*.interface_name */ "portaudio",
- /*.io_routines */ &channel_io_routines,
- /*.event_handlers */ &channel_event_handlers,
- /*.private */ NULL,
- /*.next */ NULL
-};
-
-static const switch_loadable_module_interface_t channel_module_interface = {
- /*.module_name */ modname,
- /*.endpoint_interface */ &channel_endpoint_interface,
- /*.timer_interface */ NULL,
- /*.dialplan_interface */ NULL,
- /*.codec_interface */ NULL,
- /*.application_interface */ NULL,
- /*.api_interface */ &channel_api_interface
+ /*.receive_message */ channel_receive_message
};
/* 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_caller_profile_t *outbound_profile,
+static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
+ switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool)
{
- if ((*new_session = switch_core_session_request(&channel_endpoint_interface, pool)) != 0) {
+ if ((*new_session = switch_core_session_request(channel_endpoint_interface, pool)) != 0) {
private_t *tech_pvt;
switch_channel_t *channel;
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))) != 0) {
- memset(tech_pvt, 0, sizeof(*tech_pvt));
+ memset(tech_pvt, 0, sizeof(*tech_pvt));
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
channel = switch_core_session_get_channel(*new_session);
switch_core_session_set_private(*new_session, tech_pvt);
tech_pvt->session = *new_session;
- globals.flags = GFLAG_EAR | GFLAG_MOUTH;
+ globals.flags = GFLAG_EAR | GFLAG_MOUTH;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
switch_core_session_destroy(new_session);
@@ -852,9 +773,9 @@
if (outbound_profile) {
char name[128];
- char *id = !switch_strlen_zero(outbound_profile->caller_id_number) ? outbound_profile->caller_id_number : "na";
+ char *id = !switch_strlen_zero(outbound_profile->caller_id_number) ? outbound_profile->caller_id_number : "na";
snprintf(name, sizeof(name), "PortAudio/%s", id);
-
+
switch_channel_set_name(channel, name);
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
@@ -877,30 +798,28 @@
}
-SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
+SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
{
+ switch_status_t status;
+ switch_api_interface_t *api_interface;
- switch_status_t status;
-
- if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
- return SWITCH_STATUS_TERM;
- }
+ module_pool = pool;
Pa_Initialize();
if (dump_info()) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
return SWITCH_STATUS_TERM;
- }
+ }
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
+ return status;
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Input Device: %d, Output Device: %d, Ring Device: %d Sample Rate: %d MS: %d\n",
- globals.indev, globals.outdev, globals.ringdev, globals.sample_rate, globals.codec_ms);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+ "Input Device: %d, Output Device: %d, Ring Device: %d Sample Rate: %d MS: %d\n", globals.indev,
+ globals.outdev, globals.ringdev, globals.sample_rate, globals.codec_ms);
switch_core_hash_init(&globals.call_hash, module_pool);
@@ -920,10 +839,16 @@
globals.cng_frame.data = globals.cngbuf;
globals.cng_frame.buflen = sizeof(globals.cngbuf);
globals.cng_frame.datalen = sizeof(globals.cngbuf);
- switch_set_flag((&globals.cng_frame), SFF_CNG);
+ switch_set_flag((&globals.cng_frame), SFF_CNG);
/* connect my internal structure to the blank pointer passed to me */
- *module_interface = &channel_module_interface;
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ channel_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
+ channel_endpoint_interface->interface_name = "portaudio";
+ channel_endpoint_interface->io_routines = &channel_io_routines;
+ channel_endpoint_interface->state_handler = &channel_event_handlers;
+
+ SWITCH_ADD_API(api_interface, "pa", "PortAudio", pa_cmd, "<command> [<args>]");
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
@@ -934,7 +859,7 @@
{
char *cf = "portaudio.conf";
switch_xml_t cfg, xml, settings, param;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
@@ -942,7 +867,7 @@
}
memset(&globals, 0, sizeof(globals));
- globals.indev = globals.outdev = globals.ringdev = -1;
+ globals.indev = globals.outdev = globals.ringdev = -1;
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
@@ -952,7 +877,7 @@
if (!strcmp(var, "debug")) {
globals.debug = atoi(val);
} else if (!strcmp(var, "ring-interval")) {
- globals.ring_interval = atoi(val);
+ globals.ring_interval = atoi(val);
} else if (!strcmp(var, "ring-file")) {
set_global_ring_file(val);
} else if (!strcmp(var, "hold-file")) {
@@ -987,7 +912,7 @@
} else {
globals.ringdev = get_dev_by_name(val, 0);
}
- }
+ }
}
}
@@ -1006,44 +931,44 @@
if (!globals.ring_interval) {
globals.ring_interval = 5;
}
-
- if (!globals.timer_name) {
- set_global_timer_name("soft");
- }
-
- if (globals.indev < 0) {
- globals.indev = get_dev_by_name(NULL, 1);
- if (globals.indev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device!\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
- status = SWITCH_STATUS_GENERR;
- }
- }
-
- if (globals.outdev < 0) {
- globals.outdev = get_dev_by_name(NULL, 0);
- if (globals.outdev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device!\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
- status = SWITCH_STATUS_GENERR;
- }
- }
-
- if (globals.ringdev < 0) {
- if (globals.outdev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ring device configured using output device!\n");
- globals.ringdev = globals.outdev;
- }
- }
+
+ if (!globals.timer_name) {
+ set_global_timer_name("soft");
+ }
+
+ if (globals.indev < 0) {
+ globals.indev = get_dev_by_name(NULL, 1);
+ if (globals.indev > -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device!\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+ status = SWITCH_STATUS_GENERR;
+ }
+ }
+
+ if (globals.outdev < 0) {
+ globals.outdev = get_dev_by_name(NULL, 0);
+ if (globals.outdev > -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device!\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+ status = SWITCH_STATUS_GENERR;
+ }
+ }
+
+ if (globals.ringdev < 0) {
+ if (globals.outdev > -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ring device configured using output device!\n");
+ globals.ringdev = globals.outdev;
+ }
+ }
switch_xml_free(xml);
return status;
}
-SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown)
{
if (globals.read_codec.implementation) {
switch_core_codec_destroy(&globals.read_codec);
@@ -1053,6 +978,7 @@
switch_core_codec_destroy(&globals.write_codec);
}
+ switch_core_timer_destroy(&globals.timer);
Pa_Terminate();
return SWITCH_STATUS_SUCCESS;
@@ -1061,18 +987,18 @@
static int get_dev_by_number(int number, int in)
{
- int numDevices = Pa_GetDeviceCount();
+ int numDevices = Pa_GetDeviceCount();
const PaDeviceInfo *pdi;
- if (number > -1 && number < numDevices && (pdi = Pa_GetDeviceInfo(number))) {
- if (in && pdi->maxInputChannels) {
- return number;
- } else if (!in && pdi->maxOutputChannels) {
- return number;
- }
- }
-
- return -1;
+ if (number > -1 && number < numDevices && (pdi = Pa_GetDeviceInfo(number))) {
+ if (in && pdi->maxInputChannels) {
+ return number;
+ } else if (!in && pdi->maxOutputChannels) {
+ return number;
+ }
+ }
+
+ return -1;
}
static int get_dev_by_name(char *name, int in)
@@ -1088,15 +1014,15 @@
}
for (i = 0; i < numDevices; i++) {
- int match = 0;
+ int match = 0;
pdi = Pa_GetDeviceInfo(i);
-
+
if (switch_strlen_zero(name)) {
- match = 1;
- } else if (strstr(pdi->name, name)) {
- match = 1;
- }
-
+ match = 1;
+ } else if (strstr(pdi->name, name)) {
+ match = 1;
+ }
+
if (match) {
if (in && pdi->maxInputChannels) {
return i;
@@ -1106,248 +1032,253 @@
}
}
- if (switch_strlen_zero(name)) {
- return -1;
- }
+ if (switch_strlen_zero(name)) {
+ return -1;
+ }
return get_dev_by_name(NULL, in);
}
/*******************************************************************/
-static void PrintSupportedStandardSampleRates(const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters)
+static void PrintSupportedStandardSampleRates(const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters)
{
- int i, printCount, cr = 7;
- PaError err;
- static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
- 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1};
-
- printCount = cr;
- for(i=0; standardSampleRates[i] > 0; i++) {
- err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
- if (err == paFormatIsSupported) {
- if (printCount == cr) {
- printCount = 0;
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n\t%0.2f", standardSampleRates[i]);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, ", %0.2f", standardSampleRates[i]);
- }
- printCount++;
- }
- }
- if (!printCount) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, " None\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n");
- }
+ int i, printCount, cr = 7;
+ PaError err;
+ static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
+ 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1
+ };
+
+ printCount = cr;
+ for (i = 0; standardSampleRates[i] > 0; i++) {
+ err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
+ if (err == paFormatIsSupported) {
+ if (printCount == cr) {
+ printCount = 0;
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n\t%0.2f", standardSampleRates[i]);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, ", %0.2f", standardSampleRates[i]);
+ }
+ printCount++;
+ }
+ }
+ if (!printCount) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, " None\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "\n");
+ }
}
+
/*******************************************************************/
static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *stream)
{
- int i, numDevices;
- const PaDeviceInfo *deviceInfo;
-
- numDevices = Pa_GetDeviceCount();
- if (numDevices < 0) {
+ int i, numDevices;
+ const PaDeviceInfo *deviceInfo;
+
+ numDevices = Pa_GetDeviceCount();
+ if (numDevices < 0) {
return SWITCH_STATUS_SUCCESS;
- }
- for(i=0; i<numDevices; i++) {
- deviceInfo = Pa_GetDeviceInfo(i);
- stream->write_function(stream, "%d;%s;%d;%d\n", i, deviceInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
+ }
+ for (i = 0; i < numDevices; i++) {
+ deviceInfo = Pa_GetDeviceInfo(i);
+ stream->write_function(stream, "%d;%s;%d;%d\n", i, deviceInfo->name, deviceInfo->maxInputChannels, deviceInfo->maxOutputChannels);
}
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static int dump_info(void)
{
- int i, numDevices, defaultDisplayed;
- const PaDeviceInfo *deviceInfo;
- PaStreamParameters inputParameters, outputParameters;
- PaError err;
- const char *line = "--------------------------------------------------------------------------------\n";
-
+ int i, numDevices, defaultDisplayed;
+ const PaDeviceInfo *deviceInfo;
+ PaStreamParameters inputParameters, outputParameters;
+ PaError err;
+ const char *line = "--------------------------------------------------------------------------------\n";
+
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "PortAudio version number = %d\nPortAudio version text = '%s'\n",
- Pa_GetVersion(), Pa_GetVersionText());
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+ "PortAudio version number = %d\nPortAudio version text = '%s'\n", Pa_GetVersion(), Pa_GetVersionText());
if (globals.audio_stream) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
return 0;
}
-
- numDevices = Pa_GetDeviceCount();
- if (numDevices < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
- err = numDevices;
- goto error;
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices);
- for(i=0; i<numDevices; i++) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
- deviceInfo = Pa_GetDeviceInfo(i);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Device #%d ", i);
-
- /* Mark global and API specific default devices */
- defaultDisplayed = 0;
- if (i == Pa_GetDefaultInputDevice()) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Input");
- defaultDisplayed = 1;
-
- } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
-
- const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name);
- defaultDisplayed = 1;
- }
-
- if (i == Pa_GetDefaultOutputDevice()) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Output");
- defaultDisplayed = 1;
-
- } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
-
- const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name);
- defaultDisplayed = 1;
- }
-
- if (defaultDisplayed) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "** | ");
- }
- /* print device info fields */
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels );
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels );
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
-
- /* poll for standard sample rates */
- inputParameters.device = i;
- inputParameters.channelCount = deviceInfo->maxInputChannels;
- inputParameters.sampleFormat = paInt16;
- inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
- inputParameters.hostApiSpecificStreamInfo = NULL;
-
- outputParameters.device = i;
- outputParameters.channelCount = deviceInfo->maxOutputChannels;
- outputParameters.sampleFormat = paInt16;
- outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
- outputParameters.hostApiSpecificStreamInfo = NULL;
-
- if (inputParameters.channelCount > 0) {
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:",
- inputParameters.channelCount);
- PrintSupportedStandardSampleRates(&inputParameters, NULL);
- }
-
- if (outputParameters.channelCount > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:",
- outputParameters.channelCount);
- PrintSupportedStandardSampleRates(NULL, &outputParameters);
- }
-
- if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "full-duplex 16 bit %d channel input, %d channel output rates:",
- inputParameters.channelCount, outputParameters.channelCount);
- PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
- }
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
-
- return 0;
-
- error:
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "An error occured while using the portaudio stream\n");
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error number: %d\n", err);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error message: %s\n", Pa_GetErrorText(err));
- return err;
+
+ numDevices = Pa_GetDeviceCount();
+ if (numDevices < 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
+ err = numDevices;
+ goto error;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices);
+ for (i = 0; i < numDevices; i++) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+ deviceInfo = Pa_GetDeviceInfo(i);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Device #%d ", i);
+
+ /* Mark global and API specific default devices */
+ defaultDisplayed = 0;
+ if (i == Pa_GetDefaultInputDevice()) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Input");
+ defaultDisplayed = 1;
+
+ } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
+
+ const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name);
+ defaultDisplayed = 1;
+ }
+
+ if (i == Pa_GetDefaultOutputDevice()) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Output");
+ defaultDisplayed = 1;
+
+ } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
+
+ const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name);
+ defaultDisplayed = 1;
+ }
+
+ if (defaultDisplayed) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "** | ");
+ }
+ /* print device info fields */
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
+
+ /* poll for standard sample rates */
+ inputParameters.device = i;
+ inputParameters.channelCount = deviceInfo->maxInputChannels;
+ inputParameters.sampleFormat = paInt16;
+ inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
+ inputParameters.hostApiSpecificStreamInfo = NULL;
+
+ outputParameters.device = i;
+ outputParameters.channelCount = deviceInfo->maxOutputChannels;
+ outputParameters.sampleFormat = paInt16;
+ outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+
+ if (inputParameters.channelCount > 0) {
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:", inputParameters.channelCount);
+ PrintSupportedStandardSampleRates(&inputParameters, NULL);
+ }
+
+ if (outputParameters.channelCount > 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:", outputParameters.channelCount);
+ PrintSupportedStandardSampleRates(NULL, &outputParameters);
+ }
+
+ if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+ "full-duplex 16 bit %d channel input, %d channel output rates:", inputParameters.channelCount,
+ outputParameters.channelCount);
+ PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
+ }
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+
+ return 0;
+
+ error:
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "An error occured while using the portaudio stream\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error number: %d\n", err);
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Error message: %s\n", Pa_GetErrorText(err));
+ return err;
}
static switch_status_t engage_device(int sample_rate, int codec_ms)
{
- PaStreamParameters inputParameters, outputParameters;
+ PaStreamParameters inputParameters, outputParameters;
PaError err;
- if (!globals.audio_stream) {
- if (!sample_rate) {
- sample_rate = globals.sample_rate;
- }
- if (!codec_ms) {
- codec_ms = globals.codec_ms;
- }
-
- if (switch_core_codec_init(&globals.read_codec,
- "L16",
- NULL,
- sample_rate,
- codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- return SWITCH_STATUS_FALSE;
- } else {
- if (switch_core_codec_init(&globals.write_codec,
- "L16",
- NULL,
- sample_rate,
- codec_ms,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- switch_core_codec_destroy(&globals.read_codec);
- return SWITCH_STATUS_FALSE;
- }
- }
-
- globals.read_frame.rate = sample_rate;
- globals.read_frame.codec = &globals.read_codec;
-
-
-
- switch_mutex_lock(globals.device_lock);
- /* LOCKED ***************************************************************************************************/
- inputParameters.device = globals.indev;
- inputParameters.channelCount = 1;
- inputParameters.sampleFormat = SAMPLE_TYPE;
- inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
- inputParameters.hostApiSpecificStreamInfo = NULL;
-
- outputParameters.device = globals.outdev;
- outputParameters.channelCount = 1;
- outputParameters.sampleFormat = SAMPLE_TYPE;
- outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
- outputParameters.hostApiSpecificStreamInfo = NULL;
- err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff);
- /* UNLOCKED **************************************************************************************************/
- switch_mutex_unlock(globals.device_lock);
-
-
- if (err != paNoError) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device!\n");
- switch_core_codec_destroy(&globals.read_codec);
- switch_core_codec_destroy(&globals.write_codec);
-
- return SWITCH_STATUS_FALSE;
- }
- }
+ if (!globals.audio_stream) {
+ if (!sample_rate) {
+ sample_rate = globals.sample_rate;
+ }
+ if (!codec_ms) {
+ codec_ms = globals.codec_ms;
+ }
+
+ if (switch_core_codec_init(&globals.read_codec,
+ "L16",
+ NULL, sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+ NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ return SWITCH_STATUS_FALSE;
+ } else {
+ if (switch_core_codec_init(&globals.write_codec,
+ "L16",
+ NULL,
+ sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+ NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ return SWITCH_STATUS_FALSE;
+ }
+ }
+
+ if (switch_core_timer_init(&globals.timer,
+ globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_frame,
+ module_pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ switch_core_codec_destroy(&globals.write_codec);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ globals.read_frame.rate = sample_rate;
+ globals.read_frame.codec = &globals.read_codec;
- return SWITCH_STATUS_SUCCESS;
+
+
+ switch_mutex_lock(globals.device_lock);
+ /* LOCKED ************************************************************************************************** */
+ inputParameters.device = globals.indev;
+ inputParameters.channelCount = 1;
+ inputParameters.sampleFormat = SAMPLE_TYPE;
+ inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
+ inputParameters.hostApiSpecificStreamInfo = NULL;
+
+ outputParameters.device = globals.outdev;
+ outputParameters.channelCount = 1;
+ outputParameters.sampleFormat = SAMPLE_TYPE;
+ outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+ err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
+ globals.read_codec.implementation->samples_per_frame);
+ /* UNLOCKED ************************************************************************************************* */
+ switch_mutex_unlock(globals.device_lock);
+
+ globals.mixer = Px_OpenMixer(&globals.audio_stream, 0);
+
+
+ if (err != paNoError) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device!\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ switch_core_codec_destroy(&globals.write_codec);
+
+ return SWITCH_STATUS_FALSE;
+ }
+ }
+
+
+
+ return SWITCH_STATUS_SUCCESS;
}
@@ -1355,35 +1286,35 @@
static switch_status_t engage_ring_device(int sample_rate, int channels)
{
- //int codec_ms = 20;
- PaStreamParameters outputParameters;
+ PaStreamParameters outputParameters;
PaError err;
- if (!globals.ring_stream) {
- if (!sample_rate) {
- sample_rate = globals.sample_rate;
- }
-
- switch_mutex_lock(globals.device_lock);
- /* LOCKED ***************************************************************************************************/
- outputParameters.device = globals.ringdev;
- outputParameters.channelCount = channels;
- outputParameters.sampleFormat = SAMPLE_TYPE;
- outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
- outputParameters.hostApiSpecificStreamInfo = NULL;
- err = OpenAudioStream(&globals.ring_stream, NULL, &outputParameters, sample_rate, paClipOff);
- /* UNLOCKED **************************************************************************************************/
- switch_mutex_unlock(globals.device_lock);
-
-
- if (err != paNoError) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device!\n");
- return SWITCH_STATUS_FALSE;
- }
- }
+ if (!globals.ring_stream) {
+ if (!sample_rate) {
+ sample_rate = globals.sample_rate;
+ }
+
+ switch_mutex_lock(globals.device_lock);
+ /* LOCKED ************************************************************************************************** */
+ outputParameters.device = globals.ringdev;
+ outputParameters.channelCount = channels;
+ outputParameters.sampleFormat = SAMPLE_TYPE;
+ outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+ err = OpenAudioStream(&globals.ring_stream, NULL, &outputParameters, sample_rate, paClipOff,
+ globals.read_codec.implementation->samples_per_frame);
+ /* UNLOCKED ************************************************************************************************* */
+ switch_mutex_unlock(globals.device_lock);
+
+
+ if (err != paNoError) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Engage ring device! rate: %d channels %d\n", sample_rate, channels);
- return SWITCH_STATUS_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Engage ring device! rate: %d channels %d\n", sample_rate, channels);
+ return SWITCH_STATUS_SUCCESS;
}
@@ -1391,64 +1322,64 @@
static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- char *dtmf = argv[0];
+ char *dtmf = argv[0];
- if (switch_strlen_zero(dtmf)) {
- stream->write_function(stream, "No DTMF Supplied!\n");
- } else {
- switch_mutex_lock(globals.pvt_lock);
- if (globals.call_list) {
- switch_channel_t *channel = switch_core_session_get_channel(globals.call_list->session);
- switch_channel_queue_dtmf(channel, dtmf);
- }
- switch_mutex_unlock(globals.pvt_lock);
- }
+ if (switch_strlen_zero(dtmf)) {
+ stream->write_function(stream, "No DTMF Supplied!\n");
+ } else {
+ switch_mutex_lock(globals.pvt_lock);
+ if (globals.call_list) {
+ switch_channel_t *channel = switch_core_session_get_channel(globals.call_list->session);
+ switch_channel_queue_dtmf(channel, dtmf);
+ }
+ switch_mutex_unlock(globals.pvt_lock);
+ }
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tp,*tech_pvt = NULL;
- char *callid = argv[0];
- uint8_t one_call = 0;
-
- switch_mutex_lock(globals.pvt_lock);
- if (switch_strlen_zero(callid)) {
- if (globals.call_list) {
- if (globals.call_list->next) {
- tech_pvt = globals.call_list->next;
- } else {
- tech_pvt = globals.call_list;
- one_call = 1;
- }
- }
- } else if (!strcasecmp(callid, "none")) {
- for (tp = globals.call_list; tp; tp = tp->next) {
- switch_clear_flag_locked(tp, TFLAG_MASTER);
- }
- stream->write_function(stream, "OK\n");
- goto done;
- } else {
- tech_pvt = switch_core_hash_find(globals.call_hash, callid);
- }
+ private_t *tp, *tech_pvt = NULL;
+ char *callid = argv[0];
+ uint8_t one_call = 0;
+
+ switch_mutex_lock(globals.pvt_lock);
+ if (switch_strlen_zero(callid)) {
+ if (globals.call_list) {
+ if (globals.call_list->next) {
+ tech_pvt = globals.call_list->next;
+ } else {
+ tech_pvt = globals.call_list;
+ one_call = 1;
+ }
+ }
+ } else if (!strcasecmp(callid, "none")) {
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ switch_clear_flag_locked(tp, TFLAG_MASTER);
+ }
+ stream->write_function(stream, "OK\n");
+ goto done;
+ } else {
+ tech_pvt = switch_core_hash_find(globals.call_hash, callid);
+ }
if (tech_pvt) {
- if (tech_pvt == globals.call_list && !tech_pvt->next) {
- one_call = 1;
- }
-
- if (!one_call) {
- remove_pvt(tech_pvt);
- }
- add_pvt(tech_pvt, PA_MASTER);
- stream->write_function(stream, "OK\n");
+ if (tech_pvt == globals.call_list && !tech_pvt->next) {
+ one_call = 1;
+ }
+
+ if (!one_call) {
+ remove_pvt(tech_pvt);
+ }
+ add_pvt(tech_pvt, PA_MASTER);
+ stream->write_function(stream, "OK\n");
} else {
stream->write_function(stream, "NO SUCH CALL\n");
}
- done:
- switch_mutex_unlock(globals.pvt_lock);
+ done:
+ switch_mutex_unlock(globals.pvt_lock);
return SWITCH_STATUS_SUCCESS;
@@ -1456,23 +1387,23 @@
static switch_status_t hangup_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tech_pvt;
- char *callid = argv[0];
-
- switch_mutex_lock(globals.pvt_lock);
- if (switch_strlen_zero(callid)) {
- tech_pvt = globals.call_list;
- } else {
- tech_pvt = switch_core_hash_find(globals.call_hash, callid);
- }
+ private_t *tech_pvt;
+ char *callid = argv[0];
+
+ switch_mutex_lock(globals.pvt_lock);
+ if (switch_strlen_zero(callid)) {
+ tech_pvt = globals.call_list;
+ } else {
+ tech_pvt = switch_core_hash_find(globals.call_hash, callid);
+ }
if (tech_pvt) {
- switch_set_flag_locked(tech_pvt, TFLAG_HUP);
+ switch_channel_hangup(switch_core_session_get_channel(tech_pvt->session), SWITCH_CAUSE_NORMAL_CLEARING);
stream->write_function(stream, "OK\n");
} else {
stream->write_function(stream, "NO SUCH CALL\n");
}
- switch_mutex_unlock(globals.pvt_lock);
+ switch_mutex_unlock(globals.pvt_lock);
return SWITCH_STATUS_SUCCESS;
@@ -1480,43 +1411,43 @@
static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tp;
- int x = 0;
- char *callid = argv[0];
-
- switch_mutex_lock(globals.pvt_lock);
-
- if (!switch_strlen_zero(callid)) {
- if ((tp = switch_core_hash_find(globals.call_hash, callid))) {
- if (switch_test_flag(tp, TFLAG_ANSWER)) {
- stream->write_function(stream, "CALL ALREADY ANSWERED\n");
- } else {
- switch_channel_t *channel = switch_core_session_get_channel(tp->session);
- switch_set_flag_locked(tp, TFLAG_ANSWER);
- switch_channel_answer(channel);
- add_pvt(tp, PA_MASTER);
- }
- } else {
- stream->write_function(stream, "NO SUCH CALL\n");
- }
-
- goto done;
- }
-
- for (tp = globals.call_list; tp; tp = tp->next) {
- if (!switch_test_flag(tp, TFLAG_ANSWER)) {
- switch_channel_t *channel = switch_core_session_get_channel(tp->session);
- switch_set_flag_locked(tp, TFLAG_ANSWER);
- switch_channel_answer(channel);
- add_pvt(tp, PA_MASTER);
- x++;
- break;
- }
- }
- done:
- switch_mutex_unlock(globals.pvt_lock);
+ private_t *tp;
+ int x = 0;
+ char *callid = argv[0];
+
+ switch_mutex_lock(globals.pvt_lock);
+
+ if (!switch_strlen_zero(callid)) {
+ if ((tp = switch_core_hash_find(globals.call_hash, callid))) {
+ if (switch_test_flag(tp, TFLAG_ANSWER)) {
+ stream->write_function(stream, "CALL ALREADY ANSWERED\n");
+ } else {
+ switch_channel_t *channel = switch_core_session_get_channel(tp->session);
+ switch_set_flag_locked(tp, TFLAG_ANSWER);
+ switch_channel_answer(channel);
+ add_pvt(tp, PA_MASTER);
+ }
+ } else {
+ stream->write_function(stream, "NO SUCH CALL\n");
+ }
- stream->write_function(stream, "Answered %d channels.\n", x);
+ goto done;
+ }
+
+ for (tp = globals.call_list; tp; tp = tp->next) {
+ if (!switch_test_flag(tp, TFLAG_ANSWER)) {
+ switch_channel_t *channel = switch_core_session_get_channel(tp->session);
+ switch_set_flag_locked(tp, TFLAG_ANSWER);
+ switch_channel_answer(channel);
+ add_pvt(tp, PA_MASTER);
+ x++;
+ break;
+ }
+ }
+ done:
+ switch_mutex_unlock(globals.pvt_lock);
+
+ stream->write_function(stream, "Answered %d channels.\n", x);
return SWITCH_STATUS_SUCCESS;
@@ -1525,113 +1456,110 @@
static switch_status_t do_flags(char **argv, int argc, switch_stream_handle_t *stream)
{
- char *action = argv[0];
- char *flag_str = argv[1];
- GFLAGS flags = GFLAG_NONE;
- char *p;
- int x = 0;
-
- if (argc < 2) {
- goto desc;
- }
-
- for (x = 1; x < argc; x++) {
- flag_str = argv[x];
- for(p = flag_str; *p; p++) {
- *p = (char)tolower(*p);
- }
-
- if (strstr(flag_str, "ear")) {
- flags |= GFLAG_EAR;
- }
- if (strstr(flag_str, "mouth")) {
- flags |= GFLAG_MOUTH;
- }
- }
-
- if (!strcasecmp(action, "on")) {
- if (flags & GFLAG_EAR) {
- switch_set_flag((&globals), GFLAG_EAR);
- }
- if (flags & GFLAG_MOUTH) {
- switch_set_flag((&globals), GFLAG_MOUTH);
- }
- } else if (!strcasecmp(action, "off")) {
- if (flags & GFLAG_EAR) {
- switch_clear_flag((&globals), GFLAG_EAR);
- }
- if (flags & GFLAG_MOUTH) {
- switch_clear_flag((&globals), GFLAG_MOUTH);
- }
- } else {
- goto bad;
- }
-
- desc:
- x = 0;
- stream->write_function(stream, "FLAGS: ");
- if (switch_test_flag((&globals), GFLAG_EAR)) {
- stream->write_function(stream, "ear");
- x++;
- }
- if (switch_test_flag((&globals), GFLAG_MOUTH)) {
- stream->write_function(stream, "%smouth", x ? "|" : "");
- x++;
- }
- if (!x) {
- stream->write_function(stream, "none");
- }
-
- goto done;
-
- bad:
- stream->write_function(stream, "Usage: flags [on|off] <flags>\n");
- done:
- return SWITCH_STATUS_SUCCESS;
+ char *action = argv[0];
+ char *flag_str = argv[1];
+ GFLAGS flags = GFLAG_NONE;
+ char *p;
+ int x = 0;
+
+ if (argc < 2) {
+ goto desc;
+ }
+
+ for (x = 1; x < argc; x++) {
+ flag_str = argv[x];
+ for (p = flag_str; *p; p++) {
+ *p = (char) tolower(*p);
+ }
+
+ if (strstr(flag_str, "ear")) {
+ flags |= GFLAG_EAR;
+ }
+ if (strstr(flag_str, "mouth")) {
+ flags |= GFLAG_MOUTH;
+ }
+ }
+
+ if (!strcasecmp(action, "on")) {
+ if (flags & GFLAG_EAR) {
+ switch_set_flag((&globals), GFLAG_EAR);
+ }
+ if (flags & GFLAG_MOUTH) {
+ switch_set_flag((&globals), GFLAG_MOUTH);
+ }
+ } else if (!strcasecmp(action, "off")) {
+ if (flags & GFLAG_EAR) {
+ switch_clear_flag((&globals), GFLAG_EAR);
+ }
+ if (flags & GFLAG_MOUTH) {
+ switch_clear_flag((&globals), GFLAG_MOUTH);
+ }
+ } else {
+ goto bad;
+ }
+
+ desc:
+ x = 0;
+ stream->write_function(stream, "FLAGS: ");
+ if (switch_test_flag((&globals), GFLAG_EAR)) {
+ stream->write_function(stream, "ear");
+ x++;
+ }
+ if (switch_test_flag((&globals), GFLAG_MOUTH)) {
+ stream->write_function(stream, "%smouth", x ? "|" : "");
+ x++;
+ }
+ if (!x) {
+ stream->write_function(stream, "none");
+ }
+
+ goto done;
+
+ bad:
+ stream->write_function(stream, "Usage: flags [on|off] <flags>\n");
+ done:
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t list_calls(char **argv, int argc, switch_stream_handle_t *stream)
{
- private_t *tp;
- int x = 0;
- char *cid_name = "n/a";
- char *cid_num = "n/a";
-
- switch_mutex_lock(globals.pvt_lock);
- for (tp = globals.call_list; tp; tp = tp->next) {
+ private_t *tp;
+ int x = 0;
+ char *cid_name = "n/a";
+ char *cid_num = "n/a";
+
+ switch_mutex_lock(globals.pvt_lock);
+ for (tp = globals.call_list; tp; tp = tp->next) {
switch_channel_t *channel;
- switch_caller_profile_t *profile;
- x++;
- channel = switch_core_session_get_channel(tp->session);
-
- if ((profile = switch_channel_get_caller_profile(channel))) {
- if (profile->originatee_caller_profile) {
- cid_name = "Outbound Call";
- cid_num = profile->originatee_caller_profile->destination_number;
- } else {
- cid_name = profile->caller_id_name;
- cid_num = profile->caller_id_number;
- }
- }
-
- stream->write_function(stream, "%s %s [%s (%s)] %s\n", tp->call_id, switch_channel_get_name(channel),
- cid_name,
- cid_num,
- switch_test_flag(tp, TFLAG_MASTER) ? "active" : "hold"
- );
- }
- switch_mutex_unlock(globals.pvt_lock);
+ switch_caller_profile_t *profile;
+ x++;
+ channel = switch_core_session_get_channel(tp->session);
+
+ if ((profile = switch_channel_get_caller_profile(channel))) {
+ if (profile->originatee_caller_profile) {
+ cid_name = "Outbound Call";
+ cid_num = profile->originatee_caller_profile->destination_number;
+ } else {
+ cid_name = profile->caller_id_name;
+ cid_num = profile->caller_id_number;
+ }
+ }
+
+ stream->write_function(stream, "%s %s [%s (%s)] %s\n", tp->call_id, switch_channel_get_name(channel),
+ cid_name, cid_num, switch_test_flag(tp, TFLAG_MASTER) ? "active" : "hold");
+ }
+ switch_mutex_unlock(globals.pvt_lock);
- stream->write_function(stream, "\n%d call%s\n", x, x == 1 ? "" : "s");
+ stream->write_function(stream, "\n%d call%s\n", x, x == 1 ? "" : "s");
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t *stream)
{
switch_core_session_t *session;
switch_status_t status = SWITCH_STATUS_SUCCESS;
- char *dest = NULL;
+ char *dest = NULL;
if (!argv[0]) {
stream->write_function(stream, "FAIL:Usage: call <dest>\n");
@@ -1639,12 +1567,12 @@
}
dest = argv[0];
- if ((session = switch_core_session_request(&channel_endpoint_interface, NULL)) != 0) {
+ if ((session = switch_core_session_request(channel_endpoint_interface, NULL)) != 0) {
private_t *tech_pvt;
switch_channel_t *channel;
- char *dialplan = globals.dialplan;
- char *cid_name = globals.cid_name;
- char *cid_num = globals.cid_num;
+ char *dialplan = globals.dialplan;
+ char *cid_name = globals.cid_name;
+ char *cid_num = globals.cid_num;
switch_core_session_add_stream(session, NULL);
if ((tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t))) != 0) {
@@ -1653,7 +1581,7 @@
channel = switch_core_session_get_channel(session);
switch_core_session_set_private(session, tech_pvt);
tech_pvt->session = session;
- globals.flags = GFLAG_EAR | GFLAG_MOUTH;
+ globals.flags = GFLAG_EAR | GFLAG_MOUTH;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
switch_core_session_destroy(&session);
@@ -1661,31 +1589,29 @@
}
if (!switch_strlen_zero(argv[1])) {
- dialplan = argv[1];
- }
+ dialplan = argv[1];
+ }
- if (!switch_strlen_zero(argv[2])) {
- cid_num = argv[2];
- }
-
- if (!switch_strlen_zero(argv[3])) {
- cid_name = argv[3];
- }
-
- if (!switch_strlen_zero(argv[4])) {
- tech_pvt->sample_rate = atoi(argv[4]);
- }
-
- if (!switch_strlen_zero(argv[4])) {
- tech_pvt->codec_ms = atoi(argv[5]);
- }
+ if (!switch_strlen_zero(argv[2])) {
+ cid_num = argv[2];
+ }
+
+ if (!switch_strlen_zero(argv[3])) {
+ cid_name = argv[3];
+ }
+
+ if (!switch_strlen_zero(argv[4])) {
+ tech_pvt->sample_rate = atoi(argv[4]);
+ }
+
+ if (!switch_strlen_zero(argv[4])) {
+ tech_pvt->codec_ms = atoi(argv[5]);
+ }
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
NULL,
- dialplan,
- cid_name,
- cid_num,
- NULL, NULL, NULL, NULL, (char *)modname, NULL, dest)) != 0) {
+ dialplan, cid_name, cid_num, NULL, NULL, NULL, NULL, (char *) modname, NULL,
+ dest)) != 0) {
char name[128];
snprintf(name, sizeof(name), "PortAudio/%s",
tech_pvt->caller_profile->destination_number ? tech_pvt->caller_profile->destination_number : modname);
@@ -1695,14 +1621,19 @@
}
tech_pvt->session = session;
if ((status = engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms)) == SWITCH_STATUS_SUCCESS) {
- switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
- switch_channel_mark_answered(channel);
+ switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
+ switch_channel_mark_answered(channel);
switch_channel_set_state(channel, CS_INIT);
- switch_core_session_thread_launch(tech_pvt->session);
- add_pvt(tech_pvt, PA_MASTER);
- stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+ if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
+ switch_core_session_destroy(&session);
+ stream->write_function(stream, "FAIL:Thread Error!\n");
+ } else {
+ add_pvt(tech_pvt, PA_MASTER);
+ stream->write_function(stream, "SUCCESS:%s:%s\n", tech_pvt->call_id, switch_core_session_get_uuid(tech_pvt->session));
+ }
} else {
- switch_core_session_destroy(&session);
+ switch_core_session_destroy(&session);
stream->write_function(stream, "FAIL:Device Error!\n");
}
}
@@ -1710,74 +1641,131 @@
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t padep(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+static switch_status_t set_volume(char **argv, int argc, switch_stream_handle_t *stream)
{
- stream->write_function(stream, "This command no longer exists (try 'pa help')\n");
- return SWITCH_STATUS_SUCCESS;
+ PxVolume volume;
+ switch_mutex_lock(globals.device_lock);
+ if (!switch_strlen_zero(argv[1])) {
+ volume = (PxVolume) atof(argv[1]);
+ Px_SetMasterVolume( globals.mixer, volume );
+ }
+ switch_mutex_unlock(globals.device_lock);
+ return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t pa_cmd(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+SWITCH_STANDARD_API(pa_cmd)
{
- char *argv[1024] = {0};
- int argc = 0;
- char *mycmd = NULL, *devname = NULL;
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- pa_command_t func = NULL;
- int lead = 1, devval = 0;
- const char *usage_string = "USAGE:\n"
- "--------------------------------------------------------------------------------\n"
- "pa help\n"
- "pa dump\n"
- "pa call <dest> [<dialplan> <cid_name> <cid_num> <rate>]\n"
- "pa answer [<call_id>]\n"
- "pa hangup [<call_id>]\n"
- "pa list\n"
- "pa switch [<call_id>|none]\n"
- "pa dtmf <digit string>\n"
- "pa flags [on|off] [ear] [mouth]\n"
+ char *argv[1024] = { 0 };
+ int argc = 0;
+ char *mycmd = NULL, *devname = NULL;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ pa_command_t func = NULL;
+ int lead = 1, devval = 0;
+ char *wcmd = NULL, *action = NULL;
+ char cmd_buf[1024] = "";
+ char *http = NULL;
+
+ const char *usage_string = "USAGE:\n"
+ "--------------------------------------------------------------------------------\n"
+ "pa help\n"
+ "pa dump\n"
+ "pa call <dest> [<dialplan> <cid_name> <cid_num> <rate>]\n"
+ "pa answer [<call_id>]\n"
+ "pa hangup [<call_id>]\n"
+ "pa list\n"
+ "pa switch [<call_id>|none]\n"
+ "pa dtmf <digit string>\n"
+ "pa flags [on|off] [ear] [mouth]\n"
"pa devlist\n"
"pa indev [#<num>|<partial name>\n"
"pa outdev [#<num>|<partial name>\n"
"pa ringdev [#<num>|<partial name>\n"
- "--------------------------------------------------------------------------------\n";
+ "pa setvolume <volume between 0.0 and 1.0>\n"
+ "--------------------------------------------------------------------------------\n";
+
+ if (stream->event) {
+ http = switch_event_get_header(stream->event, "http-host");
+ }
+
+
+ if (http) {
+#if 0
+ switch_event_header_t *hp;
+ stream->write_function(stream, "<pre>");
+ for (hp = stream->event->headers; hp; hp = hp->next) {
+ stream->write_function(stream, "[%s]=[%s]\n", hp->name, hp->value);
+ }
+ stream->write_function(stream, "</pre>");
+#endif
+
+ wcmd = switch_str_nil(switch_event_get_header(stream->event, "wcmd"));
+ action = switch_event_get_header(stream->event, "action");
- if (switch_strlen_zero(cmd)) {
- stream->write_function(stream, "%s", usage_string);
- goto done;
- }
-
- if (!(mycmd = strdup(cmd))) {
- status = SWITCH_STATUS_MEMERR;
- goto done;
- }
-
- if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
- stream->write_function(stream, "%s", usage_string);
- goto done;
- }
-
- if (!strcasecmp(argv[0], "call")) {
- func = place_call;
- } else if (!strcasecmp(argv[0], "help")) {
- stream->write_function(stream, "%s", usage_string);
- goto done;
- } else if (!strcasecmp(argv[0], "devlist")) {
+ if (action) {
+ if (strlen(action) == 1) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "dtmf %s", action);
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "mute")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "flags off mouth");
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "unmute")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "flags on mouth");
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "switch")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "switch %s", wcmd);
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "call")) {
+ snprintf(cmd_buf, sizeof(cmd_buf), "call %s", wcmd);
+ cmd = cmd_buf;
+ } else if (!strcmp(action, "hangup") || !strcmp(action, "list") || !strcmp(action, "answer")) {
+ cmd = action;
+ }
+ }
+
+ if (switch_strlen_zero(cmd)) {
+ goto done;
+ }
+
+ } else {
+
+ if (switch_strlen_zero(cmd)) {
+ stream->write_function(stream, "%s", usage_string);
+ goto done;
+ }
+ }
+
+ if (!(mycmd = strdup(cmd))) {
+ status = SWITCH_STATUS_MEMERR;
+ goto done;
+ }
+
+ if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
+ stream->write_function(stream, "%s", usage_string);
+ goto done;
+ }
+
+ if (!strcasecmp(argv[0], "call")) {
+ func = place_call;
+ } else if (!strcasecmp(argv[0], "help")) {
+ stream->write_function(stream, "%s", usage_string);
+ goto done;
+ } else if (!strcasecmp(argv[0], "devlist")) {
func = devlist;
- } else if (!strcasecmp(argv[0], "dump")) {
- dump_info();
- goto done;
- } else if (!strcasecmp(argv[0], "list")) {
- func = list_calls;
- } else if (!strcasecmp(argv[0], "flags")) {
- func = do_flags;
- } else if (!strcasecmp(argv[0], "hangup")) {
- func = hangup_call;
- } else if (!strcasecmp(argv[0], "answer")) {
- func = answer_call;
- } else if (!strcasecmp(argv[0], "switch")) {
- func = switch_call;
- } else if (!strcasecmp(argv[0], "dtmf")) {
- func = dtmf_call;
+ } else if (!strcasecmp(argv[0], "dump")) {
+ dump_info();
+ goto done;
+ } else if (!strcasecmp(argv[0], "list")) {
+ func = list_calls;
+ } else if (!strcasecmp(argv[0], "flags")) {
+ func = do_flags;
+ } else if (!strcasecmp(argv[0], "hangup")) {
+ func = hangup_call;
+ } else if (!strcasecmp(argv[0], "answer")) {
+ func = answer_call;
+ } else if (!strcasecmp(argv[0], "switch")) {
+ func = switch_call;
+ } else if (!strcasecmp(argv[0], "dtmf")) {
+ func = dtmf_call;
} else if (argv[1] && !strcmp(argv[0], "indev")) {
if (*argv[1] == '#') {
devval = get_dev_by_number(atoi(argv[1] + 1), 1);
@@ -1795,7 +1783,7 @@
devval = get_dev_by_name(argv[1], 0);
}
devname = "outdev";
- if (devval > 0) {
+ if (devval > 0) {
globals.outdev = devval;
}
} else if (argv[1] && !strcmp(argv[0], "ringdev")) {
@@ -1807,12 +1795,20 @@
devname = "ringdev";
if (devval > 0) {
globals.ringdev = devval;
+ }
+ } else if (!strcasecmp(argv[0], "setvolume")) {
+ func = set_volume;
+ }
+
+ if (func) {
+ if (http) {
+ stream->write_function(stream, "<pre>");
}
- }
-
- if (func) {
- status = func(&argv[lead], argc - lead, stream);
- } else {
+ status = func(&argv[lead], argc - lead, stream);
+ if (http) {
+ stream->write_function(stream, "\n\n</pre>");
+ }
+ } else {
if (devname) {
if (devval > 0) {
stream->write_function(stream, "%s set to %d\n", devname, devval);
@@ -1822,13 +1818,52 @@
} else {
stream->write_function(stream, "Unknown Command [%s]\n", argv[0]);
}
- }
+ }
+
+ done:
- done:
+ if (http) {
- switch_safe_free(mycmd);
+ stream->write_function(stream,
+ "<br><br><table align=center><tr><td><center><form method=post>\n"
+ "<input type=text name=wcmd size=40><br><br>\n"
+
+ "<input name=action type=submit value=\"call\"> "
+ "<input name=action type=submit value=\"hangup\"> "
+ "<input name=action type=submit value=\"list\"> "
+ "<input name=action type=submit value=\"switch\"> "
+ "<input name=action type=submit value=\"mute\"> "
+ "<input name=action type=submit value=\"unmute\"> "
+ "<input name=action type=submit value=\"answer\"> <br><br>"
+ "<table border=1>\n"
+ "<tr><td><input name=action type=submit value=\"1\"></td>"
+ "<td><input name=action type=submit value=\"2\"></td>"
+ "<td><input name=action type=submit value=\"3\"></td>\n"
+ "<td><input name=action type=submit value=\"A\"></td></tr>\n"
+
+ "<tr><td><input name=action type=submit value=\"4\"></td>"
+ "<td><input name=action type=submit value=\"5\"></td>"
+ "<td><input name=action type=submit value=\"6\"></td>\n"
+ "<td><input name=action type=submit value=\"B\"></td></tr>\n"
+
+ "<tr><td><input name=action type=submit value=\"7\"></td>"
+ "<td><input name=action type=submit value=\"8\"></td>"
+ "<td><input name=action type=submit value=\"9\"></td>\n"
+ "<td><input name=action type=submit value=\"C\"></td></tr>\n"
+
+ "<tr><td><input name=action type=submit value=\"*\"></td>"
+ "<td><input name=action type=submit value=\"0\"></td>"
+ "<td><input name=action type=submit value=\"#\"></td>\n"
+ "<td><input name=action type=submit value=\"D\"></td></tr>\n"
+ "</table>"
+
+ "</form><br></center></td></tr></table>\n"
+ );
+ }
- return status;
+ switch_safe_free(mycmd);
+
+ return status;
}
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.c Fri Aug 24 13:50:56 2007
@@ -81,24 +81,25 @@
# define PaUtil_WriteMemoryBarrier()
#else
-#if defined(__APPLE__) //|| defined(__FreeBSD__)
+#if defined(__APPLE__) //|| defined(__FreeBSD__)
# include <libkern/OSAtomic.h>
- /* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
- full memory barriers, so the three types of barriers are the same. */
+ /* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
+ full memory barriers, so the three types of barriers are the same. */
# define PaUtil_FullMemoryBarrier() OSMemoryBarrier()
# define PaUtil_ReadMemoryBarrier() OSMemoryBarrier()
# define PaUtil_WriteMemoryBarrier() OSMemoryBarrier()
#elif defined(__GNUC__)
- /* GCC understands volatile asm and "memory" to mean it
- * should not reorder memory read/writes */
+
+ /* GCC understands volatile asm and "memory" to mean it
+ * should not reorder memory read/writes */
# if defined( __PPC__ )
-# define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory")
-# define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory")
-# define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory")
+# define PaUtil_FullMemoryBarrier() __asm__ volatile("sync":::"memory")
+# define PaUtil_ReadMemoryBarrier() __asm__ volatile("sync":::"memory")
+# define PaUtil_WriteMemoryBarrier() __asm__ volatile("sync":::"memory")
# elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ ) || defined(__x86_64__)
-# define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory")
-# define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory")
-# define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory")
+# define PaUtil_FullMemoryBarrier() __asm__ volatile("mfence":::"memory")
+# define PaUtil_ReadMemoryBarrier() __asm__ volatile("lfence":::"memory")
+# define PaUtil_WriteMemoryBarrier() __asm__ volatile("sfence":::"memory")
# else
# define PaUtil_FullMemoryBarrier()
# define PaUtil_ReadMemoryBarrier()
@@ -122,37 +123,39 @@
* Initialize FIFO.
* numBytes must be power of 2, returns -1 if not.
*/
-long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr )
+long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr)
{
- if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
- rbuf->bufferSize = numBytes;
- rbuf->buffer = (char *)dataPtr;
- PaUtil_FlushRingBuffer( rbuf );
- rbuf->bigMask = (numBytes*2)-1;
- rbuf->smallMask = (numBytes)-1;
- return 0;
+ if (((numBytes - 1) & numBytes) != 0)
+ return -1; /* Not Power of two. */
+ rbuf->bufferSize = numBytes;
+ rbuf->buffer = (char *) dataPtr;
+ PaUtil_FlushRingBuffer(rbuf);
+ rbuf->bigMask = (numBytes * 2) - 1;
+ rbuf->smallMask = (numBytes) - 1;
+ return 0;
}
/***************************************************************************
** Return number of bytes available for reading. */
-long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf )
+long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf)
{
- PaUtil_ReadMemoryBarrier();
- return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
+ PaUtil_ReadMemoryBarrier();
+ return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask);
}
+
/***************************************************************************
** Return number of bytes available for writing. */
-long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf )
+long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf)
{
- /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
- return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
+ /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
+ return (rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
}
/***************************************************************************
** Clear buffer. Should only be called when buffer is NOT being read. */
-void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
+void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf)
{
- rbuf->writeIndex = rbuf->readIndex = 0;
+ rbuf->writeIndex = rbuf->readIndex = 0;
}
/***************************************************************************
@@ -161,42 +164,38 @@
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or numBytes, whichever is smaller.
*/
-long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 )
-{
- long index;
- long available = PaUtil_GetRingBufferWriteAvailable( rbuf );
- if( numBytes > available ) numBytes = available;
- /* Check to see if write is not contiguous. */
- index = rbuf->writeIndex & rbuf->smallMask;
- if( (index + numBytes) > rbuf->bufferSize )
- {
- /* Write data in two blocks that wrap the buffer. */
- long firstHalf = rbuf->bufferSize - index;
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = firstHalf;
- *dataPtr2 = &rbuf->buffer[0];
- *sizePtr2 = numBytes - firstHalf;
- }
- else
- {
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = numBytes;
- *dataPtr2 = NULL;
- *sizePtr2 = 0;
- }
- return numBytes;
+long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2)
+{
+ long index;
+ long available = PaUtil_GetRingBufferWriteAvailable(rbuf);
+ if (numBytes > available)
+ numBytes = available;
+ /* Check to see if write is not contiguous. */
+ index = rbuf->writeIndex & rbuf->smallMask;
+ if ((index + numBytes) > rbuf->bufferSize) {
+ /* Write data in two blocks that wrap the buffer. */
+ long firstHalf = rbuf->bufferSize - index;
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = numBytes - firstHalf;
+ } else {
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = numBytes;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return numBytes;
}
/***************************************************************************
*/
-long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes )
+long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes)
{
- /* we need to ensure that previous writes are seen before we update the write index */
- PaUtil_WriteMemoryBarrier();
- return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
+ /* we need to ensure that previous writes are seen before we update the write index */
+ PaUtil_WriteMemoryBarrier();
+ return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
}
/***************************************************************************
@@ -205,81 +204,72 @@
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or numBytes, whichever is smaller.
*/
-long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 )
-{
- long index;
- long available = PaUtil_GetRingBufferReadAvailable( rbuf );
- if( numBytes > available ) numBytes = available;
- /* Check to see if read is not contiguous. */
- index = rbuf->readIndex & rbuf->smallMask;
- if( (index + numBytes) > rbuf->bufferSize )
- {
- /* Write data in two blocks that wrap the buffer. */
- long firstHalf = rbuf->bufferSize - index;
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = firstHalf;
- *dataPtr2 = &rbuf->buffer[0];
- *sizePtr2 = numBytes - firstHalf;
- }
- else
- {
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = numBytes;
- *dataPtr2 = NULL;
- *sizePtr2 = 0;
- }
- return numBytes;
+long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2)
+{
+ long index;
+ long available = PaUtil_GetRingBufferReadAvailable(rbuf);
+ if (numBytes > available)
+ numBytes = available;
+ /* Check to see if read is not contiguous. */
+ index = rbuf->readIndex & rbuf->smallMask;
+ if ((index + numBytes) > rbuf->bufferSize) {
+ /* Write data in two blocks that wrap the buffer. */
+ long firstHalf = rbuf->bufferSize - index;
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = numBytes - firstHalf;
+ } else {
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = numBytes;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return numBytes;
}
+
/***************************************************************************
*/
-long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes )
+long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes)
{
- /* we need to ensure that previous writes are always seen before updating the index. */
- PaUtil_WriteMemoryBarrier();
- return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
+ /* we need to ensure that previous writes are always seen before updating the index. */
+ PaUtil_WriteMemoryBarrier();
+ return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
}
/***************************************************************************
** Return bytes written. */
-long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes )
+long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes)
{
- long size1, size2, numWritten;
- void *data1, *data2;
- numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
- if( size2 > 0 )
- {
-
- memcpy( data1, data, size1 );
- data = ((char *)data) + size1;
- memcpy( data2, data, size2 );
- }
- else
- {
- memcpy( data1, data, size1 );
- }
- PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten );
- return numWritten;
+ long size1, size2, numWritten;
+ void *data1, *data2;
+ numWritten = PaUtil_GetRingBufferWriteRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
+ if (size2 > 0) {
+
+ memcpy(data1, data, size1);
+ data = ((char *) data) + size1;
+ memcpy(data2, data, size2);
+ } else {
+ memcpy(data1, data, size1);
+ }
+ PaUtil_AdvanceRingBufferWriteIndex(rbuf, numWritten);
+ return numWritten;
}
/***************************************************************************
** Return bytes read. */
-long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes )
+long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes)
{
- long size1, size2, numRead;
- void *data1, *data2;
- numRead = PaUtil_GetRingBufferReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
- if( size2 > 0 )
- {
- memcpy( data, data1, size1 );
- data = ((char *)data) + size1;
- memcpy( data, data2, size2 );
- }
- else
- {
- memcpy( data, data1, size1 );
- }
- PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead );
- return numRead;
+ long size1, size2, numRead;
+ void *data1, *data2;
+ numRead = PaUtil_GetRingBufferReadRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
+ if (size2 > 0) {
+ memcpy(data, data1, size1);
+ data = ((char *) data) + size1;
+ memcpy(data, data2, size2);
+ } else {
+ memcpy(data, data1, size1);
+ }
+ PaUtil_AdvanceRingBufferReadIndex(rbuf, numRead);
+ return numRead;
}
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pa_ringbuffer.h Fri Aug 24 13:50:56 2007
@@ -51,19 +51,17 @@
*/
#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef struct PaUtilRingBuffer
-{
- long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
- long writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */
- long readIndex; /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */
- long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */
- long smallMask; /* Used for fitting indices to buffer. */
- char *buffer;
-}PaUtilRingBuffer;
+extern "C" {
+#endif /* __cplusplus */
+
+ typedef struct PaUtilRingBuffer {
+ long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
+ long writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */
+ long readIndex; /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */
+ long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */
+ long smallMask; /* Used for fitting indices to buffer. */
+ char *buffer;
+ } PaUtilRingBuffer;
/** Initialize Ring Buffer.
@@ -76,13 +74,13 @@
@return -1 if numBytes is not a power of 2, otherwise 0.
*/
-long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr );
+ long PaUtil_InitializeRingBuffer(PaUtilRingBuffer * rbuf, long numBytes, void *dataPtr);
/** Clear buffer. Should only be called when buffer is NOT being read.
@param rbuf The ring buffer.
*/
-void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf );
+ void PaUtil_FlushRingBuffer(PaUtilRingBuffer * rbuf);
/** Retrieve the number of bytes available in the ring buffer for writing.
@@ -90,7 +88,7 @@
@return The number of bytes available for writing.
*/
-long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf );
+ long PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer * rbuf);
/** Retrieve the number of bytes available in the ring buffer for reading.
@@ -98,7 +96,7 @@
@return The number of bytes available for reading.
*/
-long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf );
+ long PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer * rbuf);
/** Write data to the ring buffer.
@@ -110,7 +108,7 @@
@return The number of bytes written.
*/
-long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes );
+ long PaUtil_WriteRingBuffer(PaUtilRingBuffer * rbuf, const void *data, long numBytes);
/** Read data from the ring buffer.
@@ -122,7 +120,7 @@
@return The number of bytes read.
*/
-long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes );
+ long PaUtil_ReadRingBuffer(PaUtilRingBuffer * rbuf, void *data, long numBytes);
/** Get address of region(s) to which we can write data.
@@ -144,9 +142,7 @@
@return The room available to be written or numBytes, whichever is smaller.
*/
-long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 );
+ long PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2);
/** Advance the write index to the next location to be written.
@@ -156,7 +152,7 @@
@return The new position.
*/
-long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes );
+ long PaUtil_AdvanceRingBufferWriteIndex(PaUtilRingBuffer * rbuf, long numBytes);
/** Get address of region(s) from which we can write data.
@@ -178,9 +174,7 @@
@return The number of bytes available for reading.
*/
-long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes,
- void **dataPtr1, long *sizePtr1,
- void **dataPtr2, long *sizePtr2 );
+ long PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2);
/** Advance the read index to the next location to be read.
@@ -190,9 +184,9 @@
@return The new position.
*/
-long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes );
+ long PaUtil_AdvanceRingBufferReadIndex(PaUtilRingBuffer * rbuf, long numBytes);
#ifdef __cplusplus
}
-#endif /* __cplusplus */
-#endif /* PA_RINGBUFFER_H */
+#endif /* __cplusplus */
+#endif /* PA_RINGBUFFER_H */
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.c Fri Aug 24 13:50:56 2007
@@ -40,6 +40,7 @@
* license above.
*/
+#include <switch.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
@@ -49,176 +50,181 @@
#include <string.h>
#include <time.h>
-/************************************************************************/
-/******** Constants *****************************************************/
-/************************************************************************/
-
-#define FRAMES_PER_BUFFER (256)
/************************************************************************/
/******** Prototypes ****************************************************/
/************************************************************************/
-static int blockingIOCallback( const void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void *userData );
-static PaError PABLIO_InitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame );
-static PaError PABLIO_TermFIFO( PaUtilRingBuffer *rbuf );
+static int blockingIOCallback(const void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
+static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame);
+static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf);
/************************************************************************/
/******** Functions *****************************************************/
/************************************************************************/
/* Called from PortAudio.
- * Read and write data only if there is room in FIFOs.
+ * Read and write data
*/
-static int blockingIOCallback( const void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void *userData )
+static int blockingIOCallback(const void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
- PABLIO_Stream *data = (PABLIO_Stream*)userData;
- long numBytes = data->bytesPerFrame * framesPerBuffer;
-
- /* This may get called with NULL inputBuffer during initial setup. */
- if( inputBuffer != NULL )
- {
- PaUtil_WriteRingBuffer( &data->inFIFO, inputBuffer, numBytes );
- }
- if( outputBuffer != NULL )
- {
- int i;
- int numRead = PaUtil_ReadRingBuffer( &data->outFIFO, outputBuffer, numBytes );
- /* Zero out remainder of buffer if we run out of data. */
- for( i=numRead; i<numBytes; i++ )
- {
- ((char *)outputBuffer)[i] = 0;
- }
- }
+ PABLIO_Stream *data = (PABLIO_Stream *) userData;
+ long numBytes = data->bytesPerFrame * framesPerBuffer;
+
+ /* This may get called with NULL inputBuffer during initial setup. */
+ if (inputBuffer != NULL) {
+ if (PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes) != numBytes) {
+ PaUtil_FlushRingBuffer(&data->inFIFO);
+ PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes);
+ }
+ }
+ if (outputBuffer != NULL) {
+ int i;
+ int numRead = PaUtil_ReadRingBuffer(&data->outFIFO, outputBuffer, numBytes);
+ /* Zero out remainder of buffer if we run out of data. */
+ for (i = numRead; i < numBytes; i++) {
+ ((char *) outputBuffer)[i] = 0;
+ }
+ }
- return 0;
+ return 0;
}
/* Allocate buffer. */
-static PaError PABLIO_InitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame )
+static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame)
{
- long numBytes = numFrames * bytesPerFrame;
- char *buffer = (char *) malloc( numBytes );
- if( buffer == NULL ) return paInsufficientMemory;
- memset( buffer, 0, numBytes );
- return (PaError) PaUtil_InitializeRingBuffer( rbuf, numBytes, buffer );
+ long numBytes = numFrames * bytesPerFrame;
+ char *buffer = (char *) malloc(numBytes);
+ if (buffer == NULL)
+ return paInsufficientMemory;
+ memset(buffer, 0, numBytes);
+ return (PaError) PaUtil_InitializeRingBuffer(rbuf, numBytes, buffer);
}
/* Free buffer. */
-static PaError PABLIO_TermFIFO( PaUtilRingBuffer *rbuf )
+static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf)
{
- if( rbuf->buffer ) free( rbuf->buffer );
- rbuf->buffer = NULL;
- return paNoError;
+ if (rbuf->buffer)
+ free(rbuf->buffer);
+ rbuf->buffer = NULL;
+ return paNoError;
}
/************************************************************
* Write data to ring buffer.
* Will not return until all the data has been written.
*/
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer)
{
- long bytesWritten;
- char *p = (char *) data;
- long numBytes = aStream->bytesPerFrame * numFrames;
- while( numBytes > 0)
- {
- bytesWritten = PaUtil_WriteRingBuffer( &aStream->outFIFO, p, numBytes );
- numBytes -= bytesWritten;
- p += bytesWritten;
- if( numBytes > 0) Pa_Sleep(10);
- }
- return numFrames;
+ long bytesWritten;
+ char *p = (char *) data;
+ long numBytes = aStream->bytesPerFrame * numFrames;
+
+ while (numBytes > 0) {
+ bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFO, p, numBytes);
+ numBytes -= bytesWritten;
+ p += bytesWritten;
+ if (numBytes > 0) {
+ if (switch_core_timer_check(timer) == SWITCH_STATUS_SUCCESS) {
+ PaUtil_FlushRingBuffer(&aStream->outFIFO);
+ return 0;
+ }
+ switch_yield(1000);
+ }
+ }
+ return numFrames;
}
/************************************************************
* Read data from ring buffer.
* Will not return until all the data has been read.
*/
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer)
{
- long bytesRead;
- char *p = (char *) data;
- long numBytes = aStream->bytesPerFrame * numFrames;
-
- while( numBytes > 0)
- {
- bytesRead = PaUtil_ReadRingBuffer( &aStream->inFIFO, p, numBytes );
- numBytes -= bytesRead;
- p += bytesRead;
- if( numBytes > 0) Pa_Sleep(10);
- }
- return numFrames;
+ long bytesRead;
+ char *p = (char *) data;
+ long numBytes = aStream->bytesPerFrame * numFrames;
+
+ while (numBytes > 0) {
+ bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFO, p, numBytes);
+ numBytes -= bytesRead;
+ if (numBytes > 0) {
+ if (switch_core_timer_check(timer) == SWITCH_STATUS_SUCCESS) {
+ PaUtil_FlushRingBuffer(&aStream->inFIFO);
+ return 0;
+ }
+ switch_yield(1000);
+ }
+ }
+ return numFrames;
}
/************************************************************
* Return the number of frames that could be written to the stream without
* having to wait.
*/
-long GetAudioStreamWriteable( PABLIO_Stream *aStream )
+long GetAudioStreamWriteable(PABLIO_Stream * aStream)
{
- int bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- return bytesEmpty / aStream->bytesPerFrame;
+ int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ return bytesEmpty / aStream->bytesPerFrame;
}
/************************************************************
* Return the number of frames that are available to be read from the
* stream without having to wait.
*/
-long GetAudioStreamReadable( PABLIO_Stream *aStream )
+long GetAudioStreamReadable(PABLIO_Stream * aStream)
{
- int bytesFull = PaUtil_GetRingBufferReadAvailable( &aStream->inFIFO );
- return bytesFull / aStream->bytesPerFrame;
+ int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFO);
+ return bytesFull / aStream->bytesPerFrame;
}
-/************************************************************/
-static unsigned long RoundUpToNextPowerOf2( unsigned long n )
+/***********************************************************/
+static unsigned long RoundUpToNextPowerOf2(unsigned long n)
{
- long numBits = 0;
- if( ((n-1) & n) == 0) return n; /* Already Power of two. */
- while( n > 0 )
- {
- n= n>>1;
- numBits++;
- }
- return (1<<numBits);
+ long numBits = 0;
+ if (((n - 1) & n) == 0)
+ return n;
+ while (n > 0) {
+ n = n >> 1;
+ numBits++;
+ }
+ return (1 << numBits);
}
+
+
/************************************************************
* Opens a PortAudio stream with default characteristics.
* Allocates PABLIO_Stream structure.
*
*/
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr,
- const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters,
- double sampleRate,
- PaStreamFlags streamFlags)
+PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
+ const PaStreamParameters *inputParameters,
+ const PaStreamParameters *outputParameters,
+ double sampleRate,
+ PaStreamFlags streamFlags,
+ long samples_per_frame)
{
- long bytesPerSample;
- PaError err;
- PABLIO_Stream *aStream;
- long minNumBuffers;
- long numFrames;
- long numBytes;
+ long bytesPerSample = 2;
+ PaError err;
+ PABLIO_Stream *aStream;
+ long numFrames;
+ //long numBytes;
int channels = 1;
- /* Allocate PABLIO_Stream structure for caller. */
- aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );
- if( aStream == NULL ) return paInsufficientMemory;
- memset( aStream, 0, sizeof(PABLIO_Stream) );
-
- /* Initialize PortAudio */
- err = Pa_Initialize();
- if( err != paNoError ) goto error;
+ /* Allocate PABLIO_Stream structure for caller. */
+ aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream));
+ if (aStream == NULL)
+ return paInsufficientMemory;
+ memset(aStream, 0, sizeof(PABLIO_Stream));
+
+ /* Initialize PortAudio */
+ err = Pa_Initialize();
+ if (err != paNoError)
+ goto error;
if (inputParameters) {
channels = inputParameters->channelCount;
@@ -226,81 +232,74 @@
channels = outputParameters->channelCount;
}
- numFrames = 4 * FRAMES_PER_BUFFER;
- numFrames = RoundUpToNextPowerOf2( numFrames );
-
- bytesPerSample = 2;
- aStream->samplesPerFrame = channels;
- aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
+ numFrames = RoundUpToNextPowerOf2(samples_per_frame * 5);
+ aStream->bytesPerFrame = bytesPerSample;
- /* Initialize Ring Buffers */
+ /* Initialize Ring Buffers */
if (inputParameters) {
- err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->bytesPerFrame );
- if( err != paNoError ) goto error;
+ err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
+ if (err != paNoError)
+ goto error;
}
if (outputParameters) {
- err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame );
- if( err != paNoError ) goto error;
+ err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
+ if (err != paNoError)
+ goto error;
}
/* Make Write FIFO appear full initially. */
- numBytes = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- PaUtil_AdvanceRingBufferWriteIndex( &aStream->outFIFO, numBytes );
-
+ //numBytes = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ //PaUtil_AdvanceRingBufferWriteIndex(&aStream->outFIFO, numBytes);
+
- /* Open a PortAudio stream that we will use to communicate with the underlying
- * audio drivers. */
- err = Pa_OpenStream(
- &aStream->stream,
- inputParameters,
- outputParameters,
- sampleRate,
- FRAMES_PER_BUFFER,
- streamFlags,
- blockingIOCallback,
- aStream );
- if( err != paNoError ) goto error;
-
- err = Pa_StartStream( aStream->stream );
- if( err != paNoError ) goto error;
- *rwblPtr = aStream;
- return paNoError;
-
-error:
- CloseAudioStream( aStream );
- *rwblPtr = NULL;
- return err;
+ /* Open a PortAudio stream that we will use to communicate with the underlying
+ * audio drivers. */
+ err = Pa_OpenStream(&aStream->stream, inputParameters, outputParameters, sampleRate, samples_per_frame, streamFlags, blockingIOCallback, aStream);
+
+ if (err != paNoError)
+ goto error;
+
+ err = Pa_StartStream(aStream->stream);
+ if (err != paNoError)
+ goto error;
+ *rwblPtr = aStream;
+ return paNoError;
+
+ error:
+ CloseAudioStream(aStream);
+ *rwblPtr = NULL;
+ return err;
}
/************************************************************/
-PaError CloseAudioStream( PABLIO_Stream *aStream )
+PaError CloseAudioStream(PABLIO_Stream * aStream)
{
- PaError err;
- int bytesEmpty;
- int byteSize = aStream->outFIFO.bufferSize;
-
- /* If we are writing data, make sure we play everything written. */
- if( byteSize > 0 )
- {
- bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- while( bytesEmpty < byteSize )
- {
- Pa_Sleep( 10 );
- bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &aStream->outFIFO );
- }
- }
-
- err = Pa_StopStream( aStream->stream );
- if( err != paNoError ) goto error;
- err = Pa_CloseStream( aStream->stream );
- if( err != paNoError ) goto error;
- Pa_Terminate();
-
-error:
- PABLIO_TermFIFO( &aStream->inFIFO );
- PABLIO_TermFIFO( &aStream->outFIFO );
- free( aStream );
- return err;
+ PaError err;
+ int bytesEmpty;
+ int byteSize = aStream->outFIFO.bufferSize;
+
+ /* If we are writing data, make sure we play everything written. */
+ if (byteSize > 0) {
+ bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ while (bytesEmpty < byteSize) {
+ Pa_Sleep(10);
+ bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO);
+ }
+ }
+
+ err = Pa_StopStream(aStream->stream);
+ if (err != paNoError)
+ goto error;
+ err = Pa_CloseStream(aStream->stream);
+ if (err != paNoError)
+ goto error;
+ Pa_Terminate();
+
+ error:
+ PABLIO_TermFIFO(&aStream->inFIFO);
+ PABLIO_TermFIFO(&aStream->outFIFO);
+ free(aStream);
+ return err;
}
Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h
==============================================================================
--- freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h (original)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_portaudio/pablio.h Fri Aug 24 13:50:56 2007
@@ -2,9 +2,8 @@
#define _PABLIO_H
#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+extern "C" {
+#endif /* __cplusplus */
/*
* $Id: pablio.h 1083 2006-08-23 07:30:49Z rossb $
@@ -57,15 +56,12 @@
#include <string.h>
-typedef struct
-{
- PaUtilRingBuffer inFIFO;
- PaUtilRingBuffer outFIFO;
- PaStream *stream;
- int bytesPerFrame;
- int samplesPerFrame;
-}
-PABLIO_Stream;
+ typedef struct {
+ PaUtilRingBuffer inFIFO;
+ PaUtilRingBuffer outFIFO;
+ PaStream *stream;
+ int bytesPerFrame;
+ } PABLIO_Stream;
/* Values for flags for OpenAudioStream(). */
#define PABLIO_READ (1<<0)
@@ -78,25 +74,25 @@
* Write data to ring buffer.
* Will not return until all the data has been written.
*/
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer);
/************************************************************
* Read data from ring buffer.
* Will not return until all the data has been read.
*/
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer);
/************************************************************
* Return the number of frames that could be written to the stream without
* having to wait.
*/
-long GetAudioStreamWriteable( PABLIO_Stream *aStream );
+ long GetAudioStreamWriteable(PABLIO_Stream * aStream);
/************************************************************
* Return the number of frames that are available to be read from the
* stream without having to wait.
*/
-long GetAudioStreamReadable( PABLIO_Stream *aStream );
+ long GetAudioStreamReadable(PABLIO_Stream * aStream);
/************************************************************
* Opens a PortAudio stream with default characteristics.
@@ -106,15 +102,13 @@
* PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
* and either PABLIO_MONO or PABLIO_STEREO
*/
-PaError OpenAudioStream( PABLIO_Stream **rwblPtr,
- const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters,
- double sampleRate,
- PaStreamCallbackFlags statusFlags);
+ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
+ const PaStreamParameters * inputParameters,
+ const PaStreamParameters * outputParameters, double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_frame);
-PaError CloseAudioStream( PABLIO_Stream *aStream );
+ PaError CloseAudioStream(PABLIO_Stream * aStream);
#ifdef __cplusplus
}
-#endif /* __cplusplus */
-#endif /* _PABLIO_H */
+#endif /* __cplusplus */
+#endif /* _PABLIO_H */
1
0
[Freeswitch-branches] [commit] r5651 - in freeswitch/branches/greenlizard/src: . include mod/applications/mod_conference mod/asr_tts/mod_openmrcp mod/endpoints/mod_sofia
by Freeswitch SVN 21 Aug '07
by Freeswitch SVN 21 Aug '07
21 Aug '07
Author: greenlizard
Date: Tue Aug 21 13:44:11 2007
New Revision: 5651
Modified:
freeswitch/branches/greenlizard/src/include/switch_caller.h
freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h
freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c
freeswitch/branches/greenlizard/src/switch_caller.c
Log:
merge trunk 5640:5650
Modified: freeswitch/branches/greenlizard/src/include/switch_caller.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_caller.h (original)
+++ freeswitch/branches/greenlizard/src/include/switch_caller.h Tue Aug 21 13:44:11 2007
@@ -67,16 +67,24 @@
char *caller_id_name;
/*! Caller ID Number */
char *caller_id_number;
+ uint8_t caller_ton;
+ uint8_t caller_numplan;
/*! Caller Network Address (when applicable) */
char *network_addr;
/*! ANI (when applicable) */
char *ani;
+ uint8_t ani_ton;
+ uint8_t ani_numplan;
/*! ANI II (when applicable) */
char *aniii;
/*! RDNIS */
char *rdnis;
+ uint8_t rdnis_ton;
+ uint8_t rdnis_numplan;
/*! Destination Number */
char *destination_number;
+ uint8_t destination_number_ton;
+ uint8_t destination_number_numplan;
/*! channel type */
char *source;
/*! channel name */
Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c Tue Aug 21 13:44:11 2007
@@ -1720,7 +1720,7 @@
switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
}
mux_used = 0;
- } else if (mux_used > bytes * 2) {
+ } else if (mux_used > bytes * 4) {
/* getting behind, clear the buffer */
switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
}
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Tue Aug 21 13:44:11 2007
@@ -1,926 +1,966 @@
-/*
- * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2005/2006, Anthony Minessale II <anthmct(a)yahoo.com>
- *
- * 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 <anthmct(a)yahoo.com>
- * Portions created by the Initial Developer are Copyright (C)
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Traun Leyden <tleyden(a)branchcut.com>
- * Arsen Chaloyan <achaloyan(a)yahoo.com>
- *
- * Module which acts as an MRCP client to an MRCP speech recognition
- * server. In other words it bridges freeswitch to an external speech
- * recognition system. Documentation on how to install and configure
- * the module is here: http://wiki.freeswitch.org/wiki/Mod_openmrcp
- *
- * Uses OpenMrcp (http://wiki.freeswitch.org/wiki/OpenMRCP) as the
- * the client library.
- *
- * TODO
- * =======
- *
- * - There are two memory pools in use. One in asr_session which is managed
- * by this module, and one in the switch_asr_handle_t, which is managed by freeswitch.
- * These need to be consolidated into one. (basically throw away the one in asr_session)
- *
- * - fs status codes (eg, SWITCH_STATUS_GENERR) and mrcp status codes (MRCP_STATUS_FAILURE)
- * are intermixed badly. this needs cleanup
- *
- * - openmrcp_flush_tts, openmrcp_text_param_tts, openmrcp_numeric_param_tts,
- * openmrcp_float_param_tts need to have functionality added
- *
- * - use a regex for extracting xml from raw result received from mrcp recognition
- * server
- *
- */
-
-#ifdef __ICC
-#pragma warning (disable:188)
-#endif
-
-
-#include "openmrcp_client.h"
-#include "mrcp_client_context.h"
-#include "mrcp_recognizer.h"
-#include "mrcp_synthesizer.h"
-#include "mrcp_generic_header.h"
-#include "mrcp_resource_set.h"
-
-#include <switch.h>
-
-#define OPENMRCP_WAIT_TIMEOUT 5000
-#define MY_BUF_LEN 1024 * 128
-#define MY_BLOCK_SIZE MY_BUF_LEN
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load);
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openmrcp_shutdown);
-SWITCH_MODULE_DEFINITION(mod_openmrcp, mod_openmrcp_load,
- mod_openmrcp_shutdown, NULL);
-
-typedef struct {
- char *name;
- openmrcp_client_options_t *mrcp_options;
- mrcp_client_t *mrcp_client;
- mrcp_client_context_t *mrcp_context;
-} openmrcp_profile_t;
-
-typedef struct {
- openmrcp_profile_t *profile;
- mrcp_session_t *client_session;
- mrcp_client_channel_t *control_channel;
- mrcp_audio_channel_t *audio_channel;
- mrcp_message_t *mrcp_message_last_rcvd;
- apr_pool_t *pool;
- switch_speech_flag_t flags;
- switch_mutex_t *flag_mutex;
- switch_thread_cond_t *wait_object;
-} openmrcp_session_t;
-
-typedef enum {
- FLAG_HAS_TEXT = (1 << 0),
- FLAG_BARGE = (1 << 1),
- FLAG_READY = (1 << 2),
- FLAG_SPEAK_COMPLETE = (1 << 3),
- FLAG_FEED_STARTED = (1 << 4),
- FLAG_TERMINATING = (1 << 5)
-} mrcp_flag_t;
-
-typedef struct {
- switch_memory_pool_t *pool;
- switch_hash_t *profile_hash;
-
- openmrcp_profile_t *asr_profile;
- openmrcp_profile_t *tts_profile;
-} openmrcp_module_t;
-
-static openmrcp_module_t openmrcp_module;
-
-
-static openmrcp_session_t* openmrcp_session_create(openmrcp_profile_t *profile)
-{
- openmrcp_session_t *openmrcp_session;
- apr_pool_t *session_pool;
-
- if(!profile) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no profile specified\n");
- return NULL;
- }
-
- if(apr_pool_create(&session_pool,NULL) != APR_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create session_pool\n");
- return NULL;
- }
-
- openmrcp_session = apr_palloc(session_pool,sizeof(openmrcp_session_t));
- openmrcp_session->pool = session_pool;
- openmrcp_session->profile = profile;
- openmrcp_session->client_session = NULL;
- openmrcp_session->control_channel = NULL;
- openmrcp_session->audio_channel = NULL;
- openmrcp_session->mrcp_message_last_rcvd = NULL;
-
- switch_mutex_init(&openmrcp_session->flag_mutex, SWITCH_MUTEX_NESTED, openmrcp_session->pool);
-
- if (switch_thread_cond_create(&openmrcp_session->wait_object, openmrcp_session->pool)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "wait object creation failed\n");
- }
-
- openmrcp_session->client_session = mrcp_client_context_session_create(openmrcp_session->profile->mrcp_context,openmrcp_session);
- if (!openmrcp_session->client_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "session creation FAILED\n");
- apr_pool_destroy(session_pool);
- return NULL;
- }
-
- return openmrcp_session;
-}
-
-static void openmrcp_session_destroy(openmrcp_session_t *openmrcp_session)
-{
- if(openmrcp_session && openmrcp_session->pool) {
- mrcp_client_context_session_destroy(openmrcp_session->profile->mrcp_context,openmrcp_session->client_session);
- apr_pool_destroy(openmrcp_session->pool);
- }
-}
-
-static mrcp_status_t openmrcp_on_session_initiate(mrcp_client_context_t *context, mrcp_session_t *session)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_session_initiate called\n");
- return MRCP_STATUS_SUCCESS;
-}
-
-static mrcp_status_t openmrcp_on_session_terminate(mrcp_client_context_t *context, mrcp_session_t *session)
-{
- openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_session_terminate called\n");
- if(!openmrcp_session) {
- return MRCP_STATUS_FAILURE;
- }
-
- if (switch_test_flag(openmrcp_session, FLAG_TERMINATING)) {
- openmrcp_session_destroy(openmrcp_session);
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "abnormal session terminate\n");
- }
- return MRCP_STATUS_SUCCESS;
-}
-
-static mrcp_status_t openmrcp_on_channel_add(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *control_channel, mrcp_audio_channel_t *audio_channel)
-{
- openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_channel_add called\n");
- if(!openmrcp_session) {
- return MRCP_STATUS_FAILURE;
- }
- switch_mutex_lock(openmrcp_session->flag_mutex);
- openmrcp_session->control_channel = control_channel;
- openmrcp_session->audio_channel = audio_channel;
- switch_thread_cond_signal(openmrcp_session->wait_object);
- switch_mutex_unlock(openmrcp_session->flag_mutex);
- return MRCP_STATUS_SUCCESS;
-}
-
-static mrcp_status_t openmrcp_on_channel_remove(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *control_channel)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_channel_remove called\n");
- return MRCP_STATUS_SUCCESS;
-}
-
-/** this is called by the mrcp core whenever an mrcp message is received from
- the other side. */
-static mrcp_status_t openmrcp_on_channel_modify(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_message_t *mrcp_message)
-{
- openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_channel_modify called\n");
- if (!openmrcp_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!openmrcp_session\n");
- return MRCP_STATUS_FAILURE;
- }
- if (!mrcp_message) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!mrcp_message\n");
- return MRCP_STATUS_FAILURE;
- }
-
- if (mrcp_message->start_line.message_type != MRCP_MESSAGE_TYPE_EVENT) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ignoring mrcp response\n");
- return MRCP_STATUS_SUCCESS;
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mrcp msg body: %s\n", mrcp_message->body);
-
- if (mrcp_message->channel_id.resource_id == MRCP_RESOURCE_RECOGNIZER) {
- if (mrcp_message->start_line.method_id == RECOGNIZER_RECOGNITION_COMPLETE) {
- openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_HAS_TEXT\n");
- switch_set_flag_locked(openmrcp_session, FLAG_HAS_TEXT);
- }
- else if (mrcp_message->start_line.method_id == RECOGNIZER_START_OF_INPUT) {
- openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_BARGE\n");
- switch_set_flag_locked(openmrcp_session, FLAG_BARGE);
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
- }
- }
- else if(mrcp_message->channel_id.resource_id == MRCP_RESOURCE_SYNTHESIZER) {
- if (mrcp_message->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setting FLAG_SPEAK_COMPLETE\n");
- switch_set_flag_locked(openmrcp_session, FLAG_SPEAK_COMPLETE);
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
- }
- }
-
- return MRCP_STATUS_SUCCESS;
-}
-
-/** Read in the grammar and construct an MRCP Recognize message that has
- The grammar attached as the payload */
-static mrcp_status_t openmrcp_recog_start(mrcp_client_context_t *context, openmrcp_session_t *asr_session, char *path)
-{
- mrcp_generic_header_t *generic_header;
- apr_status_t rv;
- apr_file_t *fp;
- apr_pool_t *mp;
- apr_finfo_t finfo;
- char *buf1;
- apr_size_t bytes2read = 0;
-
- mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context, asr_session->client_session, asr_session->control_channel, RECOGNIZER_RECOGNIZE);
-
- if(!mrcp_message) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not create mrcp msg\n");
- return MRCP_STATUS_FAILURE;
- }
-
- /* open the file with the grammar and read into char* buffer */
- mp = mrcp_message->pool;
- if ((rv = apr_file_open(&fp, path, APR_READ, APR_OS_DEFAULT, mp)) != APR_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not read grammar\n");
- return -1;
- }
- rv = apr_file_info_get(&finfo, APR_FINFO_NORM, fp);
-
- buf1 = apr_palloc(mp, (apr_size_t)finfo.size);
- bytes2read = (apr_size_t)finfo.size;
- rv = apr_file_read(fp, buf1, &bytes2read);
- generic_header = mrcp_generic_header_prepare(mrcp_message);
- if(!generic_header) {
- return MRCP_STATUS_FAILURE;
- }
-
- generic_header->content_type = mrcp_str_pdup(mrcp_message->pool,"application/srgs+xml");
- mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE);
- mrcp_message->body = mrcp_str_pdup(mrcp_message->pool,buf1);
-
- /* send the MRCP RECOGNIZE message to MRCP server */
- return mrcp_client_context_channel_modify(context, asr_session->client_session, mrcp_message);
-}
-
-
-/**
- * Freeswitch calls this from switch_ivr_detect_speech() and then adds a media
- * bug to tap into the channel's audio, which will result in all data getting
- * passed to asr_feed() and calls to asr_check_results() on each recevied frame.
- *
- * This code expects certain one-time initialization of the openmrcp client
- * engine/systeme to have already taken place.function to open the asr interface
- */
-static switch_status_t openmrcp_asr_open(switch_asr_handle_t *ah, char *codec, int rate, char *dest, switch_asr_flag_t *flags)
-{
- openmrcp_session_t *asr_session;
- mrcp_client_channel_t *asr_channel;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "asr_open called, codec: %s, rate: %d\n", codec, rate);
-
- if (strcmp(codec,"L16")) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sorry, only L16 codec supported\n");
- return SWITCH_STATUS_GENERR;
- }
- if (rate != 8000) {
- // TODO: look into supporting other sample rates
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sorry, only 8kz supported\n");
- return SWITCH_STATUS_GENERR;
- }
- /* create session */
- asr_session = openmrcp_session_create(openmrcp_module.asr_profile);
- if (!asr_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_session creation FAILED\n");
- return SWITCH_STATUS_GENERR;
- }
-
- /* create recognizer channel, also starts outgoing rtp media */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Create Recognizer Channel\n");
- asr_channel = mrcp_client_recognizer_channel_create(asr_session->profile->mrcp_context, asr_session->client_session, NULL);
- if (!asr_channel) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create recognizer channel\n");
- return SWITCH_STATUS_FALSE;
- }
-
- switch_mutex_lock(asr_session->flag_mutex);
- mrcp_client_context_channel_add(asr_session->profile->mrcp_context, asr_session->client_session, asr_channel, NULL);
- if(switch_thread_cond_timedwait(asr_session->wait_object,asr_session->flag_mutex,5000*1000) != APR_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No response from client stack\n");
- }
- switch_mutex_unlock(asr_session->flag_mutex);
- if(!asr_session->control_channel) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No recognizer channel available\n");
- return SWITCH_STATUS_FALSE;
- }
-
- asr_session->flags = *flags;
- ah->private_info = asr_session;
- return SWITCH_STATUS_SUCCESS;
-}
-
-/* function to load a grammar to the asr interface */
-static switch_status_t openmrcp_asr_load_grammar(switch_asr_handle_t *ah, char *grammar, char *path)
-{
- /** Read grammar from path and create and send and MRCP RECOGNIZE msg
- that has the grammar attached to body.
-
- TODO: - how does DEFINE-GRAMMAR fit into the picture here? (if at all)
- */
-
- openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
- mrcp_client_context_t *context = asr_session->profile->mrcp_context;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Loading grammar\n");
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Start Recognizer\n");
- openmrcp_recog_start(context, asr_session, path);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Finished loading grammar\n");
- return SWITCH_STATUS_SUCCESS;
-}
-
-/*! function to feed audio to the ASR*/
-static switch_status_t openmrcp_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags)
-{
- openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
- media_frame_t media_frame;
- audio_sink_t *audio_sink = mrcp_client_audio_sink_get(asr_session->audio_channel);
-
- media_frame.type = MEDIA_FRAME_TYPE_AUDIO;
- /* sampling rate and frame size should be retrieved from audio sink */
- media_frame.codec_frame.size = 160;
- media_frame.codec_frame.buffer = data;
- while(len >= media_frame.codec_frame.size) {
- if (!audio_sink) {
- return SWITCH_STATUS_GENERR;
- }
- audio_sink->method_set->write_frame(audio_sink,&media_frame);
-
- len -= (unsigned int)media_frame.codec_frame.size;
- media_frame.codec_frame.buffer = (char*)media_frame.codec_frame.buffer + media_frame.codec_frame.size;
- }
- if(len > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "None frame alligned data len [%d]\n",len);
- }
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status_t openmrcp_asr_pause(switch_asr_handle_t *ah)
-{
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_pause called\n");
-
- return SWITCH_STATUS_SUCCESS;
-
-}
-
-static switch_status_t openmrcp_asr_resume(switch_asr_handle_t *ah)
-{
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "openmrcp_asr_resume called\n");
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-/*! function to unload a grammar to the asr interface */
-static switch_status_t openmrcp_asr_unload_grammar(switch_asr_handle_t *ah, char *grammar)
-{
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-/**
- * Freeswitch calls this whenever the channel is hungup or the
- * speech detection is stopped via a call to switch_ivr_stop_detect_speech()
- */
-static switch_status_t openmrcp_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
-{
- openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
- mrcp_client_context_t *context = asr_session->profile->mrcp_context;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_close()\n");
-
- // TODO!! should we do a switch_pool_clear(switch_memory_pool_t *p) on the pool held
- // by asr_session?
-
- // terminate client session
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Going to TERMINATE SESSION\n");
- switch_set_flag_locked(asr_session, FLAG_TERMINATING);
- mrcp_client_context_session_terminate(context, asr_session->client_session);
-
- switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-/**
- * Freeswitch calls this method from the speech_thread() thread body method
- * in switch_ivr_async.c every time a new frame is received by the media bug
- * attached to the audio channel. If this method returns SWITCH_STATUS_SUCCESS,
- * then Freeswitch will call openmrcp_asr_get_results() to get the result value.
- */
-static switch_status_t openmrcp_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
-{
- openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
-
- switch_status_t rv = (switch_test_flag(asr_session, FLAG_HAS_TEXT) || switch_test_flag(asr_session, FLAG_BARGE)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
-
- return rv;
-}
-
-/*! This will be called after asr_check_results returns SUCCESS */
-static switch_status_t openmrcp_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags)
-{
- openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
- switch_status_t ret = SWITCH_STATUS_SUCCESS;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_get_results called\n");
-
- if (switch_test_flag(asr_session, FLAG_BARGE)) {
- switch_clear_flag_locked(asr_session, FLAG_BARGE);
- ret = SWITCH_STATUS_BREAK;
- }
-
- if (switch_test_flag(asr_session, FLAG_HAS_TEXT)) {
- /*!
- we have to extract the XML but stripping off the <?xml version="1.0"?>
- header. the body looks like:
-
- Completion-Cause:001 no-match
- Content-Type: application/nlsml+xml
- Content-Length: 260
-
- <?xml version="1.0"?>
- <result xmlns="http://www.ietf.org/xml/ns/mrcpv2" xmlns:ex="http://www.example.com/example" score="100" grammar="session:request1@form-level.store">
- <interpretation> <input mode="speech">open a</input>
- </interpretation>
- </result>
- */
-
- if(asr_session->mrcp_message_last_rcvd && asr_session->mrcp_message_last_rcvd->body) {
- char *marker = "?>"; // FIXME -- lame and brittle way of doing this. use regex or better.
- char *position = strstr(asr_session->mrcp_message_last_rcvd->body, marker);
- if (!position) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad result received from mrcp server: %s", asr_session->mrcp_message_last_rcvd->body);
- ret = SWITCH_STATUS_FALSE;
- }
- else {
- position += strlen(marker);
- *xmlstr = strdup(position);
- }
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No result received from mrcp server");
- ret = SWITCH_STATUS_FALSE;
- }
-
- // since we are returning our result here, future calls to check_results
- // should return False
- switch_clear_flag_locked(asr_session, FLAG_HAS_TEXT);
- ret = SWITCH_STATUS_SUCCESS;
- }
- return ret;
-}
-
-
-static mrcp_status_t synth_speak(mrcp_client_context_t *context, openmrcp_session_t *tts_session, char *text)
-{
- mrcp_generic_header_t *generic_header;
- mrcp_message_t *mrcp_message;
-
- char *text2speak;
- const char xml_head[] =
- "<?xml version=\"1.0\"?>\r\n"
- "<speak>\r\n"
- "<paragraph>\r\n"
- " <sentence>";
-
- const char xml_tail[] = "</sentence>\r\n"
- "</paragraph>\r\n"
- "</speak>\r\n";
-
- size_t len = sizeof(xml_head) + sizeof(text) + sizeof(xml_tail);
- text2speak = (char *) switch_core_alloc(tts_session->pool, len);
- strcat(text2speak, xml_head);
- strcat(text2speak, text);
- strcat(text2speak, xml_tail);
-
- mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->control_channel,SYNTHESIZER_SPEAK);
- if(!mrcp_message) {
- return MRCP_STATUS_FAILURE;
- }
-
- generic_header = mrcp_generic_header_prepare(mrcp_message);
- if(!generic_header) {
- return MRCP_STATUS_FAILURE;
- }
-
- generic_header->content_type = mrcp_str_pdup(mrcp_message->pool,"application/synthesis+ssml");
- mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE);
- mrcp_message->body = mrcp_str_pdup(mrcp_message->pool,text2speak);
-
- return mrcp_client_context_channel_modify(context,tts_session->client_session,mrcp_message);
-}
-
-static mrcp_status_t synth_stop(mrcp_client_context_t *context, openmrcp_session_t *tts_session)
-{
- mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->control_channel,SYNTHESIZER_STOP);
- if(!mrcp_message) {
- return MRCP_STATUS_FAILURE;
- }
-
- return mrcp_client_context_channel_modify(context,tts_session->client_session,mrcp_message);
-}
-
-
-static switch_status_t openmrcp_tts_open(switch_speech_handle_t *sh, char *voice_name, int rate, switch_speech_flag_t *flags)
-{
- openmrcp_session_t *tts_session;
- mrcp_client_channel_t *tts_channel;
-
- /* create session */
- tts_session = openmrcp_session_create(openmrcp_module.tts_profile);
- if (!tts_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "tts_session creation FAILED\n");
- return SWITCH_STATUS_GENERR;
- }
-
- /* create synthesizer channel */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Create Synthesizer Channel\n");
- tts_channel = mrcp_client_synthesizer_channel_create(tts_session->profile->mrcp_context, tts_session->client_session, NULL);
- if (!tts_channel) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create synthesizer channel\n");
- return SWITCH_STATUS_FALSE;
- }
- switch_mutex_lock(tts_session->flag_mutex);
- mrcp_client_context_channel_add(tts_session->profile->mrcp_context, tts_session->client_session, tts_channel, NULL);
- if(switch_thread_cond_timedwait(tts_session->wait_object,tts_session->flag_mutex,5000*1000) != APR_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No response from client stack\n");
- }
- switch_mutex_unlock(tts_session->flag_mutex);
- if(!tts_session->control_channel) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No synthesizer channel available\n");
- return SWITCH_STATUS_FALSE;
- }
-
- tts_session->flags = *flags;
- sh->private_info = tts_session;
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t openmrcp_tts_close(switch_speech_handle_t *sh, switch_speech_flag_t *flags)
-{
- openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
- mrcp_client_context_t *context = tts_session->profile->mrcp_context;
-
- /* terminate tts session */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "terminate tts_session\n");
- switch_set_flag_locked(tts_session, FLAG_TERMINATING);
- mrcp_client_context_session_terminate(context,tts_session->client_session);
- return SWITCH_STATUS_SUCCESS;
-}
-
-static switch_status_t openmrcp_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags)
-{
- openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
- mrcp_client_context_t *context = tts_session->profile->mrcp_context;
-
- if(!tts_session->control_channel) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no synthesizer channel too feed tts\n");
- return SWITCH_STATUS_FALSE;
- }
-
- synth_speak(context, tts_session, text);
-
- switch_clear_flag(tts_session,FLAG_FEED_STARTED);
- return SWITCH_STATUS_SUCCESS;
-}
-
-/**
- * Freeswitch calls this when its ready to read datalen bytes of data.
- *
- * TODO: check the blocking flag passed in flags and act accordingly
- * (see mod_cepstral.c)
- */
-static switch_status_t openmrcp_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
-{
- openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
- size_t return_len=0;
- media_frame_t media_frame;
- audio_source_t *audio_source;
-
- if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
- /* tell fs we are done */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
- return SWITCH_STATUS_BREAK;
- }
-
- audio_source = mrcp_client_audio_source_get(tts_session->audio_channel);
- if(!audio_source) {
- return SWITCH_STATUS_BREAK;
- }
-
- if (!switch_test_flag(tts_session, FLAG_FEED_STARTED)) {
- switch_set_flag(tts_session, FLAG_FEED_STARTED);
- if(audio_source->method_set->open) {
- audio_source->method_set->open(audio_source);
- }
- }
-
- /* sampling rate and frame size should be retrieved from audio source */
- *rate = 8000;
- media_frame.codec_frame.size = 160;
- while(return_len < *datalen) {
- media_frame.codec_frame.buffer = (char*)data + return_len;
- audio_source->method_set->read_frame(audio_source,&media_frame);
- if(media_frame.type != MEDIA_FRAME_TYPE_AUDIO) {
- memset(media_frame.codec_frame.buffer,0,media_frame.codec_frame.size);
- }
- return_len += media_frame.codec_frame.size;
- }
- *datalen = return_len;
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static void openmrcp_flush_tts(switch_speech_handle_t *sh)
-{
- openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
- mrcp_client_context_t *context = tts_session->profile->mrcp_context;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "flush_tts called\n");
- synth_stop(context,tts_session); // TODO
-}
-
-static void openmrcp_text_param_tts(switch_speech_handle_t *sh, char *param, char *val)
-{
-
-}
-
-static void openmrcp_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val)
-{
-
-}
-
-static void openmrcp_float_param_tts(switch_speech_handle_t *sh, char *param, double val)
-{
-
-}
-
-
-static switch_status_t do_config()
-{
- char *cf = "mod_openmrcp.conf";
- const char *asr_profile_name = NULL;
- const char *tts_profile_name = NULL;
- switch_xml_t cfg, xml, settings, profiles, xprofile, param;
- openmrcp_profile_t *mrcp_profile;
- openmrcp_client_options_t *mrcp_options;
-
- 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;
- }
-
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct(a)yahoo.com>
+ *
+ * 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 <anthmct(a)yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Traun Leyden <tleyden(a)branchcut.com>
+ * Arsen Chaloyan <achaloyan(a)yahoo.com>
+ *
+ * Module which acts as an MRCP client to an MRCP speech recognition
+ * server. In other words it bridges freeswitch to an external speech
+ * recognition system. Documentation on how to install and configure
+ * the module is here: http://wiki.freeswitch.org/wiki/Mod_openmrcp
+ *
+ * Uses OpenMrcp (http://wiki.freeswitch.org/wiki/OpenMRCP) as the
+ * the client library.
+ *
+ * TODO
+ * =======
+ *
+ * - There are two memory pools in use. One in asr_session which is managed
+ * by this module, and one in the switch_asr_handle_t, which is managed by freeswitch.
+ * These need to be consolidated into one. (basically throw away the one in asr_session)
+ *
+ * - fs status codes (eg, SWITCH_STATUS_GENERR) and mrcp status codes (MRCP_STATUS_FAILURE)
+ * are intermixed badly. this needs cleanup
+ *
+ * - openmrcp_flush_tts, openmrcp_text_param_tts, openmrcp_numeric_param_tts,
+ * openmrcp_float_param_tts need to have functionality added
+ *
+ * - use a regex for extracting xml from raw result received from mrcp recognition
+ * server
+ *
+ */
+
+#ifdef __ICC
+#pragma warning (disable:188)
+#endif
+
+
+#include "openmrcp_client.h"
+#include "mrcp_client_context.h"
+#include "mrcp_recognizer.h"
+#include "mrcp_synthesizer.h"
+#include "mrcp_generic_header.h"
+#include "mrcp_resource_set.h"
+
+#include <switch.h>
+
+#define OPENMRCP_WAIT_TIMEOUT 5000
+#define MY_BUF_LEN 1024 * 128
+#define MY_BLOCK_SIZE MY_BUF_LEN
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openmrcp_shutdown);
+SWITCH_MODULE_DEFINITION(mod_openmrcp, mod_openmrcp_load,
+ mod_openmrcp_shutdown, NULL);
+
+typedef struct {
+ char *name;
+ openmrcp_client_options_t *mrcp_options;
+ mrcp_client_t *mrcp_client;
+ mrcp_client_context_t *mrcp_context;
+} openmrcp_profile_t;
+
+typedef struct {
+ openmrcp_profile_t *profile;
+ mrcp_session_t *client_session;
+ mrcp_client_channel_t *control_channel;
+ mrcp_audio_channel_t *audio_channel;
+ mrcp_message_t *mrcp_message_last_rcvd;
+ apr_pool_t *pool;
+ switch_speech_flag_t flags;
+ switch_mutex_t *flag_mutex;
+ switch_thread_cond_t *wait_object;
+} openmrcp_session_t;
+
+typedef enum {
+ FLAG_HAS_TEXT = (1 << 0),
+ FLAG_BARGE = (1 << 1),
+ FLAG_READY = (1 << 2),
+ FLAG_SPEAK_COMPLETE = (1 << 3),
+ FLAG_FEED_STARTED = (1 << 4),
+ FLAG_TERMINATING = (1 << 5)
+} mrcp_flag_t;
+
+typedef struct {
+ switch_memory_pool_t *pool;
+ switch_hash_t *profile_hash;
+
+ openmrcp_profile_t *asr_profile;
+ openmrcp_profile_t *tts_profile;
+} openmrcp_module_t;
+
+static openmrcp_module_t openmrcp_module;
+
+
+static openmrcp_session_t* openmrcp_session_create(openmrcp_profile_t *profile)
+{
+ openmrcp_session_t *openmrcp_session;
+ apr_pool_t *session_pool;
+
+ if(!profile) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no profile specified\n");
+ return NULL;
+ }
+
+ if(apr_pool_create(&session_pool,NULL) != APR_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create session_pool\n");
+ return NULL;
+ }
+
+ openmrcp_session = apr_palloc(session_pool,sizeof(openmrcp_session_t));
+ openmrcp_session->pool = session_pool;
+ openmrcp_session->profile = profile;
+ openmrcp_session->client_session = NULL;
+ openmrcp_session->control_channel = NULL;
+ openmrcp_session->audio_channel = NULL;
+ openmrcp_session->mrcp_message_last_rcvd = NULL;
+
+ switch_mutex_init(&openmrcp_session->flag_mutex, SWITCH_MUTEX_NESTED, openmrcp_session->pool);
+
+ if (switch_thread_cond_create(&openmrcp_session->wait_object, openmrcp_session->pool)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "wait object creation failed\n");
+ }
+
+ openmrcp_session->client_session = mrcp_client_context_session_create(openmrcp_session->profile->mrcp_context,openmrcp_session);
+ if (!openmrcp_session->client_session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "session creation FAILED\n");
+ apr_pool_destroy(session_pool);
+ return NULL;
+ }
+
+ return openmrcp_session;
+}
+
+static void openmrcp_session_destroy(openmrcp_session_t *openmrcp_session)
+{
+ if(openmrcp_session && openmrcp_session->pool) {
+ mrcp_client_context_session_destroy(openmrcp_session->profile->mrcp_context,openmrcp_session->client_session);
+ apr_pool_destroy(openmrcp_session->pool);
+ }
+}
+
+static mrcp_status_t openmrcp_on_session_initiate(mrcp_client_context_t *context, mrcp_session_t *session)
+{
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_session_initiate called\n");
+ return MRCP_STATUS_SUCCESS;
+}
+
+static mrcp_status_t openmrcp_on_session_terminate(mrcp_client_context_t *context, mrcp_session_t *session)
+{
+ openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_session_terminate called\n");
+ if(!openmrcp_session) {
+ return MRCP_STATUS_FAILURE;
+ }
+
+ if (switch_test_flag(openmrcp_session, FLAG_TERMINATING)) {
+ openmrcp_session_destroy(openmrcp_session);
+ }
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "abnormal session terminate\n");
+ }
+ return MRCP_STATUS_SUCCESS;
+}
+
+static mrcp_status_t openmrcp_on_channel_add(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *control_channel, mrcp_audio_channel_t *audio_channel)
+{
+ openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_channel_add called\n");
+ if(!openmrcp_session) {
+ return MRCP_STATUS_FAILURE;
+ }
+ switch_mutex_lock(openmrcp_session->flag_mutex);
+ openmrcp_session->control_channel = control_channel;
+ openmrcp_session->audio_channel = audio_channel;
+ switch_thread_cond_signal(openmrcp_session->wait_object);
+ switch_mutex_unlock(openmrcp_session->flag_mutex);
+ return MRCP_STATUS_SUCCESS;
+}
+
+static mrcp_status_t openmrcp_on_channel_remove(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *control_channel)
+{
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_channel_remove called\n");
+ return MRCP_STATUS_SUCCESS;
+}
+
+/** this is called by the mrcp core whenever an mrcp message is received from
+ the other side. */
+static mrcp_status_t openmrcp_on_channel_modify(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_message_t *mrcp_message)
+{
+ openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_channel_modify called\n");
+ if (!openmrcp_session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!openmrcp_session\n");
+ return MRCP_STATUS_FAILURE;
+ }
+ if (!mrcp_message) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!mrcp_message\n");
+ return MRCP_STATUS_FAILURE;
+ }
+
+ if (mrcp_message->start_line.message_type != MRCP_MESSAGE_TYPE_EVENT) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ignoring mrcp response\n");
+ return MRCP_STATUS_SUCCESS;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mrcp msg body: %s\n", mrcp_message->body);
+
+ if (mrcp_message->channel_id.resource_id == MRCP_RESOURCE_RECOGNIZER) {
+ if (mrcp_message->start_line.method_id == RECOGNIZER_RECOGNITION_COMPLETE) {
+ openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_HAS_TEXT\n");
+ switch_set_flag_locked(openmrcp_session, FLAG_HAS_TEXT);
+ }
+ else if (mrcp_message->start_line.method_id == RECOGNIZER_START_OF_INPUT) {
+ openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_BARGE\n");
+ switch_set_flag_locked(openmrcp_session, FLAG_BARGE);
+ }
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
+ }
+ }
+ else if(mrcp_message->channel_id.resource_id == MRCP_RESOURCE_SYNTHESIZER) {
+ if (mrcp_message->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setting FLAG_SPEAK_COMPLETE\n");
+ switch_set_flag_locked(openmrcp_session, FLAG_SPEAK_COMPLETE);
+ }
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
+ }
+ }
+
+ return MRCP_STATUS_SUCCESS;
+}
+
+/** Read in the grammar and construct an MRCP Recognize message that has
+ The grammar attached as the payload */
+static mrcp_status_t openmrcp_recog_start(mrcp_client_context_t *context, openmrcp_session_t *asr_session, char *path)
+{
+ mrcp_generic_header_t *generic_header;
+ apr_status_t rv;
+ apr_file_t *fp;
+ apr_pool_t *mp;
+ apr_finfo_t finfo;
+ char *buf1;
+ apr_size_t bytes2read = 0;
+
+ mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context, asr_session->client_session, asr_session->control_channel, RECOGNIZER_RECOGNIZE);
+
+ if(!mrcp_message) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not create mrcp msg\n");
+ return MRCP_STATUS_FAILURE;
+ }
+
+ /* open the file with the grammar and read into char* buffer */
+ mp = mrcp_message->pool;
+ if ((rv = apr_file_open(&fp, path, APR_READ, APR_OS_DEFAULT, mp)) != APR_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not read grammar\n");
+ return -1;
+ }
+ rv = apr_file_info_get(&finfo, APR_FINFO_NORM, fp);
+
+ buf1 = apr_palloc(mp, (apr_size_t)finfo.size + 1);
+ bytes2read = (apr_size_t)finfo.size;
+ rv = apr_file_read(fp, buf1, &bytes2read);
+ buf1[bytes2read] = '\0';
+
+ generic_header = mrcp_generic_header_prepare(mrcp_message);
+ if(!generic_header) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not prepare generic_header\n");
+ return MRCP_STATUS_FAILURE;
+ }
+
+ generic_header->content_type = "application/srgs+xml";
+ mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE);
+ mrcp_message->body = buf1;
+
+ /* send the MRCP RECOGNIZE message to MRCP server */
+ return mrcp_client_context_channel_modify(context, asr_session->client_session, mrcp_message);
+}
+
+
+/**
+ * Freeswitch calls this from switch_ivr_detect_speech() and then adds a media
+ * bug to tap into the channel's audio, which will result in all data getting
+ * passed to asr_feed() and calls to asr_check_results() on each recevied frame.
+ *
+ * This code expects certain one-time initialization of the openmrcp client
+ * engine/systeme to have already taken place.function to open the asr interface
+ */
+static switch_status_t openmrcp_asr_open(switch_asr_handle_t *ah, char *codec, int rate, char *dest, switch_asr_flag_t *flags)
+{
+ openmrcp_session_t *asr_session;
+ mrcp_client_channel_t *asr_channel;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "asr_open called, codec: %s, rate: %d\n", codec, rate);
+
+ if (strcmp(codec,"L16")) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sorry, only L16 codec supported\n");
+ return SWITCH_STATUS_GENERR;
+ }
+ if (rate != 8000) {
+ // TODO: look into supporting other sample rates
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sorry, only 8kz supported\n");
+ return SWITCH_STATUS_GENERR;
+ }
+ /* create session */
+ asr_session = openmrcp_session_create(openmrcp_module.asr_profile);
+ if (!asr_session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_session creation FAILED\n");
+ return SWITCH_STATUS_GENERR;
+ }
+
+ /* create recognizer channel, also starts outgoing rtp media */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Create Recognizer Channel\n");
+ asr_channel = mrcp_client_recognizer_channel_create(asr_session->profile->mrcp_context, asr_session->client_session, NULL);
+ if (!asr_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create recognizer channel\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ switch_mutex_lock(asr_session->flag_mutex);
+ mrcp_client_context_channel_add(asr_session->profile->mrcp_context, asr_session->client_session, asr_channel, NULL);
+ if(switch_thread_cond_timedwait(asr_session->wait_object,asr_session->flag_mutex,5000*1000) != APR_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No response from client stack\n");
+ }
+ switch_mutex_unlock(asr_session->flag_mutex);
+ if(!asr_session->control_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No recognizer channel available\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ asr_session->flags = *flags;
+ ah->private_info = asr_session;
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/* function to load a grammar to the asr interface */
+static switch_status_t openmrcp_asr_load_grammar(switch_asr_handle_t *ah, char *grammar, char *path)
+{
+ /** Read grammar from path and create and send and MRCP RECOGNIZE msg
+ that has the grammar attached to body.
+
+ TODO: - how does DEFINE-GRAMMAR fit into the picture here? (if at all)
+ */
+
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+ mrcp_client_context_t *context = asr_session->profile->mrcp_context;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Loading grammar\n");
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Start Recognizer\n");
+ openmrcp_recog_start(context, asr_session, path);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Finished loading grammar\n");
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/*! function to feed audio to the ASR*/
+static switch_status_t openmrcp_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags)
+{
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+ media_frame_t media_frame;
+ audio_sink_t *audio_sink = mrcp_client_audio_sink_get(asr_session->audio_channel);
+
+ media_frame.type = MEDIA_FRAME_TYPE_AUDIO;
+ /* sampling rate and frame size should be retrieved from audio sink */
+ media_frame.codec_frame.size = 160;
+ media_frame.codec_frame.buffer = data;
+ while(len >= media_frame.codec_frame.size) {
+ if (!audio_sink) {
+ /*!
+ If there is no audio_sink established yet, discard the audio and
+ return SUCCESS. returning anything other than success causes freeswitch
+ to abort the call and tear down the channel. One reason there might
+ not be an audio sink is that the openmrcp client lib is still in the startup
+ process.
+ */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "!audio_sink\n");
+ return SWITCH_STATUS_SUCCESS;
+ }
+ audio_sink->method_set->write_frame(audio_sink,&media_frame);
+
+ len -= (unsigned int)media_frame.codec_frame.size;
+ media_frame.codec_frame.buffer = (char*)media_frame.codec_frame.buffer + media_frame.codec_frame.size;
+ }
+ if(len > 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "None frame alligned data len [%d]\n",len);
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_status_t openmrcp_asr_pause(switch_asr_handle_t *ah)
+{
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_pause called\n");
+
+ return SWITCH_STATUS_SUCCESS;
+
+}
+
+static switch_status_t openmrcp_asr_resume(switch_asr_handle_t *ah)
+{
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "openmrcp_asr_resume called\n");
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+/*! function to unload a grammar to the asr interface */
+static switch_status_t openmrcp_asr_unload_grammar(switch_asr_handle_t *ah, char *grammar)
+{
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/**
+ * Freeswitch calls this whenever the channel is hungup or the
+ * speech detection is stopped via a call to switch_ivr_stop_detect_speech()
+ */
+static switch_status_t openmrcp_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
+{
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+ mrcp_client_context_t *context = asr_session->profile->mrcp_context;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_close()\n");
+
+ // TODO!! should we do a switch_pool_clear(switch_memory_pool_t *p) on the pool held
+ // by asr_session?
+
+ // terminate client session
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Going to TERMINATE SESSION\n");
+ switch_set_flag_locked(asr_session, FLAG_TERMINATING);
+ mrcp_client_context_session_terminate(context, asr_session->client_session);
+
+ switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+/**
+ * Freeswitch calls this method from the speech_thread() thread body method
+ * in switch_ivr_async.c every time a new frame is received by the media bug
+ * attached to the audio channel. If this method returns SWITCH_STATUS_SUCCESS,
+ * then Freeswitch will call openmrcp_asr_get_results() to get the result value.
+ */
+static switch_status_t openmrcp_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
+{
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+
+ switch_status_t rv = (switch_test_flag(asr_session, FLAG_HAS_TEXT) || switch_test_flag(asr_session, FLAG_BARGE)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+
+ return rv;
+}
+
+/*! This will be called after asr_check_results returns SUCCESS */
+static switch_status_t openmrcp_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags)
+{
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+ switch_status_t ret = SWITCH_STATUS_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_get_results called\n");
+
+ if (switch_test_flag(asr_session, FLAG_BARGE)) {
+ switch_clear_flag_locked(asr_session, FLAG_BARGE);
+ ret = SWITCH_STATUS_BREAK;
+ }
+
+ if (switch_test_flag(asr_session, FLAG_HAS_TEXT)) {
+ /*!
+ we have to extract the XML but stripping off the <?xml version="1.0"?>
+ header. the body looks like:
+
+ Completion-Cause:001 no-match
+ Content-Type: application/nlsml+xml
+ Content-Length: 260
+
+ <?xml version="1.0"?>
+ <result xmlns="http://www.ietf.org/xml/ns/mrcpv2" xmlns:ex="http://www.example.com/example" score="100" grammar="session:request1@form-level.store">
+ <interpretation> <input mode="speech">open a</input>
+ </interpretation>
+ </result>
+ */
+
+ if(asr_session->mrcp_message_last_rcvd && asr_session->mrcp_message_last_rcvd->body) {
+ char *marker = "?>"; // FIXME -- lame and brittle way of doing this. use regex or better.
+ char *position = strstr(asr_session->mrcp_message_last_rcvd->body, marker);
+ if (!position) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad result received from mrcp server: %s", asr_session->mrcp_message_last_rcvd->body);
+ ret = SWITCH_STATUS_FALSE;
+ }
+ else {
+ position += strlen(marker);
+ *xmlstr = strdup(position);
+ }
+ }
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No result received from mrcp server\n");
+ ret = SWITCH_STATUS_FALSE;
+ }
+
+ // since we are returning our result here, future calls to check_results
+ // should return False
+ switch_clear_flag_locked(asr_session, FLAG_HAS_TEXT);
+ ret = SWITCH_STATUS_SUCCESS;
+ }
+ return ret;
+}
+
+
+static mrcp_status_t synth_speak(mrcp_client_context_t *context, openmrcp_session_t *tts_session, char *text)
+{
+ mrcp_generic_header_t *generic_header;
+ mrcp_message_t *mrcp_message;
+
+ char *text2speak;
+ const char xml_head[] =
+ "<?xml version=\"1.0\"?>\r\n"
+ "<speak>\r\n"
+ "<paragraph>\r\n"
+ " <sentence>";
+
+ const char xml_tail[] = "</sentence>\r\n"
+ "</paragraph>\r\n"
+ "</speak>\r\n";
+
+ size_t len = sizeof(xml_head) + sizeof(text) + sizeof(xml_tail);
+ text2speak = (char *) switch_core_alloc(tts_session->pool, len);
+ strcat(text2speak, xml_head);
+ strcat(text2speak, text);
+ strcat(text2speak, xml_tail);
+
+ mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->control_channel,SYNTHESIZER_SPEAK);
+ if(!mrcp_message) {
+ return MRCP_STATUS_FAILURE;
+ }
+
+ generic_header = mrcp_generic_header_prepare(mrcp_message);
+ if(!generic_header) {
+ return MRCP_STATUS_FAILURE;
+ }
+
+ generic_header->content_type = "application/synthesis+ssml";
+ mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE);
+ mrcp_message->body = text2speak;
+
+ return mrcp_client_context_channel_modify(context,tts_session->client_session,mrcp_message);
+}
+
+static mrcp_status_t synth_stop(mrcp_client_context_t *context, openmrcp_session_t *tts_session)
+{
+ mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->control_channel,SYNTHESIZER_STOP);
+ if(!mrcp_message) {
+ return MRCP_STATUS_FAILURE;
+ }
+
+ return mrcp_client_context_channel_modify(context,tts_session->client_session,mrcp_message);
+}
+
+
+static switch_status_t openmrcp_tts_open(switch_speech_handle_t *sh, char *voice_name, int rate, switch_speech_flag_t *flags)
+{
+ openmrcp_session_t *tts_session;
+ mrcp_client_channel_t *tts_channel;
+
+ /* create session */
+ tts_session = openmrcp_session_create(openmrcp_module.tts_profile);
+ if (!tts_session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "tts_session creation FAILED\n");
+ return SWITCH_STATUS_GENERR;
+ }
+
+ /* create synthesizer channel */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Create Synthesizer Channel\n");
+ tts_channel = mrcp_client_synthesizer_channel_create(tts_session->profile->mrcp_context, tts_session->client_session, NULL);
+ if (!tts_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create synthesizer channel\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ switch_mutex_lock(tts_session->flag_mutex);
+ mrcp_client_context_channel_add(tts_session->profile->mrcp_context, tts_session->client_session, tts_channel, NULL);
+ if(switch_thread_cond_timedwait(tts_session->wait_object,tts_session->flag_mutex,5000*1000) != APR_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No response from client stack\n");
+ }
+ switch_mutex_unlock(tts_session->flag_mutex);
+ if(!tts_session->control_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No synthesizer channel available\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ tts_session->flags = *flags;
+ sh->private_info = tts_session;
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t openmrcp_tts_close(switch_speech_handle_t *sh, switch_speech_flag_t *flags)
+{
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
+ mrcp_client_context_t *context = tts_session->profile->mrcp_context;
+
+ /* terminate tts session */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "terminate tts_session\n");
+ switch_set_flag_locked(tts_session, FLAG_TERMINATING);
+ mrcp_client_context_session_terminate(context,tts_session->client_session);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t openmrcp_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags)
+{
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
+ mrcp_client_context_t *context = tts_session->profile->mrcp_context;
+
+ if(!tts_session->control_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no synthesizer channel too feed tts\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ synth_speak(context, tts_session, text);
+
+ switch_clear_flag(tts_session,FLAG_FEED_STARTED);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/**
+ * Freeswitch calls this when its ready to read datalen bytes of data.
+ *
+ * TODO: check the blocking flag passed in flags and act accordingly
+ * (see mod_cepstral.c)
+ */
+static switch_status_t openmrcp_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
+{
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
+ size_t return_len=0;
+ media_frame_t media_frame;
+ audio_source_t *audio_source;
+
+ if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
+ /* tell fs we are done */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
+ return SWITCH_STATUS_BREAK;
+ }
+
+ audio_source = mrcp_client_audio_source_get(tts_session->audio_channel);
+ if(!audio_source) {
+ return SWITCH_STATUS_BREAK;
+ }
+
+ if (!switch_test_flag(tts_session, FLAG_FEED_STARTED)) {
+ switch_set_flag(tts_session, FLAG_FEED_STARTED); // shouldn't this use set_flag_locked? -tl
+ if(audio_source->method_set->open) {
+ audio_source->method_set->open(audio_source);
+ }
+ }
+
+ /* sampling rate and frame size should be retrieved from audio source */
+ *rate = 8000;
+ media_frame.codec_frame.size = 160;
+ while(return_len < *datalen) {
+ media_frame.codec_frame.buffer = (char*)data + return_len;
+ audio_source->method_set->read_frame(audio_source,&media_frame);
+ if(media_frame.type != MEDIA_FRAME_TYPE_AUDIO) {
+ memset(media_frame.codec_frame.buffer,0,media_frame.codec_frame.size);
+ }
+ return_len += media_frame.codec_frame.size;
+ }
+ *datalen = return_len;
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+static void openmrcp_flush_tts(switch_speech_handle_t *sh)
+{
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
+ mrcp_client_context_t *context = tts_session->profile->mrcp_context;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "flush_tts called\n");
+ synth_stop(context,tts_session); // TODO
+}
+
+static void openmrcp_text_param_tts(switch_speech_handle_t *sh, char *param, char *val)
+{
+
+}
+
+static void openmrcp_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val)
+{
+
+}
+
+static void openmrcp_float_param_tts(switch_speech_handle_t *sh, char *param, double val)
+{
+
+}
+
+
+static switch_status_t do_config()
+{
+ char *cf = "mod_openmrcp.conf";
+ const char *asr_profile_name = NULL;
+ const char *tts_profile_name = NULL;
+ switch_xml_t cfg, xml, settings, profiles, xprofile, param;
+ openmrcp_profile_t *mrcp_profile;
+ openmrcp_client_options_t *mrcp_options;
+
+ 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;
+ }
+
mrcp_logger.priority = MRCP_PRIO_EMERGENCY;
- if ((settings = switch_xml_child(cfg, "settings"))) {
- for (param = switch_xml_child(settings, "param"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "value");
-
- if (!strcasecmp(var, "asr_default_profile")) {
- asr_profile_name = val;
- } else if (!strcasecmp(var, "tts_default_profile")) {
- tts_profile_name = val;
- } else if (!strcasecmp(var, "log_level")) {
+ if ((settings = switch_xml_child(cfg, "settings"))) {
+ for (param = switch_xml_child(settings, "param"); param; param = param->next) {
+ const char *var = switch_xml_attr_soft(param, "name");
+ const char *val = switch_xml_attr_soft(param, "value");
+
+ if (!strcasecmp(var, "asr_default_profile")) {
+ asr_profile_name = val;
+ } else if (!strcasecmp(var, "tts_default_profile")) {
+ tts_profile_name = val;
+ } else if (!strcasecmp(var, "log_level")) {
mrcp_logger.priority = atoi(val);
- }
- }
- }
- else {
- goto error;
- }
- if ((profiles = switch_xml_child(cfg, "profiles"))) {
- for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
- const char *profile_name = switch_xml_attr_soft(xprofile, "name");
- mrcp_profile = switch_core_alloc(openmrcp_module.pool,sizeof(openmrcp_profile_t));
- mrcp_profile->mrcp_client = NULL;
- mrcp_profile->mrcp_context = NULL;
- mrcp_profile->name = "noname";
- if(profile_name) {
- mrcp_profile->name = switch_core_strdup(openmrcp_module.pool,profile_name);
- }
-
- mrcp_options = openmrcp_client_options_create(openmrcp_module.pool);
- for (param = switch_xml_child(xprofile, "param"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "value");
-
- if (!strcasecmp(var, "proto_version")) {
- mrcp_options->proto_version =(mrcp_version_t) atoi(val);
- }
- else if (!strcasecmp(var, "client_ip")) {
- mrcp_options->client_ip = switch_core_strdup(openmrcp_module.pool,val);
- } else if (!strcasecmp(var, "server_ip")) {
- mrcp_options->server_ip = switch_core_strdup(openmrcp_module.pool,val);
- } else if (!strcasecmp(var, "client_port")) {
- mrcp_options->client_port = (apr_port_t) atoi(val);
- } else if (!strcasecmp(var, "server_port")) {
- mrcp_options->server_port = (apr_port_t) atoi(val);
- } else if (!strcasecmp(var, "rtp_port_min")) {
- mrcp_options->rtp_port_min = (apr_port_t) atoi(val);
- } else if (!strcasecmp(var, "rtp_port_max")) {
- mrcp_options->rtp_port_max = (apr_port_t) atoi(val);
- }
- }
- mrcp_profile->mrcp_options = mrcp_options;
-
- /* add profile */
- if (!switch_core_hash_find(openmrcp_module.profile_hash, mrcp_profile->name)) {
- switch_core_hash_insert(openmrcp_module.profile_hash, mrcp_profile->name, mrcp_profile);
-
- /* try to set default asr profile */
- if (!openmrcp_module.asr_profile) {
- if (asr_profile_name) {
- if (!strcasecmp(mrcp_profile->name,asr_profile_name)) {
- openmrcp_module.asr_profile = mrcp_profile;
- }
- }
- else {
- openmrcp_module.asr_profile = mrcp_profile;
- }
- }
- /* try to set default tts profile */
- if (!openmrcp_module.tts_profile) {
- if (tts_profile_name) {
- if (!strcasecmp(mrcp_profile->name,tts_profile_name)) {
- openmrcp_module.tts_profile = mrcp_profile;
- }
- }
- else {
- openmrcp_module.tts_profile = mrcp_profile;
- }
- }
- }
- }
- }
- else {
- goto error;
- }
-
- switch_xml_free(xml);
- return SWITCH_STATUS_SUCCESS;
-
- error:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load module configuration\n");
- switch_xml_free(xml);
- return SWITCH_STATUS_TERM;
-
-}
-
-static switch_status_t openmrcp_profile_run(openmrcp_profile_t *profile)
-{
- mrcp_client_event_handler_t *mrcp_event_handler;
- mrcp_client_t *mrcp_client;
- mrcp_client_context_t *mrcp_context;
-
- /*!
- Perform one-time initialization of mrcp client library
- */
- mrcp_event_handler = switch_core_alloc(openmrcp_module.pool,sizeof(mrcp_client_event_handler_t));
- mrcp_event_handler->on_session_initiate = openmrcp_on_session_initiate;
- mrcp_event_handler->on_session_terminate = openmrcp_on_session_terminate;
- mrcp_event_handler->on_channel_add = openmrcp_on_channel_add;
- mrcp_event_handler->on_channel_remove = openmrcp_on_channel_remove;
- mrcp_event_handler->on_channel_modify = openmrcp_on_channel_modify;
-
- // create client context, which must be passed to client engine
- mrcp_context = mrcp_client_context_create(&openmrcp_module,mrcp_event_handler);
- if(!mrcp_context) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mrcp_client_context creation failed\n");
- return SWITCH_STATUS_GENERR;
- }
- profile->mrcp_context = mrcp_context;
-
- // this basically starts a thread that pulls events from the event queue
- // and handles them
- mrcp_client = openmrcp_client_start(profile->mrcp_options,mrcp_context);
- if(!mrcp_client) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "openmrcp_client_start FAILED\n");
- mrcp_client_context_destroy(mrcp_context);
- return SWITCH_STATUS_GENERR;
- }
- profile->mrcp_client = mrcp_client;
- return SWITCH_STATUS_SUCCESS;
-}
-
-
-static switch_status_t openmrcp_init()
-{
- openmrcp_module.pool = mrcp_global_pool_get();
- openmrcp_module.asr_profile = NULL;
- openmrcp_module.tts_profile = NULL;
-
- switch_core_hash_init(&openmrcp_module.profile_hash,openmrcp_module.pool);
-
- /* read config */
- if (do_config() != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- /* run default asr/tts profiles */
- if(openmrcp_module.asr_profile) {
- openmrcp_profile_run(openmrcp_module.asr_profile);
- }
- if(openmrcp_module.tts_profile && openmrcp_module.tts_profile != openmrcp_module.asr_profile) {
- openmrcp_profile_run(openmrcp_module.tts_profile);
- }
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load)
-{
- /* connect my internal structure to the blank pointer passed to me */
- //*module_interface = &openmrcp_module_interface;
-
- switch_speech_interface_t *speech_interface;
- switch_asr_interface_t *asr_interface;
-
- /* connect my internal structure to the blank pointer passed to me */
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
- speech_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SPEECH_INTERFACE);
- speech_interface->interface_name = "openmrcp";
- speech_interface->speech_open = openmrcp_tts_open;
- speech_interface->speech_close = openmrcp_tts_close;
- speech_interface->speech_feed_tts = openmrcp_feed_tts;
- speech_interface->speech_read_tts = openmrcp_read_tts;
- speech_interface->speech_flush_tts = openmrcp_flush_tts;
- speech_interface->speech_text_param_tts = openmrcp_text_param_tts;
- speech_interface->speech_numeric_param_tts = openmrcp_numeric_param_tts;
- speech_interface->speech_float_param_tts = openmrcp_float_param_tts;
- asr_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ASR_INTERFACE);
- asr_interface->interface_name = "openmrcp";
- asr_interface->asr_open = openmrcp_asr_open;
- asr_interface->asr_load_grammar = openmrcp_asr_load_grammar;
- asr_interface->asr_unload_grammar = openmrcp_asr_unload_grammar;
- asr_interface->asr_close = openmrcp_asr_close;
- asr_interface->asr_feed = openmrcp_asr_feed;
- asr_interface->asr_resume = openmrcp_asr_resume;
- asr_interface->asr_pause = openmrcp_asr_pause;
- asr_interface->asr_check_results = openmrcp_asr_check_results;
- asr_interface->asr_get_results = openmrcp_asr_get_results;
-
- mrcp_global_init();
-
- /* initialize openmrcp */
- if (openmrcp_init() != SWITCH_STATUS_SUCCESS) {
- return SWITCH_STATUS_FALSE;
- }
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
-
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openmrcp_shutdown)
-{
- return SWITCH_STATUS_UNLOAD;
-}
+ }
+ }
+ }
+ else {
+ goto error;
+ }
+ if ((profiles = switch_xml_child(cfg, "profiles"))) {
+ for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
+ const char *profile_name = switch_xml_attr_soft(xprofile, "name");
+ mrcp_profile = switch_core_alloc(openmrcp_module.pool,sizeof(openmrcp_profile_t));
+ mrcp_profile->mrcp_client = NULL;
+ mrcp_profile->mrcp_context = NULL;
+ mrcp_profile->name = "noname";
+ if(profile_name) {
+ mrcp_profile->name = switch_core_strdup(openmrcp_module.pool,profile_name);
+ }
+
+ mrcp_options = openmrcp_client_options_create(openmrcp_module.pool);
+ for (param = switch_xml_child(xprofile, "param"); param; param = param->next) {
+ const char *var = switch_xml_attr_soft(param, "name");
+ const char *val = switch_xml_attr_soft(param, "value");
+
+ if (!strcasecmp(var, "proto_version")) {
+ mrcp_options->proto_version =(mrcp_version_t) atoi(val);
+ }
+ else if (!strcasecmp(var, "client_ip")) {
+ mrcp_options->client_ip = switch_core_strdup(openmrcp_module.pool,val);
+ } else if (!strcasecmp(var, "server_ip")) {
+ mrcp_options->server_ip = switch_core_strdup(openmrcp_module.pool,val);
+ } else if (!strcasecmp(var, "client_port")) {
+ mrcp_options->client_port = (apr_port_t) atoi(val);
+ } else if (!strcasecmp(var, "server_port")) {
+ mrcp_options->server_port = (apr_port_t) atoi(val);
+ } else if (!strcasecmp(var, "rtp_port_min")) {
+ mrcp_options->rtp_port_min = (apr_port_t) atoi(val);
+ } else if (!strcasecmp(var, "rtp_port_max")) {
+ mrcp_options->rtp_port_max = (apr_port_t) atoi(val);
+ }
+ }
+ mrcp_profile->mrcp_options = mrcp_options;
+
+ /* add profile */
+ if (!switch_core_hash_find(openmrcp_module.profile_hash, mrcp_profile->name)) {
+ switch_core_hash_insert(openmrcp_module.profile_hash, mrcp_profile->name, mrcp_profile);
+
+ /* try to set default asr profile */
+ if (!openmrcp_module.asr_profile) {
+ if (asr_profile_name) {
+ if (!strcasecmp(mrcp_profile->name,asr_profile_name)) {
+ openmrcp_module.asr_profile = mrcp_profile;
+ }
+ }
+ else {
+ openmrcp_module.asr_profile = mrcp_profile;
+ }
+ }
+ /* try to set default tts profile */
+ if (!openmrcp_module.tts_profile) {
+ if (tts_profile_name) {
+ if (!strcasecmp(mrcp_profile->name,tts_profile_name)) {
+ openmrcp_module.tts_profile = mrcp_profile;
+ }
+ }
+ else {
+ openmrcp_module.tts_profile = mrcp_profile;
+ }
+ }
+ }
+ }
+ }
+ else {
+ goto error;
+ }
+
+ switch_xml_free(xml);
+ return SWITCH_STATUS_SUCCESS;
+
+ error:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load module configuration\n");
+ switch_xml_free(xml);
+ return SWITCH_STATUS_TERM;
+
+}
+
+static switch_status_t openmrcp_profile_run(openmrcp_profile_t *profile)
+{
+ mrcp_client_event_handler_t *mrcp_event_handler;
+ mrcp_client_t *mrcp_client;
+ mrcp_client_context_t *mrcp_context;
+
+ /*!
+ Perform one-time initialization of mrcp client library
+ */
+ mrcp_event_handler = switch_core_alloc(openmrcp_module.pool,sizeof(mrcp_client_event_handler_t));
+ mrcp_event_handler->on_session_initiate = openmrcp_on_session_initiate;
+ mrcp_event_handler->on_session_terminate = openmrcp_on_session_terminate;
+ mrcp_event_handler->on_channel_add = openmrcp_on_channel_add;
+ mrcp_event_handler->on_channel_remove = openmrcp_on_channel_remove;
+ mrcp_event_handler->on_channel_modify = openmrcp_on_channel_modify;
+
+ // create client context, which must be passed to client engine
+ mrcp_context = mrcp_client_context_create(&openmrcp_module,mrcp_event_handler);
+ if(!mrcp_context) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mrcp_client_context creation failed\n");
+ return SWITCH_STATUS_GENERR;
+ }
+ profile->mrcp_context = mrcp_context;
+
+ // this basically starts a thread that pulls events from the event queue
+ // and handles them
+ mrcp_client = openmrcp_client_start(profile->mrcp_options,mrcp_context);
+ if(!mrcp_client) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "openmrcp_client_start FAILED\n");
+ mrcp_client_context_destroy(mrcp_context);
+ return SWITCH_STATUS_GENERR;
+ }
+ profile->mrcp_client = mrcp_client;
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_status_t openmrcp_init()
+{
+ /* one-time mrcp global initialization */
+ mrcp_global_init();
+
+ openmrcp_module.pool = mrcp_global_pool_get();
+ openmrcp_module.asr_profile = NULL;
+ openmrcp_module.tts_profile = NULL;
+
+ switch_core_hash_init(&openmrcp_module.profile_hash,openmrcp_module.pool);
+
+ /* read config */
+ if (do_config() != SWITCH_STATUS_SUCCESS) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ /* run default asr/tts profiles */
+ if(openmrcp_module.asr_profile) {
+ openmrcp_profile_run(openmrcp_module.asr_profile);
+ }
+ if(openmrcp_module.tts_profile && openmrcp_module.tts_profile != openmrcp_module.asr_profile) {
+ openmrcp_profile_run(openmrcp_module.tts_profile);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t openmrcp_destroy()
+{
+ /* destroy asr/tts profiles */
+ if(openmrcp_module.asr_profile) {
+ /* shutdown client engine */
+ openmrcp_client_shutdown(openmrcp_module.asr_profile->mrcp_client);
+ /* destroy client context */
+ mrcp_client_context_destroy(openmrcp_module.asr_profile->mrcp_context);
+ if(openmrcp_module.tts_profile == openmrcp_module.asr_profile) {
+ openmrcp_module.tts_profile = NULL;
+ }
+ openmrcp_module.asr_profile = NULL;
+ }
+ if(openmrcp_module.tts_profile) {
+ /* shutdown client engine */
+ openmrcp_client_shutdown(openmrcp_module.tts_profile->mrcp_client);
+ /* destroy client context */
+ mrcp_client_context_destroy(openmrcp_module.tts_profile->mrcp_context);
+ openmrcp_module.tts_profile = NULL;
+ }
+
+ switch_core_hash_destroy(openmrcp_module.profile_hash);
+ openmrcp_module.profile_hash = NULL;
+
+ /* one-time mrcp global destroy */
+ mrcp_global_destroy();
+ return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load)
+{
+ switch_speech_interface_t *speech_interface;
+ switch_asr_interface_t *asr_interface;
+
+ /* connect my internal structure to the blank pointer passed to me */
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ speech_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SPEECH_INTERFACE);
+ speech_interface->interface_name = "openmrcp";
+ speech_interface->speech_open = openmrcp_tts_open;
+ speech_interface->speech_close = openmrcp_tts_close;
+ speech_interface->speech_feed_tts = openmrcp_feed_tts;
+ speech_interface->speech_read_tts = openmrcp_read_tts;
+ speech_interface->speech_flush_tts = openmrcp_flush_tts;
+ speech_interface->speech_text_param_tts = openmrcp_text_param_tts;
+ speech_interface->speech_numeric_param_tts = openmrcp_numeric_param_tts;
+ speech_interface->speech_float_param_tts = openmrcp_float_param_tts;
+ asr_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ASR_INTERFACE);
+ asr_interface->interface_name = "openmrcp";
+ asr_interface->asr_open = openmrcp_asr_open;
+ asr_interface->asr_load_grammar = openmrcp_asr_load_grammar;
+ asr_interface->asr_unload_grammar = openmrcp_asr_unload_grammar;
+ asr_interface->asr_close = openmrcp_asr_close;
+ asr_interface->asr_feed = openmrcp_asr_feed;
+ asr_interface->asr_resume = openmrcp_asr_resume;
+ asr_interface->asr_pause = openmrcp_asr_pause;
+ asr_interface->asr_check_results = openmrcp_asr_check_results;
+ asr_interface->asr_get_results = openmrcp_asr_get_results;
+
+ /* initialize openmrcp */
+ if (openmrcp_init() != SWITCH_STATUS_SUCCESS) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ /* indicate that the module should continue to be loaded */
+ return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openmrcp_shutdown)
+{
+ /* destroy openmrcp */
+ openmrcp_destroy();
+ return SWITCH_STATUS_UNLOAD;
+}
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/mod_sofia.h Tue Aug 21 13:44:11 2007
@@ -117,7 +117,8 @@
typedef enum {
- PFLAG_NDLB_TO_IN_200_CONTACT = (1 << 1)
+ PFLAG_NDLB_TO_IN_200_CONTACT = (1 << 0),
+ PFLAG_NDLB_BROKEN_AUTH_HASH = (1 << 1)
} sofia_NDLB_t;
typedef enum {
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c Tue Aug 21 13:44:11 2007
@@ -793,6 +793,10 @@
if (switch_true(val)) {
profile->ndlb |= PFLAG_NDLB_TO_IN_200_CONTACT;
}
+ } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
+ if (switch_true(val)) {
+ profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
+ }
} else if (!strcasecmp(var, "pass-rfc2833")) {
if (switch_true(val)) {
profile->pflags |= PFLAG_PASS_RFC2833;
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c Tue Aug 21 13:44:11 2007
@@ -725,8 +725,11 @@
char bigdigest[2 * SU_MD5_DIGEST_SIZE + 1];
char *username, *realm, *nonce, *uri, *qop, *cnonce, *nc, *response, *input = NULL, *input2 = NULL;
auth_res_t ret = AUTH_FORBIDDEN;
- char *npassword = NULL;
- int cnt = 0;
+ int cnt = 0, first = 0;
+ const char *passwd = NULL;
+ const char *a1_hash = NULL;
+ char *sql;
+ switch_xml_t domain, xml, user, param, xparams;
username = realm = nonce = uri = qop = cnonce = nc = response = NULL;
@@ -783,11 +786,7 @@
}
if (switch_strlen_zero(np)) {
- switch_xml_t domain, xml, user, param, xparams;
- const char *passwd = NULL;
- const char *a1_hash = NULL;
- char *sql;
-
+ first = 1;
sql = switch_mprintf("select nonce from sip_authentication where nonce='%q'", nonce);
assert(sql != NULL);
if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) {
@@ -796,72 +795,72 @@
goto end;
}
free(sql);
-
- if (switch_xml_locate_user(username, realm, ip, &xml, &domain, &user) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", username, realm);
- ret = AUTH_FORBIDDEN;
- goto end;
- }
+ }
+
+ if (switch_xml_locate_user(username, realm, ip, &xml, &domain, &user) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", username, realm);
+ ret = AUTH_FORBIDDEN;
+ goto end;
+ }
- if (!(xparams = switch_xml_child(user, "params"))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find params for user [%s@%s]\n", username, realm);
- ret = AUTH_FORBIDDEN;
- goto end;
+ if (!(xparams = switch_xml_child(user, "params"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find params for user [%s@%s]\n", username, realm);
+ switch_xml_free(xml);
+ ret = AUTH_FORBIDDEN;
+ goto end;
+ }
+
+ for (param = switch_xml_child(xparams, "param"); param; param = param->next) {
+ const char *var = switch_xml_attr_soft(param, "name");
+ const char *val = switch_xml_attr_soft(param, "value");
+
+ if (!strcasecmp(var, "password")) {
+ passwd = val;
}
- for (param = switch_xml_child(xparams, "param"); param; param = param->next) {
- const char *var = switch_xml_attr_soft(param, "name");
- const char *val = switch_xml_attr_soft(param, "value");
-
- if (!strcasecmp(var, "password")) {
- passwd = val;
- }
-
- if (!strcasecmp(var, "a1-hash")) {
- a1_hash = val;
- }
+ if (!strcasecmp(var, "a1-hash")) {
+ a1_hash = val;
}
+ }
+ if (first) {
if (v_event && (xparams = switch_xml_child(user, "variables"))) {
if (switch_event_create(v_event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
for (param = switch_xml_child(xparams, "variable"); param; param = param->next) {
const char *var = switch_xml_attr_soft(param, "name");
const char *val = switch_xml_attr_soft(param, "value");
-
+
if (!switch_strlen_zero(var) && !switch_strlen_zero(val)) {
switch_event_add_header(*v_event, SWITCH_STACK_BOTTOM, var, "%s", val);
}
}
}
}
+ }
+ switch_xml_free(xml);
- if (switch_strlen_zero(passwd) && switch_strlen_zero(a1_hash)) {
- ret = AUTH_OK;
- goto end;
- }
-
- if (!a1_hash) {
- su_md5_t ctx;
- char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1];
- char *input;
-
- input = switch_mprintf("%s:%s:%s", username, realm, passwd);
- su_md5_init(&ctx);
- su_md5_strupdate(&ctx, input);
- su_md5_hexdigest(&ctx, hexdigest);
- su_md5_deinit(&ctx);
- switch_safe_free(input);
- a1_hash = hexdigest;
-
- }
+ if (switch_strlen_zero(passwd) && switch_strlen_zero(a1_hash)) {
+ ret = AUTH_OK;
+ goto end;
+ }
- np = strdup(a1_hash);
+ if (!a1_hash) {
+ su_md5_t ctx;
+ char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1];
+ char *input;
- switch_xml_free(xml);
+ input = switch_mprintf("%s:%s:%s", username, realm, passwd);
+ su_md5_init(&ctx);
+ su_md5_strupdate(&ctx, input);
+ su_md5_hexdigest(&ctx, hexdigest);
+ su_md5_deinit(&ctx);
+ switch_safe_free(input);
+ a1_hash = hexdigest;
+
}
- npassword = np;
+ for_the_sake_of_interop:
if ((input = switch_mprintf("%s:%q", regstr, uri))) {
su_md5_init(&ctx);
@@ -870,7 +869,7 @@
su_md5_deinit(&ctx);
}
- if ((input2 = switch_mprintf("%q:%q:%q:%q:%q:%q", npassword, nonce, nc, cnonce, qop, uridigest))) {
+ if ((input2 = switch_mprintf("%q:%q:%q:%q:%q:%q", a1_hash, nonce, nc, cnonce, qop, uridigest))) {
memset(&ctx, 0, sizeof(ctx));
su_md5_init(&ctx);
su_md5_strupdate(&ctx, input2);
@@ -880,6 +879,16 @@
if (!strcasecmp(bigdigest, response)) {
ret = AUTH_OK;
} else {
+ if ((profile->ndlb & PFLAG_NDLB_BROKEN_AUTH_HASH) && strcasecmp(regstr, "REGISTER") && strcasecmp(regstr, "INVITE")) {
+ /* some clients send an ACK with the method 'INVITE' in the hash which will break auth so we will
+ try again with INVITE so we don't get people complaining to us when someone else's client has a bug......
+ */
+ switch_safe_free(input);
+ switch_safe_free(input2);
+ regstr = "INVITE";
+ goto for_the_sake_of_interop;
+ }
+
ret = AUTH_FORBIDDEN;
}
}
Modified: freeswitch/branches/greenlizard/src/switch_caller.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_caller.c (original)
+++ freeswitch/branches/greenlizard/src/switch_caller.c Tue Aug 21 13:44:11 2007
@@ -86,6 +86,14 @@
profile->source = switch_core_session_strdup(session, tocopy->source);
profile->context = switch_core_session_strdup(session, tocopy->context);
profile->chan_name = switch_core_session_strdup(session, tocopy->chan_name);
+ profile->caller_ton = tocopy->caller_ton;
+ profile->caller_numplan = tocopy->caller_numplan;
+ profile->ani_ton = tocopy->ani_ton;
+ profile->ani_numplan = tocopy->ani_numplan;
+ profile->rdnis_ton = tocopy->rdnis_ton;
+ profile->rdnis_numplan = tocopy->rdnis_numplan;
+ profile->destination_number_ton = tocopy->destination_number_ton;
+ profile->destination_number_numplan = tocopy->destination_number_numplan;
profile->flags = tocopy->flags;
}
1
0
[Freeswitch-branches] [commit] r5641 - in freeswitch/branches/greenlizard/src: . mod/asr_tts/mod_openmrcp mod/timers/mod_softtimer
by Freeswitch SVN 20 Aug '07
by Freeswitch SVN 20 Aug '07
20 Aug '07
Author: greenlizard
Date: Mon Aug 20 18:01:13 2007
New Revision: 5641
Modified:
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
freeswitch/branches/greenlizard/src/mod/timers/mod_softtimer/mod_softtimer.c
freeswitch/branches/greenlizard/src/switch_loadable_module.c
Log:
merge trunk 5627:5639
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Mon Aug 20 18:01:13 2007
@@ -99,7 +99,8 @@
FLAG_BARGE = (1 << 1),
FLAG_READY = (1 << 2),
FLAG_SPEAK_COMPLETE = (1 << 3),
- FLAG_FEED_STARTED = (1 << 4)
+ FLAG_FEED_STARTED = (1 << 4),
+ FLAG_TERMINATING = (1 << 5)
} mrcp_flag_t;
typedef struct {
@@ -173,7 +174,13 @@
if(!openmrcp_session) {
return MRCP_STATUS_FAILURE;
}
- openmrcp_session_destroy(openmrcp_session);
+
+ if (switch_test_flag(openmrcp_session, FLAG_TERMINATING)) {
+ openmrcp_session_destroy(openmrcp_session);
+ }
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "abnormal session terminate\n");
+ }
return MRCP_STATUS_SUCCESS;
}
@@ -436,6 +443,7 @@
// terminate client session
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Going to TERMINATE SESSION\n");
+ switch_set_flag_locked(asr_session, FLAG_TERMINATING);
mrcp_client_context_session_terminate(context, asr_session->client_session);
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
@@ -487,15 +495,21 @@
</result>
*/
- char *marker = "?>"; // FIXME -- lame and brittle way of doing this. use regex or better.
- char *position = strstr(asr_session->mrcp_message_last_rcvd->body, marker);
- if (!position) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad result received from mrcp server: %s", asr_session->mrcp_message_last_rcvd->body);
- ret = SWITCH_STATUS_FALSE;
+ if(asr_session->mrcp_message_last_rcvd && asr_session->mrcp_message_last_rcvd->body) {
+ char *marker = "?>"; // FIXME -- lame and brittle way of doing this. use regex or better.
+ char *position = strstr(asr_session->mrcp_message_last_rcvd->body, marker);
+ if (!position) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad result received from mrcp server: %s", asr_session->mrcp_message_last_rcvd->body);
+ ret = SWITCH_STATUS_FALSE;
+ }
+ else {
+ position += strlen(marker);
+ *xmlstr = strdup(position);
+ }
}
else {
- position += strlen(marker);
- *xmlstr = strdup(position);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No result received from mrcp server");
+ ret = SWITCH_STATUS_FALSE;
}
// since we are returning our result here, future calls to check_results
@@ -599,6 +613,7 @@
/* terminate tts session */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "terminate tts_session\n");
+ switch_set_flag_locked(tts_session, FLAG_TERMINATING);
mrcp_client_context_session_terminate(context,tts_session->client_session);
return SWITCH_STATUS_SUCCESS;
}
@@ -705,6 +720,7 @@
return SWITCH_STATUS_TERM;
}
+ mrcp_logger.priority = MRCP_PRIO_EMERGENCY;
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
const char *var = switch_xml_attr_soft(param, "name");
@@ -714,6 +730,8 @@
asr_profile_name = val;
} else if (!strcasecmp(var, "tts_default_profile")) {
tts_profile_name = val;
+ } else if (!strcasecmp(var, "log_level")) {
+ mrcp_logger.priority = atoi(val);
}
}
}
Modified: freeswitch/branches/greenlizard/src/mod/timers/mod_softtimer/mod_softtimer.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/timers/mod_softtimer/mod_softtimer.c (original)
+++ freeswitch/branches/greenlizard/src/mod/timers/mod_softtimer/mod_softtimer.c Mon Aug 20 18:01:13 2007
@@ -74,7 +74,7 @@
#define IDLE_SPEED 100
-static inline switch_status_t timer_init(switch_timer_t *timer)
+static switch_status_t timer_init(switch_timer_t *timer)
{
timer_private_t *private_info;
int sanity = 0;
@@ -112,7 +112,7 @@
-static inline switch_status_t timer_step(switch_timer_t *timer)
+static switch_status_t timer_step(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
uint64_t samples;
@@ -136,7 +136,7 @@
}
-static inline switch_status_t timer_next(switch_timer_t *timer)
+static switch_status_t timer_next(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
@@ -154,7 +154,7 @@
return SWITCH_STATUS_FALSE;
}
-static inline switch_status_t timer_check(switch_timer_t *timer)
+static switch_status_t timer_check(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
switch_status_t status = SWITCH_STATUS_SUCCESS;
@@ -182,7 +182,7 @@
}
-static inline switch_status_t timer_destroy(switch_timer_t *timer)
+static switch_status_t timer_destroy(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
switch_mutex_lock(globals.mutex);
Modified: freeswitch/branches/greenlizard/src/switch_loadable_module.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_loadable_module.c (original)
+++ freeswitch/branches/greenlizard/src/switch_loadable_module.c Mon Aug 20 18:01:13 2007
@@ -1047,6 +1047,7 @@
assert(module != NULL);
switch_loadable_module_unprocess(module);
+ switch_core_hash_delete_locked(loadable_modules.module_hash, module->key, loadable_modules.mutex);
if (module->switch_module_shutdown) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping: %s\n", module->module_interface->module_name);
@@ -1067,7 +1068,7 @@
}
- switch_core_hash_delete_locked(loadable_modules.module_hash, module->key, loadable_modules.mutex);
+
}
1
0
[Freeswitch-branches] [commit] r5640 - freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp
by Freeswitch SVN 20 Aug '07
by Freeswitch SVN 20 Aug '07
20 Aug '07
Author: greenlizard
Date: Mon Aug 20 17:54:21 2007
New Revision: 5640
Modified:
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
Log:
attempting to fix shutdown segfault, convert to new style module loading as seen in mod_cepstral
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Mon Aug 20 17:54:21 2007
@@ -690,47 +690,6 @@
}
-static switch_asr_interface_t openmrcp_asr_interface = {
- /*.interface_name*/ "openmrcp",
- /*.asr_open*/ openmrcp_asr_open,
- /*.asr_load_grammar*/ openmrcp_asr_load_grammar,
- /*.asr_unload_grammar*/ openmrcp_asr_unload_grammar,
- /*.asr_close*/ openmrcp_asr_close,
- /*.asr_feed*/ openmrcp_asr_feed,
- /*.asr_resume*/ openmrcp_asr_resume,
- /*.asr_pause*/ openmrcp_asr_pause,
- /*.asr_check_results*/ openmrcp_asr_check_results,
- /*.asr_get_results*/ openmrcp_asr_get_results
-};
-
-static switch_speech_interface_t openmrcp_tts_interface = {
- /*.interface_name*/ "openmrcp",
- /*.speech_open*/ openmrcp_tts_open,
- /*.speech_close*/ openmrcp_tts_close,
- /*.speech_feed_tts*/ openmrcp_feed_tts,
- /*.speech_read_tts*/ openmrcp_read_tts,
- /*.speech_flush_tts*/ openmrcp_flush_tts,
- /*.speech_text_param_tts*/ openmrcp_text_param_tts,
- /*.speech_numeric_param_tts*/ openmrcp_numeric_param_tts,
- /*.speech_float_param_tts*/ openmrcp_float_param_tts,
-};
-
-static switch_loadable_module_interface_t openmrcp_module_interface = {
- /*.module_name */ modname,
- /*.endpoint_interface */ NULL,
- /*.timer_interface */ NULL,
- /*.dialplan_interface */ NULL,
- /*.codec_interface */ NULL,
- /*.application_interface */ NULL,
- /*.api_interface */ NULL,
- /*.file_interface */ NULL,
- /*.speech_interface */ &openmrcp_tts_interface,
- /*.directory_interface */ NULL,
- /*.chat_interface */ NULL,
- /*.say_interface */ NULL,
- /*.asr_interface */ &openmrcp_asr_interface
-};
-
static switch_status_t do_config()
{
@@ -903,7 +862,34 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load)
{
/* connect my internal structure to the blank pointer passed to me */
- *module_interface = &openmrcp_module_interface;
+ //*module_interface = &openmrcp_module_interface;
+
+ switch_speech_interface_t *speech_interface;
+ switch_asr_interface_t *asr_interface;
+
+ /* connect my internal structure to the blank pointer passed to me */
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ speech_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SPEECH_INTERFACE);
+ speech_interface->interface_name = "openmrcp";
+ speech_interface->speech_open = openmrcp_tts_open;
+ speech_interface->speech_close = openmrcp_tts_close;
+ speech_interface->speech_feed_tts = openmrcp_feed_tts;
+ speech_interface->speech_read_tts = openmrcp_read_tts;
+ speech_interface->speech_flush_tts = openmrcp_flush_tts;
+ speech_interface->speech_text_param_tts = openmrcp_text_param_tts;
+ speech_interface->speech_numeric_param_tts = openmrcp_numeric_param_tts;
+ speech_interface->speech_float_param_tts = openmrcp_float_param_tts;
+ asr_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ASR_INTERFACE);
+ asr_interface->interface_name = "openmrcp";
+ asr_interface->asr_open = openmrcp_asr_open;
+ asr_interface->asr_load_grammar = openmrcp_asr_load_grammar;
+ asr_interface->asr_unload_grammar = openmrcp_asr_unload_grammar;
+ asr_interface->asr_close = openmrcp_asr_close;
+ asr_interface->asr_feed = openmrcp_asr_feed;
+ asr_interface->asr_resume = openmrcp_asr_resume;
+ asr_interface->asr_pause = openmrcp_asr_pause;
+ asr_interface->asr_check_results = openmrcp_asr_check_results;
+ asr_interface->asr_get_results = openmrcp_asr_get_results;
mrcp_global_init();
1
0
[Freeswitch-branches] [commit] r5637 - freeswitch/branches/greenlizard/src
by Freeswitch SVN 20 Aug '07
by Freeswitch SVN 20 Aug '07
20 Aug '07
Author: greenlizard
Date: Mon Aug 20 15:59:51 2007
New Revision: 5637
Modified:
freeswitch/branches/greenlizard/src/switch_cpp.cpp
Log:
did not have a return value and was breaking on windows build
Modified: freeswitch/branches/greenlizard/src/switch_cpp.cpp
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_cpp.cpp (original)
+++ freeswitch/branches/greenlizard/src/switch_cpp.cpp Mon Aug 20 15:59:51 2007
@@ -165,6 +165,7 @@
begin_allow_threads();
switch_ivr_collect_digits_callback(session, ap, timeout);
end_allow_threads();
+ return SWITCH_STATUS_SUCCESS;
}
int CoreSession::getDigits(char *dtmf_buf,
1
0
Author: greenlizard
Date: Mon Aug 20 13:37:13 2007
New Revision: 5631
Added:
freeswitch/branches/greenlizard/conf/mod_openmrcp.conf.xml
- copied unchanged from r5626, /freeswitch/trunk/conf/mod_openmrcp.conf.xml
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/heap.h
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/heap.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_open_c_localinfo.cpp
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/su/su_open_c_localinfo.cpp
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_heap.c
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/su/torture_heap.c
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/libsofia-sip-ua-glib.mmp
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/libsofia-sip-ua-glib.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/su_source_test.mmp
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/su_source_test.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/su_source_test_reg.rss
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/su_source_test_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_http.mmp
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/test_http.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_http_reg.rss
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/test_http_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_nua.mmp
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/test_nua.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_nua_reg.rss
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/test_nua_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_tport.mmp
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/test_tport.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_tport_reg.rss
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/group/test_tport_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/sis/
- copied from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/sis/
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/sis/libsofia-sip-ua-glib.pkg
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/sis/libsofia-sip-ua-glib.pkg
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/sis/libsofia-sip-ua.pkg
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/sis/libsofia-sip-ua.pkg
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/sis/su_source_test.pkg
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/sis/su_source_test.pkg
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/sis/test_nua.pkg
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/sis/test_nua.pkg
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/sis/test_tport.pkg
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/open_c/sis/test_tport.pkg
freeswitch/branches/greenlizard/libs/sofia-sip/utils/utils.docs
- copied unchanged from r5626, /freeswitch/trunk/libs/sofia-sip/utils/utils.docs
freeswitch/branches/greenlizard/scripts/contrib/trixter/asyncsock.pl
- copied unchanged from r5626, /freeswitch/trunk/scripts/contrib/trixter/asyncsock.pl
freeswitch/branches/greenlizard/scripts/contrib/trixter/callcredit.pl
- copied unchanged from r5626, /freeswitch/trunk/scripts/contrib/trixter/callcredit.pl
freeswitch/branches/greenlizard/scripts/contrib/trixter/makecombinedfsxml.pl
- copied unchanged from r5626, /freeswitch/trunk/scripts/contrib/trixter/makecombinedfsxml.pl
freeswitch/branches/greenlizard/scripts/contrib/trixter/mod_xml_cdr.c
- copied unchanged from r5626, /freeswitch/trunk/scripts/contrib/trixter/mod_xml_cdr.c
freeswitch/branches/greenlizard/scripts/contrib/trixter/switch_xml.c
- copied unchanged from r5626, /freeswitch/trunk/scripts/contrib/trixter/switch_xml.c
freeswitch/branches/greenlizard/scripts/contrib/trixter/vile/
- copied from r5626, /freeswitch/trunk/scripts/contrib/trixter/vile/
freeswitch/branches/greenlizard/scripts/contrib/trixter/vile/fsconsole.c
- copied unchanged from r5626, /freeswitch/trunk/scripts/contrib/trixter/vile/fsconsole.c
freeswitch/branches/greenlizard/scripts/contrib/vile/
- copied from r5626, /freeswitch/trunk/scripts/contrib/vile/
freeswitch/branches/greenlizard/src/include/switch_version.h.template
- copied unchanged from r5626, /freeswitch/trunk/src/include/switch_version.h.template
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.vcproj
- copied unchanged from r5626, /freeswitch/trunk/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.vcproj
Removed:
freeswitch/branches/greenlizard/conf/freeswitch_combined.xml
freeswitch/branches/greenlizard/src/include/switch_version.h.in
Modified:
freeswitch/branches/greenlizard/ (props changed)
freeswitch/branches/greenlizard/Freeswitch.sln
freeswitch/branches/greenlizard/Makefile.am
freeswitch/branches/greenlizard/build/modules.conf.in
freeswitch/branches/greenlizard/conf/freeswitch.xml
freeswitch/branches/greenlizard/conf/xml_cdr.conf.xml
freeswitch/branches/greenlizard/configure.in
freeswitch/branches/greenlizard/libs/libteletone/src/libteletone.h
freeswitch/branches/greenlizard/libs/sofia-sip/RELEASE
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source_test.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/bnf/torture_bnf.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/conformance.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/features/features.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http_basic.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/test_http.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/Makefile.am
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/ipt.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_tag.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec_debug.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_module.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_plugin.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_table.c.in
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea_debug.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/Doxyfile.in
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_common.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_extension.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_message.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_options.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_publish.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nat.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_bad_mask
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra_headers.txt
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_extra.h.in
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_header.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/torture_sip.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa_tag.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/test_soa.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/Makefile.am
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/test_sresolv.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/stun/stun_tag.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Doxyfile.in
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Makefile.am
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_config.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_configure.h.in
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_time.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_types.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_wait.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.docs
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_addrinfo.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_base_port.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_default_log.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_global_log.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_log.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_port.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_root.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time0.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/tag_dll.awk
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/test_poll.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_tag.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_time.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_timer.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/test_tport.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c
freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/build_sources.cmd
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/config.h.in
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/bld.inf
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/libsofia-sip-ua.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url.mmp
freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url_reg.rss
freeswitch/branches/greenlizard/libs/sofia-sip/utils/Doxyfile.in
freeswitch/branches/greenlizard/libs/sofia-sip/utils/Makefile.am
freeswitch/branches/greenlizard/libs/sofia-sip/utils/sip-options.c
freeswitch/branches/greenlizard/libs/sofia-sip/win32/README.txt
freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.dsp
freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.vcproj
freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.dsp
freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.vcproj
freeswitch/branches/greenlizard/libs/sofia-sip/win32/sofia-sip/su_configure.h
freeswitch/branches/greenlizard/libs/sofia-sip/win32/utils/stunc/stunc.vcproj
freeswitch/branches/greenlizard/libs/win32/util.vbs
freeswitch/branches/greenlizard/scripts/socket/socket2me/socket2me.c
freeswitch/branches/greenlizard/src/dotnet/ (props changed)
freeswitch/branches/greenlizard/src/include/switch_module_interfaces.h
freeswitch/branches/greenlizard/src/include/switch_types.h
freeswitch/branches/greenlizard/src/include/switch_utils.h
freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c
freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c
freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/ (props changed)
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/Makefile
freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/mod_h26x.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_glue.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_presence.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c
freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/Makefile
freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c
freeswitch/branches/greenlizard/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
freeswitch/branches/greenlizard/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c
freeswitch/branches/greenlizard/src/mod/formats/mod_local_stream/ (props changed)
freeswitch/branches/greenlizard/src/mod/formats/mod_shout/Makefile
freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_core_db/mod_spidermonkey_core_db.c
freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_etpan/mod_spidermonkey_etpan.c
freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
freeswitch/branches/greenlizard/src/switch.c
freeswitch/branches/greenlizard/src/switch_core.c
freeswitch/branches/greenlizard/src/switch_core_state_machine.c
freeswitch/branches/greenlizard/src/switch_event.c
freeswitch/branches/greenlizard/src/switch_ivr.c
freeswitch/branches/greenlizard/src/switch_ivr_async.c
freeswitch/branches/greenlizard/src/switch_ivr_bridge.c
freeswitch/branches/greenlizard/src/switch_ivr_originate.c
freeswitch/branches/greenlizard/src/switch_ivr_play_say.c
freeswitch/branches/greenlizard/src/switch_loadable_module.c
freeswitch/branches/greenlizard/src/switch_xml.c
freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj
Log:
merge trunk 5519:5626
Modified: freeswitch/branches/greenlizard/Freeswitch.sln
==============================================================================
--- freeswitch/branches/greenlizard/Freeswitch.sln (original)
+++ freeswitch/branches/greenlizard/Freeswitch.sln Mon Aug 20 13:37:13 2007
@@ -3,20 +3,20 @@
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Console\FreeSwitchConsole.vcproj", "{1AF3A893-F7BE-43DD-B697-8AB2397C0D67}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Library\FreeSwitchCore.vcproj", "{202D7A4E-760D-4D0E-AFA1-D7459CED30FF}"
ProjectSection(ProjectDependencies) = postProject
- {50AD0E28-B8D7-4FCC-8FC3-599F6AC69761} = {50AD0E28-B8D7-4FCC-8FC3-599F6AC69761}
- {8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
- {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
- {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
- {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750}
- {101130D1-3EA6-4ED2-B65D-CEB5243A20ED} = {101130D1-3EA6-4ED2-B65D-CEB5243A20ED}
{6EDFEFD5-3596-4FA9-8EBA-B331547B35A3} = {6EDFEFD5-3596-4FA9-8EBA-B331547B35A3}
+ {101130D1-3EA6-4ED2-B65D-CEB5243A20ED} = {101130D1-3EA6-4ED2-B65D-CEB5243A20ED}
+ {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
+ {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
+ {8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
+ {50AD0E28-B8D7-4FCC-8FC3-599F6AC69761} = {50AD0E28-B8D7-4FCC-8FC3-599F6AC69761}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_g729", "src\mod\codecs\mod_g729\mod_g729.vcproj", "{1D95CD95-0DE2-48C3-AC23-D5C7D1C9C0F0}"
@@ -26,28 +26,28 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_gsm", "src\mod\codecs\mod_gsm\mod_gsm.vcproj", "{4926323F-4EA8-4B7D-A3D3-65488725988F}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{8FD2E297-4096-47E5-9258-C48FF1841523} = {8FD2E297-4096-47E5-9258-C48FF1841523}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xmpp_event", "src\mod\event_handlers\mod_xmpp_event\mod_xmpp_event.vcproj", "{F10BE67C-A8FF-4CB2-AF29-D46D2590DC59}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{E727E8F6-935D-46FE-8B0E-37834748A0E3} = {E727E8F6-935D-46FE-8B0E-37834748A0E3}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_sndfile", "src\mod\formats\mod_sndfile\mod_sndfile.vcproj", "{AFAC0568-7548-42D5-9F6A-8D3400A1E4F6}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{3D0370CA-BED2-4657-A475-32375CBCB6E4} = {3D0370CA-BED2-4657-A475-32375CBCB6E4}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_event_test", "src\mod\event_handlers\mod_event_test\mod_event_test.vcproj", "{3A2A7795-C216-4FFF-B8EF-4D17A84BACCC}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_g711", "src\mod\codecs\mod_g711\mod_g711.vcproj", "{B1FE4613-3F4B-4DAF-9714-2472BF8F56AE}"
@@ -57,16 +57,16 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_iax", "src\mod\endpoints\mod_iax\mod_iax.vcproj", "{3A5B9131-F20C-4A85-9447-6C1610941CEE}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{5CC054B7-6DAA-46BF-9A08-3B33B83E8D3E} = {5CC054B7-6DAA-46BF-9A08-3B33B83E8D3E}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_PortAudio", "src\mod\endpoints\mod_portaudio\mod_PortAudio.vcproj", "{5FD31A25-5D83-4794-8BEE-904DAD84CE71}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {0A18A071-125E-442F-AFF7-A3F68ABECF99} = {0A18A071-125E-442F-AFF7-A3F68ABECF99}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {0A18A071-125E-442F-AFF7-A3F68ABECF99} = {0A18A071-125E-442F-AFF7-A3F68ABECF99}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_l16", "src\mod\codecs\mod_l16\mod_l16.vcproj", "{5844AFE1-AA3E-4BDB-A9EF-119AEF19DF88}"
@@ -76,20 +76,20 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_softtimer", "src\mod\timers\mod_softtimer\mod_softtimer.vcproj", "{DCC13474-28DF-47CA-A8EB-72F8CE9A78C5}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_speex", "src\mod\codecs\mod_speex\mod_speex.vcproj", "{5580D60E-0F77-4716-9CD4-B8E5986FA375}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{1C469CDD-A3AF-4A94-A592-B2CF12F2D918} = {1C469CDD-A3AF-4A94-A592-B2CF12F2D918}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_woomera", "src\mod\endpoints\mod_woomera\mod_woomera.vcproj", "{FE3540C5-3303-46E0-A69E-D92F775687F1}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Codecs", "Codecs", "{F881ADA2-2F1A-4046-9FEB-191D9422D781}"
@@ -112,8 +112,8 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_dialplan_xml", "src\mod\dialplans\mod_dialplan_xml\mod_dialplan_xml.vcproj", "{07113B25-D3AF-4E04-BA77-4CD1171F022C}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "FreeSwitchSetup", "w32\Setup\Setup.vdproj", "{B17FFBE6-A942-4056-8346-B624FB5D995B}"
@@ -127,22 +127,22 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_dialplan_directory", "src\mod\dialplans\mod_dialplan_directory\mod_dialplan_directory.vcproj", "{A27CCA23-1541-4337-81A4-F0A6413078A0}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_zeroconf", "src\mod\event_handlers\mod_zeroconf\mod_zeroconf.vcproj", "{C7705DC4-2088-493E-AF8D-65BC6D65C125}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {49C34584-B6DA-448F-83CF-27584DC9FC90} = {49C34584-B6DA-448F-83CF-27584DC9FC90}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{0D826AF5-0506-4C50-BB8B-7DB019AC21AE} = {0D826AF5-0506-4C50-BB8B-7DB019AC21AE}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {49C34584-B6DA-448F-83CF-27584DC9FC90} = {49C34584-B6DA-448F-83CF-27584DC9FC90}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_event_multicast", "src\mod\event_handlers\mod_event_multicast\mod_event_multicast.vcproj", "{784113EF-44D9-4949-835D-7065D3C7AD08}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libteletone", "libs\libteletone\libteletone.vcproj", "{89385C74-5860-4174-9CAF-A39E7C48909C}"
@@ -151,10 +151,10 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey", "src\mod\languages\mod_spidermonkey\mod_spidermonkey.vcproj", "{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
- {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
{204FA0DE-305D-4414-AE2E-F195A23F390D} = {204FA0DE-305D-4414-AE2E-F195A23F390D}
+ {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ASR-TTS", "ASR-TTS", "{4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}"
@@ -176,22 +176,22 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_ilbc", "src\mod\codecs\mod_ilbc\mod_ilbc.vcproj", "{D3EC0AFF-76FC-4210-A825-9A17410660A3}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{989BB874-7AF1-44CB-8E5C-CC8113D267E8} = {989BB874-7AF1-44CB-8E5C-CC8113D267E8}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_dingaling", "src\mod\endpoints\mod_dingaling\mod_dingaling.vcproj", "{FFAA4C52-3A53-4F99-90C1-D59D1F0427F3}"
ProjectSection(ProjectDependencies) = postProject
- {1906D736-08BD-4EE1-924F-B536249B9A54} = {1906D736-08BD-4EE1-924F-B536249B9A54}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{E727E8F6-935D-46FE-8B0E-37834748A0E3} = {E727E8F6-935D-46FE-8B0E-37834748A0E3}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {1906D736-08BD-4EE1-924F-B536249B9A54} = {1906D736-08BD-4EE1-924F-B536249B9A54}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_commands", "src\mod\applications\mod_commands\mod_commands.vcproj", "{30A5B29C-983E-4580-9FD0-D647CCDCC7EB}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Loggers", "Loggers", "{A7AB4405-FDB7-4853-9FBB-1516B1C3D80A}"
@@ -205,42 +205,42 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_rpc", "src\mod\xml_int\mod_xml_rpc\mod_xml_rpc.vcproj", "{CBEC7225-0C21-4DA8-978E-1F158F8AD950}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {356EC96D-4C9F-47B5-9083-FC328B87BA94} = {356EC96D-4C9F-47B5-9083-FC328B87BA94}
- {A3FE0076-B366-429D-A238-D7304DA7D3C1} = {A3FE0076-B366-429D-A238-D7304DA7D3C1}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
- {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
{155844C3-EC5F-407F-97A4-A2DDADED9B2F} = {155844C3-EC5F-407F-97A4-A2DDADED9B2F}
+ {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {A3FE0076-B366-429D-A238-D7304DA7D3C1} = {A3FE0076-B366-429D-A238-D7304DA7D3C1}
+ {356EC96D-4C9F-47B5-9083-FC328B87BA94} = {356EC96D-4C9F-47B5-9083-FC328B87BA94}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_rss", "src\mod\applications\mod_rss\mod_rss.vcproj", "{B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_conference", "src\mod\applications\mod_conference\mod_conference.vcproj", "{C24FB505-05D7-4319-8485-7540B44C8603}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_dptools", "src\mod\applications\mod_dptools\mod_dptools.vcproj", "{B5881A85-FE70-4F64-8607-2CAAE52669C6}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_event_socket", "src\mod\event_handlers\mod_event_socket\mod_event_socket.vcproj", "{05515420-16DE-4E63-BE73-85BE85BA5142}"
ProjectSection(ProjectDependencies) = postProject
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_cdr", "src\mod\event_handlers\mod_cdr\mod_cdr.vcproj", "{3D1EED36-A510-4EDB-B4D9-4E0F4A5EC2A8}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Libraries", "_Libraries", "{EB910B0D-F27D-4B62-B67B-DE834C99AC5B}"
@@ -253,8 +253,8 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdingaling", "libs\libdingaling\libdingaling.vcproj", "{1906D736-08BD-4EE1-924F-B536249B9A54}"
ProjectSection(ProjectDependencies) = postProject
- {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
{E727E8F6-935D-46FE-8B0E-37834748A0E3} = {E727E8F6-935D-46FE-8B0E-37834748A0E3}
+ {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsrtp", "libs\srtp\libsrtp.vcproj", "{EEF031CB-FED8-451E-A471-91EC8D4F6750}"
@@ -279,8 +279,8 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libaprutil", "libs\win32\apr-util\libaprutil.vcproj", "{F057DA7F-79E5-4B00-845C-EF446EF055E3}"
ProjectSection(ProjectDependencies) = postProject
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{101130D1-3EA6-4ED2-B65D-CEB5243A20ED} = {101130D1-3EA6-4ED2-B65D-CEB5243A20ED}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Downloads", "_Downloads", "{C120A020-773F-4EA3-923F-B67AF28B750D}"
@@ -298,8 +298,8 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mDNSResponder static library", "libs\win32\howl\libmDNSResponder.vcproj", "{49C34584-B6DA-448F-83CF-27584DC9FC90}"
ProjectSection(ProjectDependencies) = postProject
- {5927104D-C14C-4AC8-925C-4AB681762E75} = {5927104D-C14C-4AC8-925C-4AB681762E75}
{0D826AF5-0506-4C50-BB8B-7DB019AC21AE} = {0D826AF5-0506-4C50-BB8B-7DB019AC21AE}
+ {5927104D-C14C-4AC8-925C-4AB681762E75} = {5927104D-C14C-4AC8-925C-4AB681762E75}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsndfile", "libs\win32\libsndfile\libsndfile.vcproj", "{3D0370CA-BED2-4657-A475-32375CBCB6E4}"
@@ -319,34 +319,34 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_sofia", "src\mod\endpoints\mod_sofia\mod_sofia.vcproj", "{0DF3ABD0-DDC0-4265-B778-07C66780979B}"
ProjectSection(ProjectDependencies) = postProject
- {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4} = {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{70A49BC2-7500-41D0-B75D-EDCC5BE987A0} = {70A49BC2-7500-41D0-B75D-EDCC5BE987A0}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4} = {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libg726", "libs\codec\g726\libg726.vcproj", "{5A6A281A-AA50-470A-8305-202BDA1CD1BF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_g726", "src\mod\codecs\mod_g726\mod_g726.vcproj", "{486369EB-F150-4B56-BCC8-77B9E18FF5F5}"
ProjectSection(ProjectDependencies) = postProject
- {5A6A281A-AA50-470A-8305-202BDA1CD1BF} = {5A6A281A-AA50-470A-8305-202BDA1CD1BF}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {5A6A281A-AA50-470A-8305-202BDA1CD1BF} = {5A6A281A-AA50-470A-8305-202BDA1CD1BF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libg7xx", "libs\codec\g7xx\libg7xx.vcproj", "{D71E7338-8D9C-4FE4-A15F-D5CC60202C7C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_g722", "src\mod\codecs\mod_g722\mod_g722.vcproj", "{D42518CC-7475-454D-B392-0E132C07D761}"
ProjectSection(ProjectDependencies) = postProject
- {D71E7338-8D9C-4FE4-A15F-D5CC60202C7C} = {D71E7338-8D9C-4FE4-A15F-D5CC60202C7C}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {D71E7338-8D9C-4FE4-A15F-D5CC60202C7C} = {D71E7338-8D9C-4FE4-A15F-D5CC60202C7C}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsofia_sip_ua_static", "libs\win32\sofia\libsofia_sip_ua_static.vcproj", "{70A49BC2-7500-41D0-B75D-EDCC5BE987A0}"
ProjectSection(ProjectDependencies) = postProject
- {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4} = {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4}
{8B3B4C4C-13C2-446C-BEB0-F412CC2CFB9A} = {8B3B4C4C-13C2-446C-BEB0-F412CC2CFB9A}
+ {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4} = {DF018947-0FFF-4EB3-BDEE-441DC81DA7A4}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download PTHREAD", "libs\win32\Download PTHREAD.vcproj", "{8B3B4C4C-13C2-446C-BEB0-F412CC2CFB9A}"
@@ -358,85 +358,85 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_g723_1", "src\mod\codecs\mod_g723_1\mod_g723_1.vcproj", "{FEA1EEF7-876F-48DE-88BF-C0E3E606D758}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_native_file", "src\mod\formats\mod_native_file\mod_native_file.vcproj", "{9254C4B0-6F60-42B6-BB3A-36D63FC001C7}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSwitch.NET", "src\dotnet\FreeSwitch.NET.csproj", "{251CAABC-16C3-4593-A491-603B908094E0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey_core_db", "src\mod\languages\mod_spidermonkey_core_db\mod_spidermonkey_core_db.vcproj", "{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}"
ProjectSection(ProjectDependencies) = postProject
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{204FA0DE-305D-4414-AE2E-F195A23F390D} = {204FA0DE-305D-4414-AE2E-F195A23F390D}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey_teletone", "src\mod\languages\mod_spidermonkey_teletone\mod_spidermonkey_teletone.vcproj", "{8F992C49-6C51-412F-B2A3-34EAB708EB65}"
ProjectSection(ProjectDependencies) = postProject
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{204FA0DE-305D-4414-AE2E-F195A23F390D} = {204FA0DE-305D-4414-AE2E-F195A23F390D}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libudns", "libs\win32\udns\libudns.vcproj", "{4043FC6A-9A30-4577-8AD5-9B233C9575D8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_enum", "src\mod\applications\mod_enum\mod_enum.vcproj", "{71A967D5-0E99-4CEF-A587-98836EE6F2EF}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {4043FC6A-9A30-4577-8AD5-9B233C9575D8} = {4043FC6A-9A30-4577-8AD5-9B233C9575D8}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {4043FC6A-9A30-4577-8AD5-9B233C9575D8} = {4043FC6A-9A30-4577-8AD5-9B233C9575D8}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey_etpan", "src\mod\languages\mod_spidermonkey_etpan\mod_spidermonkey_etpan.vcproj", "{D6C82F86-2B05-4A7F-8CC6-D2592E66FBB9}"
ProjectSection(ProjectDependencies) = postProject
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
- {BA4DED3C-E56F-4484-BFC3-9C13E461A1BE} = {BA4DED3C-E56F-4484-BFC3-9C13E461A1BE}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{204FA0DE-305D-4414-AE2E-F195A23F390D} = {204FA0DE-305D-4414-AE2E-F195A23F390D}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {BA4DED3C-E56F-4484-BFC3-9C13E461A1BE} = {BA4DED3C-E56F-4484-BFC3-9C13E461A1BE}
+ {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey_odbc", "src\mod\languages\mod_spidermonkey_odbc\mod_spidermonkey_odbc.vcproj", "{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}"
ProjectSection(ProjectDependencies) = postProject
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{204FA0DE-305D-4414-AE2E-F195A23F390D} = {204FA0DE-305D-4414-AE2E-F195A23F390D}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libetpan", "libs\win32\etpan\libetpan.vcproj", "{BA4DED3C-E56F-4484-BFC3-9C13E461A1BE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_curl", "src\mod\xml_int\mod_xml_curl\mod_xml_curl.vcproj", "{AB91A099-7690-4ECF-8994-E458F4EA1ED4}"
ProjectSection(ProjectDependencies) = postProject
- {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "say", "say", "{6CD61A1D-797C-470A-BE08-8C31B68BB336}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_en", "src\mod\say\mod_say_en\mod_say_en.vcproj", "{988CACF7-3FCB-4992-BE69-77872AE67DC8}"
ProjectSection(ProjectDependencies) = postProject
- {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portaudio", "libs\portaudio\build\msvc\portaudio.vcproj", "{0A18A071-125E-442F-AFF7-A3F68ABECF99}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_xml_cdr", "src\mod\xml_int\mod_xml_cdr\mod_xml_cdr.vcproj", "{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}"
ProjectSection(ProjectDependencies) = postProject
- {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
- {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_amr", "src\mod\codecs\mod_amr\mod_amr.vcproj", "{8DEB383C-4091-4F42-A56F-C9E46D552D79}"
@@ -458,7 +458,6 @@
conf\event_multicast.conf.xml = conf\event_multicast.conf.xml
conf\event_socket.conf.xml = conf\event_socket.conf.xml
conf\freeswitch.xml = conf\freeswitch.xml
- conf\freeswitch_combined.xml = conf\freeswitch_combined.xml
conf\iax.conf.xml = conf\iax.conf.xml
conf\ivr.conf.xml = conf\ivr.conf.xml
conf\lang_en.xml = conf\lang_en.xml
@@ -551,13 +550,9 @@
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Build System", "_Build System", "{DB1024A8-41BF-4AD7-9AE6-13202230D1F3}"
ProjectSection(SolutionItems) = preProject
acsite.m4 = acsite.m4
- build\addenv.sh = build\addenv.sh
- build\build.sh = build\build.sh
build\buildlib.sh = build\buildlib.sh
- build\checkversion.sh = build\checkversion.sh
configure.in = configure.in
Makefile.am = Makefile.am
- build\modmake.sh = build\modmake.sh
build\modules.conf.in = build\modules.conf.in
libs\win32\util.vbs = libs\win32\util.vbs
EndProjectSection
@@ -591,6 +586,58 @@
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mediaframe", "libs\openmrcp\mediaframe\mediaframe.vcproj", "{AA91F0AC-6562-435E-814C-5C94689FEFA2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mrcpcore", "libs\openmrcp\mrcpcore\mrcpcore.vcproj", "{829A9309-3B94-43C0-846B-7EC9D6D35F8B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2} = {AA91F0AC-6562-435E-814C-5C94689FEFA2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rtspcore", "libs\openmrcp\rtspcore\rtspcore.vcproj", "{EB751DC4-87BD-4766-B78D-DFB64BA9F988}"
+ ProjectSection(ProjectDependencies) = postProject
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B} = {829A9309-3B94-43C0-846B-7EC9D6D35F8B}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mrcpmediaframe", "libs\openmrcp\module\mrcpmediaframe\mrcpmediaframe.vcproj", "{9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B} = {829A9309-3B94-43C0-846B-7EC9D6D35F8B}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mrcprtsp", "libs\openmrcp\module\mrcprtsp\mrcprtsp.vcproj", "{CF78E84D-8456-44F2-8197-0E0E88D30A3C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988} = {EB751DC4-87BD-4766-B78D-DFB64BA9F988}
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "openmrcp", "openmrcp", "{ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mrcpsofiasip", "libs\openmrcp\module\mrcpsofiasip\mrcpsofiasip.vcproj", "{819C7242-6184-46FE-BC7B-C7E25C0581EE}"
+ ProjectSection(ProjectDependencies) = postProject
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B} = {829A9309-3B94-43C0-846B-7EC9D6D35F8B}
+ {70A49BC2-7500-41D0-B75D-EDCC5BE987A0} = {70A49BC2-7500-41D0-B75D-EDCC5BE987A0}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mrcpv2agent", "libs\openmrcp\module\mrcpv2agent\mrcpv2agent.vcproj", "{FB64EA08-3BC0-48AE-BE4B-74F1024B756E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B} = {829A9309-3B94-43C0-846B-7EC9D6D35F8B}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libopenmrcpclient", "libs\openmrcp\platform\openmrcpclient\libopenmrcpclient.vcproj", "{A407B661-D7DC-4E30-B268-FFF3296C35E6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E} = {FB64EA08-3BC0-48AE-BE4B-74F1024B756E}
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6} = {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE} = {819C7242-6184-46FE-BC7B-C7E25C0581EE}
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C} = {CF78E84D-8456-44F2-8197-0E0E88D30A3C}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_openmrcp", "src\mod\asr_tts\mod_openmrcp\mod_openmrcp.vcproj", "{E7116F50-2B10-472F-92BD-C8667AA9C1AE}"
+ ProjectSection(ProjectDependencies) = postProject
+ {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6} = {A407B661-D7DC-4E30-B268-FFF3296C35E6}
+ {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
+ {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
+ {70A49BC2-7500-41D0-B75D-EDCC5BE987A0} = {70A49BC2-7500-41D0-B75D-EDCC5BE987A0}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -1065,12 +1112,10 @@
{988CACF7-3FCB-4992-BE69-77872AE67DC8}.Release|x64.ActiveCfg = Release|Win32
{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug|Win32
{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug|x64
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug|x64
+ {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug|Win32
{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release|Win32
{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release|Win32
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release|x64
- {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release|x64
+ {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release|Win32
{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.Debug|Win32.ActiveCfg = Debug|Win32
{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.Debug|Win32.Build.0 = Debug|Win32
{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.Debug|x64.ActiveCfg = Debug|Win32
@@ -1101,6 +1146,60 @@
{2CA40887-1622-46A1-A7F9-17FD7E7E545B}.Release|Win32.ActiveCfg = Release|Win32
{2CA40887-1622-46A1-A7F9-17FD7E7E545B}.Release|Win32.Build.0 = Release|Win32
{2CA40887-1622-46A1-A7F9-17FD7E7E545B}.Release|x64.ActiveCfg = Release|Win32
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2}.Debug|Win32.Build.0 = Debug|Win32
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2}.Debug|x64.ActiveCfg = Debug|Win32
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2}.Release|Win32.ActiveCfg = Release|Win32
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2}.Release|Win32.Build.0 = Release|Win32
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2}.Release|x64.ActiveCfg = Release|Win32
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B}.Debug|Win32.Build.0 = Debug|Win32
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B}.Debug|x64.ActiveCfg = Debug|Win32
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B}.Release|Win32.ActiveCfg = Release|Win32
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B}.Release|Win32.Build.0 = Release|Win32
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B}.Release|x64.ActiveCfg = Release|Win32
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988}.Debug|Win32.Build.0 = Debug|Win32
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988}.Debug|x64.ActiveCfg = Debug|Win32
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988}.Release|Win32.ActiveCfg = Release|Win32
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988}.Release|Win32.Build.0 = Release|Win32
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988}.Release|x64.ActiveCfg = Release|Win32
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}.Debug|Win32.Build.0 = Debug|Win32
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}.Debug|x64.ActiveCfg = Debug|Win32
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}.Release|Win32.ActiveCfg = Release|Win32
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}.Release|Win32.Build.0 = Release|Win32
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6}.Release|x64.ActiveCfg = Release|Win32
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C}.Debug|Win32.ActiveCfg = Debug Static|Win32
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C}.Debug|Win32.Build.0 = Debug Static|Win32
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C}.Debug|x64.ActiveCfg = Debug|Win32
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C}.Release|Win32.ActiveCfg = Release Static|Win32
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C}.Release|Win32.Build.0 = Release Static|Win32
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C}.Release|x64.ActiveCfg = Release|Win32
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE}.Debug|Win32.ActiveCfg = Debug Static|Win32
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE}.Debug|Win32.Build.0 = Debug Static|Win32
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE}.Debug|x64.ActiveCfg = Debug|Win32
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE}.Release|Win32.ActiveCfg = Release Static|Win32
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE}.Release|Win32.Build.0 = Release Static|Win32
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE}.Release|x64.ActiveCfg = Release|Win32
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E}.Debug|Win32.Build.0 = Debug|Win32
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E}.Debug|x64.ActiveCfg = Debug|Win32
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E}.Release|Win32.ActiveCfg = Release|Win32
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E}.Release|Win32.Build.0 = Release|Win32
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E}.Release|x64.ActiveCfg = Release|Win32
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6}.Debug|Win32.Build.0 = Debug|Win32
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6}.Debug|x64.ActiveCfg = Debug|Win32
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6}.Release|Win32.ActiveCfg = Release|Win32
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6}.Release|Win32.Build.0 = Release|Win32
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6}.Release|x64.ActiveCfg = Release|Win32
+ {E7116F50-2B10-472F-92BD-C8667AA9C1AE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E7116F50-2B10-472F-92BD-C8667AA9C1AE}.Debug|Win32.Build.0 = Debug|Win32
+ {E7116F50-2B10-472F-92BD-C8667AA9C1AE}.Debug|x64.ActiveCfg = Debug|Win32
+ {E7116F50-2B10-472F-92BD-C8667AA9C1AE}.Release|Win32.ActiveCfg = Release|Win32
+ {E7116F50-2B10-472F-92BD-C8667AA9C1AE}.Release|Win32.Build.0 = Release|Win32
+ {E7116F50-2B10-472F-92BD-C8667AA9C1AE}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1172,6 +1271,7 @@
{4043FC6A-9A30-4577-8AD5-9B233C9575D8} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{BA4DED3C-E56F-4484-BFC3-9C13E461A1BE} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{0A18A071-125E-442F-AFF7-A3F68ABECF99} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
+ {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{B0C6CFF9-7DCD-4A21-8BA4-C2011E18DED8} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{7B077E7F-1BE7-4291-AB86-55E527B25CAC} = {0C808854-54D1-4230-BFF5-77B5FD905000}
@@ -1180,6 +1280,7 @@
{D6C82F86-2B05-4A7F-8CC6-D2592E66FBB9} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{692F6330-4D87-4C82-81DF-40DB5892636E} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}
+ {E7116F50-2B10-472F-92BD-C8667AA9C1AE} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}
{1C453396-D912-4213-89FD-9B489162B7B5} = {A7AB4405-FDB7-4853-9FBB-1516B1C3D80A}
{CBEC7225-0C21-4DA8-978E-1F158F8AD950} = {F69A4A6B-9360-4EBB-A280-22AA3C455AC5}
{AB91A099-7690-4ECF-8994-E458F4EA1ED4} = {F69A4A6B-9360-4EBB-A280-22AA3C455AC5}
@@ -1191,5 +1292,13 @@
{7BFD517E-7F8F-4A40-A78E-8D3632738227} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8}
{6374D55C-FABE-4A02-9CF1-4145308A56C5} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8}
{CDE9B06A-3C27-4987-8FAE-DF1006BC705D} = {DB1024A8-41BF-4AD7-9AE6-13202230D1F3}
+ {829A9309-3B94-43C0-846B-7EC9D6D35F8B} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
+ {EB751DC4-87BD-4766-B78D-DFB64BA9F988} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
+ {9EA22C31-BB7E-4C40-A698-2C6792D1E0C6} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
+ {CF78E84D-8456-44F2-8197-0E0E88D30A3C} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
+ {AA91F0AC-6562-435E-814C-5C94689FEFA2} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
+ {819C7242-6184-46FE-BC7B-C7E25C0581EE} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
+ {FB64EA08-3BC0-48AE-BE4B-74F1024B756E} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
+ {A407B661-D7DC-4E30-B268-FFF3296C35E6} = {ACFD96F2-58AA-491D-B4C0-33BD0BD57FDE}
EndGlobalSection
EndGlobal
Modified: freeswitch/branches/greenlizard/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/Makefile.am (original)
+++ freeswitch/branches/greenlizard/Makefile.am Mon Aug 20 13:37:13 2007
@@ -161,13 +161,20 @@
touch .version
src/include/switch_version.h: $(top_srcdir)/src/include/switch_version.h.in .version $(libfreeswitch_la_SOURCES) $(library_include_HEADERS)
- @force=0 ; \
- version=`svnversion . -n || echo hacked` ; \
- oldversion=`cat .version 2>/dev/null || echo "0"` ; \
- test ! -f src/include/switch_version.h || grep "@SVN_VERSION@" src/include/switch_version.h && force=1 ; \
- if test "$$oldversion" != "$$version" || test $$force = 1 ; then \
- cat src/include/switch_version.h.in | sed "s/@SVN_VERSION@/$$version/g" > src/include/switch_version.h ; \
- echo $$version > .version ; \
+ @have_version=1 ; \
+ force=0 ; \
+ grep "@SWITCH_VERSION_REVISION@" src/include/switch_version.h.in > /dev/null && have_version=0 ; \
+ test ! -f src/include/switch_version.h || grep "@SWITCH_VERSION_REVISION@" src/include/switch_version.h > /dev/null && force=1 ; \
+ if test $$have_version = 1 ; then \
+ cat src/include/switch_version.h.in > src/include/switch_version.h ; \
+ touch .version ; \
+ else \
+ version=`svnversion . -n || echo hacked` ; \
+ oldversion=`cat .version 2>/dev/null || echo "0"` ; \
+ if test "$$oldversion" != "$$version" || test $$force = 1 ; then \
+ cat src/include/switch_version.h.in | sed "s/@SWITCH_VERSION_REVISION@/$$version/g" > src/include/switch_version.h ; \
+ echo $$version > .version ; \
+ fi ; \
fi ;
update:
Modified: freeswitch/branches/greenlizard/build/modules.conf.in
==============================================================================
--- freeswitch/branches/greenlizard/build/modules.conf.in (original)
+++ freeswitch/branches/greenlizard/build/modules.conf.in Mon Aug 20 13:37:13 2007
@@ -8,6 +8,7 @@
#applications/mod_soundtouch
#applications/mod_rss
#asr_tts/mod_cepstral
+#asr_tts/mod_openmrcp
#codecs/mod_amr
codecs/mod_g711
#codecs/mod_g722
@@ -28,6 +29,7 @@
endpoints/mod_sofia
#endpoints/mod_wanpipe
endpoints/mod_woomera
+#../../libs/openzap/mod_openzap
#event_handlers/mod_cdr
#event_handlers/mod_event_multicast
event_handlers/mod_event_socket
Modified: freeswitch/branches/greenlizard/conf/freeswitch.xml
==============================================================================
--- freeswitch/branches/greenlizard/conf/freeswitch.xml (original)
+++ freeswitch/branches/greenlizard/conf/freeswitch.xml Mon Aug 20 13:37:13 2007
@@ -121,6 +121,7 @@
<!-- ASR /TTS -->
<!-- none for mod_cepstral -->
<!--#include "rss.conf.xml"-->
+ <!--#include "mod_openmrcp.conf.xml"-->
<!-- Say -->
<!-- none for mod_say_en -->
Modified: freeswitch/branches/greenlizard/conf/xml_cdr.conf.xml
==============================================================================
--- freeswitch/branches/greenlizard/conf/xml_cdr.conf.xml (original)
+++ freeswitch/branches/greenlizard/conf/xml_cdr.conf.xml Mon Aug 20 13:37:13 2007
@@ -10,7 +10,7 @@
<!-- <param name="retries" value="2"/> -->
<!-- delay between retries in seconds, default is 5 seconds -->
- <!-- <param name="retries" value="1"/> -->
+ <!-- <param name="delay" value="1"/> -->
<!-- optional: full path to the error log dir for failed web posts if not specified its <freeswitch>/logs/xml_cdr_curl -->
<!-- <param name="errLogDir" value="/tmp"/> -->
Modified: freeswitch/branches/greenlizard/configure.in
==============================================================================
--- freeswitch/branches/greenlizard/configure.in (original)
+++ freeswitch/branches/greenlizard/configure.in Mon Aug 20 13:37:13 2007
@@ -1,8 +1,16 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
+# Must change all of the below together
+# For a release, set revision for that tagged release as well and uncomment
+AC_INIT([freeswitch], [1.0.pre1], BUG-REPORT-ADDRESS)
+AC_SUBST(SWITCH_VERSION_MAJOR, [1])
+AC_SUBST(SWITCH_VERSION_MINOR, [0])
+AC_SUBST(SWITCH_VERSION_MICRO, [pre1])
+#AC_SUBST(SWITCH_VERSION_REVISION, [svn-revision-here])
+
+AC_CONFIG_FILES([src/include/switch_version.h.in:src/include/switch_version.h.template])
-AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_AUX_DIR(build/config)
AM_INIT_AUTOMAKE(libfreeswitch,0.1)
AC_CONFIG_SRCDIR([src/switch.c])
@@ -106,9 +114,6 @@
# set DYNAMIC_LIB_EXTEN
# we should really be using libtool so we don't need to do this
case "$host" in
- *darwin*)
- DYNAMIC_LIB_EXTEN="dylib"
- ;;
*cygwin* | *mingw*)
DYNAMIC_LIB_EXTEN="dll"
;;
@@ -117,6 +122,10 @@
;;
esac
+# Enable debugging
+AC_ARG_ENABLE(64,
+[AC_HELP_STRING([--enable-64],[build with 64 bit support])],[enable_64="$enable_64"],[enable_64="yes"])
+
# tweak compiler specific flags
if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
APR_ADDTO(SWITCH_AM_CFLAGS, -KPIC)
@@ -126,6 +135,10 @@
APR_ADDTO(SWITCH_AM_CXXFLAGS, "-features=extensions")
APR_ADDTO(SWITCH_AM_LDFLAGS, -R${prefix}/lib)
+ if test "${enable_64}" = "yes"; then
+ APR_ADDTO(SWITCH_AM_CFLAGS, -m64)
+ APR_ADDTO(SWITCH_AM_LDFLAGS, -L/opt/csw/lib/amd64)
+ fi
elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then
APR_ADDTO(SWITCH_AM_CFLAGS, -fPIC)
APR_ADDTO(SWITCH_AM_CXXFLAGS, -fPIC)
@@ -387,5 +400,6 @@
AC_CONFIG_SUBDIRS(libs/speex)
AC_CONFIG_SUBDIRS(libs/xmlrpc-c)
AC_CONFIG_SUBDIRS(libs/portaudio)
+#AC_CONFIG_SUBDIRS(libs/openmrcp)
AC_OUTPUT
Modified: freeswitch/branches/greenlizard/libs/libteletone/src/libteletone.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/libteletone/src/libteletone.h (original)
+++ freeswitch/branches/greenlizard/libs/libteletone/src/libteletone.h Mon Aug 20 13:37:13 2007
@@ -74,6 +74,9 @@
#ifdef __cplusplus
extern "C" {
#endif
+
+#include <math.h>
+
#define TELETONE_MAX_DTMF_DIGITS 128
#define TELETONE_MAX_TONES 6
#define TELETONE_TONE_RANGE 127
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/RELEASE
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/RELEASE (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/RELEASE Mon Aug 20 13:37:13 2007
@@ -9,6 +9,9 @@
and in less than 10 lines, written in 3rd person English, with
complete sentences />
+The stack now compiles and runs on Symbian SDK with Open C support
+enabled.
+
Bugs in blaa and foo have been fixed. The stack now supports
use of foobar...
@@ -24,10 +27,13 @@
New features in API are marked with Doxytag macro @VERSION_1_12_7.
libsofia-sip-ua:
+- Added access point selection functionality for Open C / Symbian
- Removed extra system headers from <sofia-sip/stun_common.h>
- Added global variable su_socket_blocking. If it is set to true,
sockets are created as blocking.
- Added accessor function nta_outgoing_branch()
+- Added SIP headers Alert-Info and Reply-To.
+- Added macros SIP_HAVE_XXXX for extra headers, e.g., SIP_HAVE_ALERT_INFO().
- **template**: Added foobar() function (sofia-sip/foobar.h).
- This release is ABI/API compatible with applications linked against
any 1.12.x release. However, applications built against this release won't
@@ -52,7 +58,7 @@
- roughly sorted by number of patches accepted
/>
-- **template**: First Surname (patch to nua/soa/msg)
+- Kai Vehmanen (fixes to win32 VC6/2005 project files)
See the AUTHORS file in the distribution package.
@@ -65,6 +71,13 @@
- section may be omitted for minor releases
/>
+IPv6 support can now be disabled in VC6/VC2005 builds, by
+setting SU_HAVE_IN6 to zero `win32/sofia-sip/su_configure.h'.
+
+Symbian Open C build and packaging (SIS) files for libsofia-sip-ua,
+libsofia-sip-ua-glib and for several test apps have been added under
+sofia-sip/open_c.
+
Bugs fixed in this release
--------------------------
@@ -74,6 +87,5 @@
- other bugs as fixed in CVS/darcs
/>
-- **template**: #9499652 sf.net bug item title
- Fixed #1472682 sf.net bug: ACK does not find INVITE when
To URI has been changed.
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source.c Mon Aug 20 13:37:13 2007
@@ -36,12 +36,15 @@
*
*/
-#if HAVE_CONFIG_H
#include "config.h"
-#endif
#include <glib.h>
+#if HAVE_OPEN_C
+#include <glib/gthread.h>
+#include <glib_global.h>
+#endif
+
#define SU_PORT_IMPLEMENTATION 1
#define SU_MSG_ARG_T union { char anoymous[4]; }
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source_test.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source_test.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua-glib/su-glib/su_source_test.c Mon Aug 20 13:37:13 2007
@@ -32,9 +32,7 @@
* @date Created: Thu Mar 18 19:40:51 1999 pessi
*/
-#if HAVE_CONFIG_H
#include "config.h"
-#endif
#include <stdlib.h>
#include <string.h>
@@ -52,6 +50,7 @@
#include "sofia-sip/su_wait.h"
#include "sofia-sip/su_log.h"
+#include <glib/gthread.h>
#include "sofia-sip/su_glib.h"
struct pinger {
@@ -373,11 +372,13 @@
}
}
+#if HAVE_SIGNAL
static
RETSIGTYPE term(int n)
{
exit(1);
}
+#endif
void
time_test(void)
@@ -433,6 +434,10 @@
char *argv0 = argv[0];
+#if HAVE_OPEN_C
+ dup2(1, 2);
+#endif
+
while (argv[1]) {
if (strcmp(argv[1], "-v") == 0) {
opt_verbatim = 1;
@@ -457,7 +462,15 @@
}
}
+#if HAVE_OPEN_C
+ opt_verbatim = 1;
+ opt_singlethread = 1;
+ su_log_soft_set_level(su_log_default, 9);
+#endif
+
+#if HAVE_SIGNAL
signal(SIGTERM, term);
+#endif
su_init(); atexit(su_deinit);
@@ -509,9 +522,15 @@
printf("%s exiting\n", argv0);
#ifndef HAVE_WIN32
+#if HAVE_SIGNAL
if (sleeppid)
kill(sleeppid, SIGTERM);
#endif
+#endif
+#if HAVE_OPEN_C
+ sleep(7);
+#endif
+
return 0;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/bnf/torture_bnf.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/bnf/torture_bnf.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/bnf/torture_bnf.c Mon Aug 20 13:37:13 2007
@@ -320,13 +320,14 @@
TEST(host_has_domain_invalid("valid."), 0);
TEST(host_has_domain_invalid("1-.invalid."), 0);
- /* Invalid IP4 addresses (extra leading zeros) */
+ /* Invalid IP4 address (extra leading zeros) */
TEST_1(!host_cmp("127.0.0.1", "127.0.0.01"));
- TEST_1(!host_cmp("[ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]",
- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
/* Invalid reference (extra leading zeros) */
TEST_1(host_cmp("[0ffff:0ffff:0ffff:0ffff:0ffff:0ffff:255.255.255.255]",
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
+#if SU_HAVE_IN6
+ TEST_1(!host_cmp("[ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]",
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
TEST_1(!host_cmp("::1", "::001"));
TEST_1(!host_cmp("[::1]", "::1"));
TEST_1(!host_cmp("[::1]", "::0.0.0.1"));
@@ -334,6 +335,7 @@
TEST_1(!host_cmp("::ffff:127.0.0.1", "::ffff:7f00:1"));
TEST_1(!host_cmp("::ffff:127.0.0.1", "::ffff:7f00:1"));
TEST_1(!host_cmp("[::ffff:127.0.0.1]", "[::7f00:1]"));
+#endif
TEST_1(host_cmp("::", "0.0.0.0"));
TEST_1(host_cmp("::1", "0.0.0.1"));
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/Doxyfile.aliases Mon Aug 20 13:37:13 2007
@@ -49,4 +49,7 @@
"VERSION_1_12_6=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.6.txt\">1.12.6</a>" \
"NEW_1_12_6=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.6.txt\">1.12.6</a>" \
"EXP_1_12_6=@since Experimental in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.6.txt\">1.12.6</a>, available if --enable-experimental configuration option is given" \
+ "VERSION_1_12_7=<a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>" \
+ "NEW_1_12_7=@since New in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>" \
+ "EXP_1_12_7=@since Experimental in <a href=\"http://sofia-sip.sf.net/relnotes/relnotes-sofia-sip-1.12.7.txt\">1.12.7</a>, available if --enable-experimental configuration option is given" \
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/conformance.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/conformance.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/docs/conformance.docs Mon Aug 20 13:37:13 2007
@@ -66,9 +66,9 @@
<th>Notes</td>
</tr>
+<a name="3261"></a>
<tr valign=top>
<th align="left">
- <a name="3261"></a>
@RFC3261: Basic SIP Protocol
</th>
<td>
@@ -90,9 +90,9 @@
</td>
</tr>
+<a name="3261.19"></a> <a name="3261.20"></a>
<tr valign=top>
<th align="left">
- <a name="3261.19"></a> <a name="3261.20"></a>
@RFC3261 Sections 19 and 20:<br>
Syntax and encoding
</td>
@@ -116,6 +116,7 @@
@ref sip_accept "Accept",
@ref sip_accept_encoding "Accept-Encoding",
@ref sip_accept_language "Accept-Language",
+ @ref sip_alert_info "Alert-Info" (@VERSION_1_12_7),
@ref sip_allow "Allow",
@ref sip_authentication_info "Authentication-Info",
@ref sip_authorization "Authorization",
@@ -142,6 +143,7 @@
@ref sip_proxy_authorization "Proxy-Authorization",
@ref sip_proxy_require "Proxy-Require",
@ref sip_record_route "Record-Route",
+ @ref sip_reply_to "Reply-To" (@VERSION_1_12_7),
@ref sip_require "Require",
@ref sip_retry_after "Retry-After",
@ref sip_route "Route",
@@ -163,18 +165,15 @@
parsers.
</td>
<td>
- - Unsupported headers:
- Alert-Info,
- Reply-To
- Automatic escaping of reserved characters has not been
implemented.
- Using NUL (zero byte) in doublequoted strings has not been implemented
</td>
</tr>
+<a name="3261.18"></a>
<tr valign=top>
<th align="left">
- <a name="3261.18"></a>
@RFC3261 Section 18:<br>
UDP and TCP transports
</th>
@@ -201,9 +200,9 @@
</td>
</tr>
+<a name="3261.17"></a>
<tr valign=top>
<th align="left">
- <a name="3261.17"></a>
@RFC3261 Section 17:<br> Transactions
</th>
<td>
@@ -214,7 +213,7 @@
Default values for SIP timers are those specified by @RFC3261. The
defaults for T1, T1x64, T2 and T4 can be changed via
- configuration tags defined in <nta_tag.h>.
+ configuration tags defined in <sofia-sip/nta_tag.h>.
</td>
<td>
@@ -222,9 +221,9 @@
</tr>
+<a name="3261.26"></a>
<tr valign=top>
<th align="left">
- <a name="3261.26"></a>
@RFC3261 Section 26:<br> Security
</th>
<td>
@@ -234,19 +233,19 @@
</td>
<td>
Missing:
- - TLS certificate checking
+ - Authorizing connections with TLS certificates
- S/MIME
</td>
</tr>
+<a name="2617"></a>
<tr valign=top>
<th align="left">
- <a name="2617"></a>
@RFC2617: HTTP Digest Authentication
</th>
<td>
- Sofia-SIP an authentication client and server modules implementing
- HTTP Digest authentication.
+ Sofia-SIP includes authentication client and server modules
+ implementing HTTP Digest authentication.
HTTP Digest is a simple challenge-response authentication
scheme defined in @RFC2617 based on the UA sending a checksum
@@ -283,9 +282,9 @@
</td>
</tr>
+<a name="3262"></a>
<tr valign=top>
<th align="left">
- <a name="3262"></a>
@RFC3262: PRACK and 100rel
</th>
<td>
@@ -305,9 +304,9 @@
</td>
</tr>
+<a name="3263"></a>
<tr valign=top>
<th align="left">
- <a name="3263"></a>
@RFC3263: Locating SIP Servers
</th>
<td>
@@ -320,9 +319,9 @@
</td>
</tr>
+<a name="3265"></a>
<tr valign=top>
<th align="left">
- <a name="3265"></a>
@RFC3265: SIP Event Notifications
</th>
<td>
@@ -347,9 +346,9 @@
</td>
</tr>
+<a name="2806"></a>
<tr valign=top>
<th align="left">
- <a name="2806"></a>
@RFC2806: tel URI
</th>
<td>
@@ -362,9 +361,9 @@
</td>
</tr>
+<a name="2976"></a>
<tr valign=top>
<th align="left">
- <a name="2976"></a>
@RFC2976: INFO
</th>
<td>
@@ -377,9 +376,9 @@
</tr>
+<a name="3311"></a>
<tr valign=top>
<th align="left">
- <a name="3311"></a>
@RFC3311: UPDATE
</th>
<td>
@@ -396,9 +395,9 @@
</tr>
+<a name="3313"></a>
<tr valign=top>
<th align="left">
- <a name="3313"></a>
@RFC3313: Media Authentication
</th>
<td>
@@ -413,9 +412,9 @@
</tr>
+<a name="3323"></a>
<tr valign=top>
<th align="left">
- <a name="3323"></a>
@RFC3323: Privacy
</th>
<td>
@@ -441,9 +440,9 @@
</tr>
+<a name="3326"></a>
<tr valign=top>
<th align="left">
- <a name="3326"></a>
@RFC3326: Reason
</th>
<td>
@@ -457,9 +456,9 @@
</tr>
+<a name="3325"></a>
<tr valign=top>
<th align="left">
- <a name="3325"></a>
@RFC3325: Asserted Identity
</th>
<td>
@@ -476,9 +475,9 @@
</td>
</tr>
+<a name="3327"></a>
<tr valign=top>
<th align="left">
- <a name="3327"></a>
@RFC3327: Path
</th>
<td>
@@ -493,9 +492,9 @@
</td>
</tr>
+<a name="3329"></a>
<tr valign=top>
<th align="left">
- <a name="3329"></a>
@RFC3329:
Security Agreement
</th>
@@ -517,9 +516,9 @@
</td>
</tr>
+<a name="3361"></a>
<tr valign=top>
<th align="left">
- <a name="3361"></a>
@RFC3361: DHCPv4 option for locating SIP servers.
</th>
<td>
@@ -532,9 +531,9 @@
</td>
</tr>
+<a name="3420"></a>
<tr valign=top>
<th align="left">
- <a name="3420"></a>
@RFC3420: message/sipfrag
</th>
<td>
@@ -547,9 +546,9 @@
</td>
</tr>
+<a name="3428"></a>
<tr valign=top>
<th align="left">
- <a name="3428"></a>
@RFC3428: MESSAGE
</th>
<td>
@@ -560,9 +559,9 @@
</td>
</tr>
+<a name="3486"></a>
<tr valign=top>
<th align="left">
- <a name="3486"></a>
@RFC3486: Compressing SIP
</th>
<td>
@@ -575,9 +574,9 @@
</td>
</tr>
+<a name="3515"></a>
<tr valign=top>
<th align="left">
- <a name="3515"></a>
@RFC3515: REFER
</th>
<td>
@@ -600,9 +599,9 @@
</td>
</tr>
+<a name="3608"></a>
<tr valign=top>
<th align="left">
- <a name="3608"></a>
@RFC3608: Service-Route
</th>
<td>
@@ -619,9 +618,9 @@
</td>
</tr>
+<a name="3680"></a>
<tr valign=top>
<th align="left">
- <a name="3680"></a>
@RFC3680: "reg" event
</th>
<td>
@@ -643,9 +642,9 @@
</td>
</tr>
+<a name="3824"></a>
<tr valign=top>
<th align="left">
- <a name="3824"></a>
@RFC3824: ENUM
</th>
<td>
@@ -659,9 +658,9 @@
</td>
</tr>
+<a name="3840"></a>
<tr valign=top>
<th align="left">
- <a name="3840"></a>
@RFC3840: Callee Capabilities
</th>
<td>
@@ -681,9 +680,9 @@
</tr>
+<a name="3841"></a>
<tr valign=top>
<th align="left">
- <a name="3841"></a>
@RFC3841: Caller Preferences
</th>
<td>
@@ -712,9 +711,9 @@
</td>
</tr>
+<a name="3842"></a>
<tr valign=top>
<th align="left">
- <a name="3842"></a>
@RFC3842: Message waiting event
</th>
<td>
@@ -734,9 +733,9 @@
</td>
</tr>
+<a name="3856"></a>
<tr valign=top>
<th align="left">
- <a name="3856"></a>
@RFC3856: Presence
</th>
<td>
@@ -760,9 +759,9 @@
</td>
</tr>
+<a name="3857"></a> <a name="3858"></a>
<tr valign=top>
<th align="left">
- <a name="3857"></a> <a name="3858"></a>
@RFC3857: "winfo" event template package<br>
@RFC3858: winfo format
</th>
@@ -783,9 +782,9 @@
</td>
</tr>
+<a name="3891"></a>
<tr valign=top>
<th align="left">
- <a name="3891"></a>
@RFC3891: Replaces
</th>
<td>
@@ -799,9 +798,9 @@
</td>
</tr>
+<a name="3892"></a>
<tr valign=top>
<th align="left">
- <a name="3892"></a>
@RFC3892: Referred-By
</th>
<td>
@@ -819,9 +818,9 @@
</td>
</tr>
+<a name="3903"></a>
<tr valign=top>
<th align="left">
- <a name="3903"></a>
@RFC3903: PUBLISH
</th>
<td>
@@ -839,9 +838,9 @@
</td>
</tr>
+<a name="4028"></a>
<tr valign=top>
<th align="left">
- <a name="4028"></a>
@RFC4028: Session Timers
</th>
<td>
@@ -865,9 +864,9 @@
</td>
</tr>
+<a name="4320"></a>
<tr valign=top>
<th align="left">
- <a name="4320"></a>
@RFC4320: Actions Addressing Identified Issues with SIP's Non-INVITE Transaction
</th>
<td>
@@ -896,10 +895,12 @@
<th>Notes</td>
</tr>
+<a name="4566"></a>
+<a name="2327"></a>
+<a name="3266"></a>
<tr valign=top>
<th align="left" align="left">
- <a name="2327"></a>
- @RFC2327: SDP (Session Description Protocol)
+ @RFC4566: SDP: Session Description Protocol
</th>
<td>
Generic support (generating, parsing and syntax checking) for SDP.
@@ -920,17 +921,20 @@
The attributes "a=sendrecv", "a=sendonly", "a=recvonly",
"a=inactive", @ref sdp_rtpmap_s "a=rtpmap", and "a=fmtp" are parsed.
- The implementation tries to follow draft-ietf-mmusic-sdp-new-25,
- draft Internet Standard for SDP in progress.
+ The implementation partially implements @RFC4566. Note that
+ definiton of 'token' was updated in @RFC4566 and the parser has not
+ been updated yet.
</td>
<td>
- - see also <a href="#4566">RFC 4566</a>
+ @RFC4566 obsoletes
+ - @RFC2327: SDP (Session Description Protocol)
+ - @RFC3266: IP6 in SDP
</td>
</tr>
+<a name="3264"></a>
<tr valign=top>
<th align="left">
- <a name="3264"></a>
@RFC3264: SDP Offer/Answer Negotiation
</th>
<td>
@@ -942,22 +946,9 @@
</td>
</tr>
+<a name="3312"></a>
<tr valign=top>
<th align="left">
- <a name="3266"></a>
- @RFC3266: IP6 in SDP
- </th>
- <td>
- Representation of IP6 addresses within SDP message.
- </td>
- <td>
- - see also <a href="#4566">RFC 4566</a>
- </td>
-</tr>
-
-<tr valign=top>
- <th align="left">
- <a name="3312"></a>
@RFC3312: Preconditions
</th>
<td>
@@ -978,9 +969,9 @@
</td>
</tr>
+<a name="3388"></a>
<tr valign=top>
<th align="left">
- <a name="3388"></a>
@RFC3388: Grouping of Media Lines
</th>
<td>
@@ -998,9 +989,9 @@
</tr>
+<a name="3407"></a>
<tr valign=top>
<th align="left">
- <a name="3407"></a>
@RFC3407: Capability Declaration
</th>
<td>
@@ -1016,9 +1007,9 @@
</tr>
+<a name="3524"></a>
<tr valign=top>
<th align="left">
- <a name="3524"></a>
@RFC3524: SRF
</th>
<td>
@@ -1032,9 +1023,9 @@
</td>
</tr>
+<a name="3556"></a>
<tr valign=top>
<th align="left">
- <a name="3556"></a>
@RFC3556: Bandwidth
</th>
<td>
@@ -1048,9 +1039,9 @@
</td>
</tr>
+<a name="3605"></a>
<tr valign=top>
<th align="left">
- <a name="3605"></a>
@RFC3605: RTCP attribute
</th>
<td>
@@ -1064,9 +1055,9 @@
</td>
</tr>
+<a name="3890"></a>
<tr valign=top>
<th align="left">
- <a name="3890"></a>
@RFC3890: TIAS
</th>
<td>
@@ -1080,9 +1071,16 @@
</td>
</tr>
+</table>
+
+
+*/
+
+/* Overflow:
+
+<a name="4566"></a>
<tr valign=top>
<th align="left">
- <a name="4566"></a>
@RFC4566: SDP: Session Description Protocol
</th>
<td>
@@ -1093,15 +1091,10 @@
</td>
</tr>
-</table>
-
-*/
-
-/* Overflow:
+<a name="3320"></a>
<tr valign=top>
<th align="left">
- <a name="3320"></a>
@RFC3320: SigComp
</th>
<td>
@@ -1116,9 +1109,9 @@
</td>
</tr>
+<a name="3321"></a>
<tr valign=top>
<th align="left">
- <a name="3321"></a>
@RFC3321: SigComp Extended operations
</th>
<td>
@@ -1132,9 +1125,9 @@
</td>
</tr>
+<a name="3325"></a>
<tr valign=top>
<th align="left">
- <a name="3325"></a>
@RFC3325: Asserted Identity
</th>
<td>
@@ -1147,9 +1140,9 @@
</td>
</tr>
+<a name="3485"></a>
<tr valign=top>
<th align="left">
- <a name="3485"></a>
@RFC3485: SIP/SDP Dictionary
</th>
<td>
@@ -1166,9 +1159,9 @@
- Implicitly registered user identities
+<a name="3959"></a>
<tr valign=top>
<th align="left">
- <a name="3959"></a>
@RFC3959: early-session
</th>
<td>
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/features/features.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/features/features.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/features/features.c Mon Aug 20 13:37:13 2007
@@ -35,7 +35,7 @@
#include <stddef.h>
#include <sofia-sip/su_configure.h>
-#include <tport_tls.h>
+#include "tport_tls.h"
#include "sofia-sip/sofia_features.h"
/** The name and version of software package providing Sofia-SIP-UA library.
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http.docs Mon Aug 20 13:37:13 2007
@@ -20,7 +20,7 @@
* documented in a <a href="modules.html">submodule</a> for the header. In
* addition to the header structure, there is defined a @em header @em class
* structure and some standard functions for each header in the
- * <http_header.h> include file. For header @c X, there are types,
+ * <sofia-sip/http_header.h> include file. For header @c X, there are types,
* functions, macros and header class as follows:
*
* - @c http_X_t is the structure used to store parsed header,
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http_basic.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http_basic.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/http_basic.c Mon Aug 20 13:37:13 2007
@@ -140,7 +140,7 @@
*
* Note that version string is not copied; it @b MUST remain constant during
* lifetime of the @c http_request_t object. You can use constants
- * http_version_1_1 or http_version_1_0 declared in <http_header.h>.
+ * http_version_1_1 or http_version_1_0 declared in <sofia-sip/http_header.h>.
*/
http_request_t *http_request_create(su_home_t *home,
http_method_t method, char const *name,
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/test_http.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/test_http.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/http/test_http.c Mon Aug 20 13:37:13 2007
@@ -112,6 +112,10 @@
usage(1);
}
+#if HAVE_OPEN_C
+ tstflags |= tst_verbatim;
+#endif
+
if (!test_mclass)
test_mclass = http_default_mclass();
@@ -125,6 +129,10 @@
retval |= http_chunk_test(); fflush(stdout);
retval |= test_query_parser(); fflush(stdout);
+#if HAVE_OPEN_C
+ sleep(5);
+#endif
+
return retval;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/Makefile.am (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/Makefile.am Mon Aug 20 13:37:13 2007
@@ -23,14 +23,14 @@
# Rules for building the targets
nobase_include_sofia_HEADERS = \
- sofia-sip/rc4.h \
sofia-sip/base64.h \
- sofia-sip/token64.h \
+ sofia-sip/token64.h \
sofia-sip/uniqueid.h
libipt_la_SOURCES = base64.c token64.c
EXTRA_DIST = sofia-sip/utf8.h \
+ sofia-sip/rc4.h \
utf8internal.h \
utf8.c ucs2.c ucs4.c rc4.c \
utf8test.c
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/ipt.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/ipt.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/ipt/ipt.docs Mon Aug 20 13:37:13 2007
@@ -15,9 +15,6 @@
* @section ipt_overview Overview
*
* This module contain some routines useful for IPT applications, like
- * - base64.h BASE64 encoding/decoding,
- * - token64.h encoding/decoding binary as SIP/HTTP token,
- * - utf8.h UTF8 encoding/decoding,
- * - sha1.h SHA1 hash routines, and
- * - rc4.h arcfour random number generator.
+ * - <sofia-sip/base64.h> BASE64 encoding/decoding,
+ * - <sofia-sip/token64.h> encoding/decoding binary as SIP/HTTP token,
*/
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c Mon Aug 20 13:37:13 2007
@@ -133,6 +133,7 @@
char const *realm = NULL, *opaque = NULL, *db = NULL, *allows = NULL;
char const *qop = NULL, *algorithm = NULL;
unsigned expires = 60 * 60, next_expires = 5 * 60;
+ unsigned max_ncount = 0;
unsigned blacklist = 5;
int forbidden = 0;
int anonymous = 0;
@@ -152,6 +153,7 @@
AUTHTAG_ALGORITHM_REF(algorithm),
AUTHTAG_EXPIRES_REF(expires),
AUTHTAG_NEXT_EXPIRES_REF(next_expires),
+ AUTHTAG_MAX_NCOUNT_REF(max_ncount),
AUTHTAG_BLACKLIST_REF(blacklist),
AUTHTAG_FORBIDDEN_REF(forbidden),
AUTHTAG_ANONYMOUS_REF(anonymous),
@@ -172,6 +174,7 @@
msg_commalist_d(am->am_home, &s, &am->am_allow, NULL);
am->am_expires = expires;
am->am_next_exp = next_expires;
+ am->am_max_ncount = max_ncount;
am->am_blacklist = blacklist;
am->am_forbidden = forbidden;
am->am_anonymous = anonymous;
@@ -1437,6 +1440,16 @@
as->as_stale = 1;
}
+ if (am->am_max_ncount && ar->ar_nc) {
+ unsigned long nc = strtoul(ar->ar_nc, NULL, 10);
+
+ if (nc == 0 || nc > am->am_max_ncount) {
+ SU_DEBUG_5(("auth_method_digest: nonce used %s times, max %u\n",
+ ar->ar_nc, am->am_max_ncount));
+ as->as_stale = 1;
+ }
+ }
+
/* We should also check cnonce, nc... */
return 0;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_tag.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_tag.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_tag.c Mon Aug 20 13:37:13 2007
@@ -64,7 +64,7 @@
* authentication module, like "Digest" or "Basic", or an plugin module,
* like "SGMF+Digest".
*
- * @sa See <auth_plugin.h> for plugin interface.
+ * @sa See <sofia-sip/auth_plugin.h> for plugin interface.
*/
tag_typedef_t authtag_method = STRTAG_TYPEDEF(method);
@@ -150,6 +150,17 @@
*/
tag_typedef_t authtag_next_expires = UINTTAG_TYPEDEF(next_expires);
+/**@def AUTHTAG_MAX_NCOUNT()
+ *
+ * Max nonce count value.
+ *
+ * The tag AUTHTAG_MAX_NCOUNT() specifies the maximum number of times a
+ * nonce should be used.
+ *
+ * @todo Count actual usages and don't trust "nc" parameter only.
+ */
+tag_typedef_t authtag_max_ncount = UINTTAG_TYPEDEF(max_ncount);
+
/**@def AUTHTAG_BLACKLIST()
*
* Blacklist time.
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec.docs Mon Aug 20 13:37:13 2007
@@ -19,11 +19,10 @@
*
* @section auth_module Server Verifying Authentication
*
- * The file <auth_module.h> defines the interface used by a server verifying
- * the authentication from client. After the server has created an @ref
- * auth_mod_t "authentication module", the usual authentication operation is
- * simple enough:
-
+ * The file <sofia-sip/auth_module.h> defines the interface used by a server
+ * verifying the authentication from client. After the server has created an
+ * @ref auth_mod_t "authentication module", the usual authentication
+ * operation is simple enough:
* -# server initializes an #auth_status_t structure with information from
* the request
* -# server calls auth_mod_method()
@@ -42,8 +41,8 @@
*
* When the server creates the authentication module with auth_mod_create(),
* it can specify numerous parameters affecting the authentication protocol
- * and algorithms. The parameter tags are defined in <auth_module.h>. The
- * most important parameters include:
+ * and algorithms. The parameter tags are defined in
+ * <sofia-sip/auth_module.h>. The most important parameters include:
*
* - AUTHTAG_METHOD(),
* - AUTHTAG_ALGORITHM(),
@@ -52,7 +51,7 @@
*
* @section auth_client Client Authenticating User
*
- * The file <auth_client.h> defines the interface used by a client
+ * The file <sofia-sip/auth_client.h> defines the interface used by a client
* authenticating a user with a server. Because there may be multiple
* servers or proxies requiring authentication, the client-side
* authentication information is represented using a list of #auth_client_t
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec_debug.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec_debug.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/iptsec_debug.c Mon Aug 20 13:37:13 2007
@@ -44,7 +44,7 @@
* The IPTSEC_DEBUG environment variable is used to determine the debug
* logging level for @b iptsec module. The default level is 3.
*
- * @sa <su_debug.h>, iptsec_log, SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, iptsec_log, SOFIA_DEBUG
*/
extern char const IPTSEC_DEBUG[];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_module.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_module.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_module.h Mon Aug 20 13:37:13 2007
@@ -322,6 +322,13 @@
authtag_next_expires_ref, tag_uint_vr((&x))
SOFIAPUBVAR tag_typedef_t authtag_next_expires_ref;
+/** Maximum nonce count allowed. */
+#define AUTHTAG_MAX_NCOUNT(x) authtag_max_ncount, tag_uint_v((x))
+SOFIAPUBVAR tag_typedef_t authtag_max_ncount;
+
+#define AUTHTAG_MAX_NCOUNT_REF(x) authtag_max_ncount_ref, tag_uint_vr((&x))
+SOFIAPUBVAR tag_typedef_t authtag_max_ncount_ref;
+
/** Extra delay when responding if provided invalid credentials or nonce. */
#define AUTHTAG_BLACKLIST(x) authtag_blacklist, tag_uint_v((x))
SOFIAPUBVAR tag_typedef_t authtag_blacklist;
@@ -343,13 +350,6 @@
#define AUTHTAG_ANONYMOUS_REF(x) authtag_anonymous_ref, tag_bool_vr((&x))
SOFIAPUBVAR tag_typedef_t authtag_anonymous_ref;
-/** Fake authentication procedure - do not check result. */
-#define AUTHTAG_FAKE(x) authtag_fake, tag_bool_v((x))
-SOFIAPUBVAR tag_typedef_t authtag_fake;
-
-#define AUTHTAG_FAKE_REF(x) authtag_fake_ref, tag_bool_vr((&x))
-SOFIAPUBVAR tag_typedef_t authtag_fake_ref;
-
/** HSS client structure. */
#define AUTHTAG_HSS(x) authtag_hss, tag_ptr_v((x))
SOFIAPUBVAR tag_typedef_t authtag_hss;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_plugin.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_plugin.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/sofia-sip/auth_plugin.h Mon Aug 20 13:37:13 2007
@@ -164,6 +164,8 @@
su_md5_t am_hmac_ipad; /**< MD5 with inner pad */
su_md5_t am_hmac_opad; /**< MD5 with outer pad */
+
+ unsigned am_max_ncount:1; /**< If nonzero, challenge with new nonce after ncount */
};
SOFIAPUBFUN
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/iptsec/test_auth_digest.c Mon Aug 20 13:37:13 2007
@@ -92,11 +92,9 @@
unsigned offset;
-void su_time(su_time_t *tv)
+void offset_time(su_time_t *tv)
{
- tv->tv_sec = time(NULL) + offset +
- /* Seconds from 1.1.1900 to 1.1.1970 */ 2208988800UL ;
- tv->tv_usec = 555555;
+ tv->tv_sec += offset;
}
int test_digest()
@@ -896,6 +894,7 @@
AUTHTAG_QOP("auth,auth-int"),
AUTHTAG_FORBIDDEN(1),
AUTHTAG_ANONYMOUS(1),
+ AUTHTAG_MAX_NCOUNT(1),
TAG_END()));
reinit_as(as);
@@ -942,6 +941,36 @@
TEST(as->as_status, 401);
TEST_1(au = (void *)as->as_response); TEST_1(au->au_params);
TEST_S(msg_params_find(au->au_params, "stale="), "true");
+
+ TEST(auc_challenge(&aucs, home, (msg_auth_t *)as->as_response,
+ sip_authorization_class), 1);
+ msg_header_remove(m2, (void *)sip, (void *)sip->sip_authorization);
+ TEST(auc_authorization(&aucs, m2, (msg_pub_t*)sip, rq->rq_method_name,
+ (url_t *)"sip:surf3@ims3.so.noklab.net",
+ sip->sip_payload), 1);
+ TEST_1(sip->sip_authorization);
+ TEST_S(msg_header_find_param(sip->sip_authorization->au_common, "nc="),
+ "00000001");
+
+ reinit_as(as);
+ auth_mod_check_client(am, as, sip->sip_authorization, ach);
+ TEST(as->as_status, 0);
+
+ /* Test nonce count check */
+ msg_header_remove(m2, (void *)sip, (void *)sip->sip_authorization);
+ TEST(auc_authorization(&aucs, m2, (msg_pub_t*)sip, rq->rq_method_name,
+ (url_t *)"sip:surf3@ims3.so.noklab.net",
+ sip->sip_payload), 1);
+ TEST_1(sip->sip_authorization);
+ TEST_S(msg_header_find_param(sip->sip_authorization->au_common, "nc="),
+ "00000002");
+
+ reinit_as(as);
+ auth_mod_check_client(am, as, sip->sip_authorization, ach);
+ TEST(as->as_status, 401);
+ TEST_1(au = (void *)as->as_response); TEST_1(au->au_params);
+ TEST_S(msg_params_find(au->au_params, "stale="), "true");
+
aucs = NULL;
/* Test anonymous operation */
@@ -1210,6 +1239,9 @@
{
int retval = 0;
int i;
+ extern void (*_su_time)(su_time_t *tv);
+
+ _su_time = offset_time;
argv0 = argv[0];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_class.c Mon Aug 20 13:37:13 2007
@@ -42,10 +42,10 @@
#define TAG_NAMESPACE "tst"
-#include <test_class.h>
+#include "test_class.h"
#include <sofia-sip/msg_parser.h>
#include <sofia-sip/msg_mclass.h>
-#include <test_protos.h>
+#include "test_protos.h"
#include <sofia-sip/msg_addr.h>
extern msg_mclass_t const msg_test_mclass[1];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_table.c.in
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_table.c.in (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/msg/test_table.c.in Mon Aug 20 13:37:13 2007
@@ -47,8 +47,8 @@
#include <stddef.h>
#include <string.h>
-#include <test_class.h>
-#include <test_protos.h>
+#include "test_class.h"
+#include "test_protos.h"
#include <sofia-sip/msg_mime_protos.h>
#include <sofia-sip/msg_mclass.h>
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea.docs Mon Aug 20 13:37:13 2007
@@ -6,7 +6,7 @@
*
* Sofia Event API provides an interface to different events used in SIP
* presence and conferencing. Interface used both in client and server sides
- * is presented in <nea.h>.
+ * is presented in <sofia-sip/nea.h>.
*
* @CONTACT Pekka Pessi <Pekka.Pessi(a)nokia.com>
*
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea_debug.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea_debug.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nea/nea_debug.c Mon Aug 20 13:37:13 2007
@@ -67,7 +67,7 @@
* The NEA_DEBUG environment variable is used to determine the debug
* logging level for @b nea module. The default level is 3.
*
- * @sa <su_debug.h>, nea_log, SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, nea_log, SOFIA_DEBUG
*/
extern char const NEA_DEBUG[];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/Doxyfile.in
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/Doxyfile.in (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/Doxyfile.in Mon Aug 20 13:37:13 2007
@@ -14,6 +14,7 @@
TAGFILES += ../docs/sip.doxytags=../sip
TAGFILES += ../docs/sresolv.doxytags=../sresolv
TAGFILES += ../docs/tport.doxytags=../tport
+TAGFILES += ../docs/nua.doxytags=../nua
GENERATE_TAGFILE = ../docs/nta.doxytags
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.c Mon Aug 20 13:37:13 2007
@@ -282,7 +282,7 @@
* The NTA_DEBUG environment variable is used to determine the default
* debug logging level. The normal level is 3.
*
- * @sa <su_debug.h>, #su_log_global, #SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, #su_log_global, #SOFIA_DEBUG
*/
#ifdef DOXYGEN
extern char const NTA_DEBUG[]; /* dummy declaration for Doxygen */
@@ -336,13 +336,36 @@
* @param contact_url URL that agent uses to bind the server sockets
* @param callback pointer to callback function
* @param magic pointer to user data
- * @param tag,value,... other arguments
+ * @param tag,value,... tagged arguments
*
- * @note It is possible to provide -1 as @a contact_url.
+ * @TAGS
+ * NTATAG_ALIASES(),
+ * NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(), NTATAG_BLACKLIST(),
+ * NTATAG_CANCEL_2543(), NTATAG_CANCEL_487(), NTATAG_CLIENT_RPORT(),
+ * NTATAG_DEBUG_DROP_PROB(), NTATAG_DEFAULT_PROXY(),
+ * NTATAG_EXTRA_100(),
+ * NTATAG_MAXSIZE(), NTATAG_MAX_FORWARDS(), NTATAG_MERGE_482(), NTATAG_MCLASS()
+ * NTATAG_PASS_100(), NTATAG_PASS_408(), NTATAG_PRELOAD(), NTATAG_PROGRESS(),
+ * NTATAG_REL100(),
+ * NTATAG_SERVER_RPORT(),
+ * NTATAG_SIPFLAGS(),
+ * NTATAG_SIP_T1X64(), NTATAG_SIP_T1(), NTATAG_SIP_T2(), NTATAG_SIP_T4(),
+ * NTATAG_STATELESS(),
+ * NTATAG_TAG_3261(), NTATAG_TCP_RPORT(), NTATAG_TIMEOUT_408(),
+ * NTATAG_TIMER_C(),
+ * NTATAG_UA(), NTATAG_UDP_MTU(), NTATAG_USER_VIA(),
+ * NTATAG_USE_NAPTR(), NTATAG_USE_SRV() and NTATAG_USE_TIMESTAMP().
+ *
+ * @note The value from following tags are stored, but they currently do nothing:
+ * NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_OPTIONS(), NTATAG_SMIME()
+ *
+ * @note It is possible to provide @c (url_string_t*)-1 as @a contact_url.
+ * In that case, no server sockets are bound.
*
* @retval handle to the agent when successful,
* @retval NULL upon an error.
*
+ * @sa NUTAG_
*/
nta_agent_t *nta_agent_create(su_root_t *root,
url_string_t const *contact_url,
@@ -359,6 +382,8 @@
ta_start(ta, tag, value);
if ((agent = su_home_new(sizeof(*agent)))) {
+ unsigned timer_c;
+
agent->sa_root = root;
agent->sa_callback = callback;
agent->sa_magic = magic;
@@ -366,13 +391,20 @@
agent->sa_maxsize = 2 * 1024 * 1024; /* 2 MB */
agent->sa_bad_req_mask =
- (unsigned) ~(sip_mask_response | sip_mask_proxy);
+ /*
+ * Bit-wise not of these - what is left is suitable for UAs with
+ * 100rel, timer, events, publish
+ */
+ (unsigned) ~(sip_mask_response | sip_mask_proxy | sip_mask_registrar |
+ sip_mask_pref | sip_mask_privacy);
agent->sa_bad_resp_mask =
- (unsigned) ~(sip_mask_request | sip_mask_proxy);
+ (unsigned) ~(sip_mask_request | sip_mask_proxy | sip_mask_registrar |
+ sip_mask_pref | sip_mask_privacy);
agent->sa_t1 = NTA_SIP_T1;
agent->sa_t2 = NTA_SIP_T2;
agent->sa_t4 = NTA_SIP_T4;
agent->sa_t1x64 = 64 * NTA_SIP_T1;
+ agent->sa_timer_c = 185 * 1000;
agent->sa_drop_prob = 0;
agent->sa_is_a_uas = 0;
agent->sa_progress = 60 * 1000;
@@ -421,7 +453,9 @@
outgoing_queue_init(agent->sa_out.terminated, 0);
/* Special queues (states) for outgoing INVITE transactions */
outgoing_queue_init(agent->sa_out.inv_calling, agent->sa_t1x64); /* B */
- outgoing_queue_init(agent->sa_out.inv_proceeding, 0);
+ timer_c = (agent->sa_use_timer_c || !agent->sa_is_a_uas)
+ ? agent->sa_timer_c : 0;
+ outgoing_queue_init(agent->sa_out.inv_proceeding, timer_c); /* C */
outgoing_queue_init(agent->sa_out.inv_completed, 32000); /* Timer D */
if (leg_htable_resize(agent->sa_home, agent->sa_dialogs, 0) < 0 ||
@@ -841,17 +875,25 @@
* 0 selects the default value.
*
* @TAGS
- * NTATAG_ALIASES(), NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(),
- * NTATAG_CANCEL_2543(), NTATAG_CANCEL_487(), NTATAG_DEBUG_DROP_PROB(),
- * NTATAG_DEFAULT_PROXY(), NTATAG_EXTRA_100(), NTATAG_MAXSIZE(),
- * NTATAG_MAX_FORWARDS(),
- * NTATAG_UDP_MTU(), NTATAG_MERGE_482(), NTATAG_PASS_100(),
- * NTATAG_PRELOAD(), NTATAG_REL100(), NTATAG_RPORT(), NTATAG_SERVER_RPORT(),
- * NTATAG_TCP_RPORT(),
- * NTATAG_SIPFLAGS(), NTATAG_SIP_T1X64(), NTATAG_SIP_T1(), NTATAG_SIP_T2(),
- * NTATAG_SIP_T4(), NTATAG_SMIME(), NTATAG_STATELESS(), NTATAG_TAG_3261(),
- * NTATAG_TIMEOUT_408(), NTATAG_PASS_408(), NTATAG_UA(), NTATAG_USER_VIA(),
- * and NTATAG_USE_TIMESTAMP().
+ * NTATAG_ALIASES(),
+ * NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(), NTATAG_BLACKLIST(),
+ * NTATAG_CANCEL_2543(), NTATAG_CANCEL_487(), NTATAG_CLIENT_RPORT(),
+ * NTATAG_DEBUG_DROP_PROB(), NTATAG_DEFAULT_PROXY(),
+ * NTATAG_EXTRA_100(),
+ * NTATAG_MAXSIZE(), NTATAG_MAX_FORWARDS(), NTATAG_MERGE_482(), NTATAG_MCLASS()
+ * NTATAG_PASS_100(), NTATAG_PASS_408(), NTATAG_PRELOAD(), NTATAG_PROGRESS(),
+ * NTATAG_REL100(),
+ * NTATAG_SERVER_RPORT(),
+ * NTATAG_SIPFLAGS(),
+ * NTATAG_SIP_T1X64(), NTATAG_SIP_T1(), NTATAG_SIP_T2(), NTATAG_SIP_T4(),
+ * NTATAG_STATELESS(),
+ * NTATAG_TAG_3261(), NTATAG_TCP_RPORT(), NTATAG_TIMEOUT_408(),
+ * NTATAG_TIMER_C(),
+ * NTATAG_UA(), NTATAG_UDP_MTU(), NTATAG_USER_VIA(),
+ * NTATAG_USE_NAPTR(), NTATAG_USE_SRV() and NTATAG_USE_TIMESTAMP().
+ *
+ * @note The value from following tags are stored, but they currently do nothing:
+ * NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_OPTIONS(), NTATAG_SMIME()
*/
int nta_agent_set_params(nta_agent_t *agent,
tag_type_t tag, tag_value_t value, ...)
@@ -875,7 +917,7 @@
static
int agent_set_params(nta_agent_t *agent, tagi_t *tags)
{
- int n, m;
+ int n, nC, m;
unsigned bad_req_mask = agent->sa_bad_req_mask;
unsigned bad_resp_mask = agent->sa_bad_resp_mask;
usize_t maxsize = agent->sa_maxsize;
@@ -885,6 +927,7 @@
unsigned sip_t2 = agent->sa_t2;
unsigned sip_t4 = agent->sa_t4;
unsigned sip_t1x64 = agent->sa_t1x64;
+ unsigned timer_c = agent->sa_timer_c;
unsigned blacklist = agent->sa_blacklist;
int ua = agent->sa_is_a_uas;
unsigned progress = agent->sa_progress;
@@ -919,50 +962,54 @@
su_home_t *home = agent->sa_home;
n = tl_gets(tags,
- NTATAG_MCLASS_REF(mclass),
+ NTATAG_ALIASES_REF(aliases),
NTATAG_BAD_REQ_MASK_REF(bad_req_mask),
NTATAG_BAD_RESP_MASK_REF(bad_resp_mask),
- NTATAG_ALIASES_REF(aliases),
- NTATAG_UA_REF(ua),
- NTATAG_STATELESS_REF(stateless),
- NTATAG_MAXSIZE_REF(maxsize),
- NTATAG_MAX_FORWARDS_REF(max_forwards),
- NTATAG_UDP_MTU_REF(udp_mtu),
- NTATAG_SIP_T1_REF(sip_t1),
- NTATAG_SIP_T2_REF(sip_t2),
- NTATAG_SIP_T4_REF(sip_t4),
- NTATAG_SIP_T1X64_REF(sip_t1x64),
- NTATAG_PROGRESS_REF(progress),
NTATAG_BLACKLIST_REF(blacklist),
+ NTATAG_CANCEL_2543_REF(cancel_2543),
+ NTATAG_CANCEL_487_REF(cancel_487),
NTATAG_DEBUG_DROP_PROB_REF(drop_prob),
- NTATAG_USER_VIA_REF(user_via),
+ NTATAG_DEFAULT_PROXY_REF(proxy),
NTATAG_EXTRA_100_REF(extra_100),
+ NTATAG_MAXSIZE_REF(maxsize),
+ NTATAG_MAX_FORWARDS_REF(max_forwards),
+ NTATAG_MCLASS_REF(mclass),
+ NTATAG_MERGE_482_REF(merge_482),
NTATAG_PASS_100_REF(pass_100),
- NTATAG_TIMEOUT_408_REF(timeout_408),
NTATAG_PASS_408_REF(pass_408),
- NTATAG_MERGE_482_REF(merge_482),
- NTATAG_DEFAULT_PROXY_REF(proxy),
- NTATAG_CANCEL_2543_REF(cancel_2543),
- NTATAG_CANCEL_487_REF(cancel_487),
+ NTATAG_PRELOAD_REF(preload),
+ NTATAG_PROGRESS_REF(progress),
NTATAG_REL100_REF(invite_100rel),
- NTATAG_USE_TIMESTAMP_REF(use_timestamp),
- NTATAG_USE_NAPTR_REF(use_naptr),
- NTATAG_USE_SRV_REF(use_srv),
+ NTATAG_RPORT_REF(rport),
+ NTATAG_SERVER_RPORT_REF(server_rport),
+ NTATAG_SIGCOMP_ALGORITHM_REF(algorithm),
+ NTATAG_SIGCOMP_OPTIONS_REF(sigcomp),
+ NTATAG_SIPFLAGS_REF(flags),
+ NTATAG_SIP_T1X64_REF(sip_t1x64),
+ NTATAG_SIP_T1_REF(sip_t1),
+ NTATAG_SIP_T2_REF(sip_t2),
+ NTATAG_SIP_T4_REF(sip_t4),
#if HAVE_SOFIA_SMIME
NTATAG_SMIME_REF(smime),
#endif
- NTATAG_SIPFLAGS_REF(flags),
- NTATAG_RPORT_REF(rport),
- NTATAG_SERVER_RPORT_REF(server_rport),
+ NTATAG_STATELESS_REF(stateless),
NTATAG_TCP_RPORT_REF(tcp_rport),
- NTATAG_PRELOAD_REF(preload),
+ NTATAG_TIMEOUT_408_REF(timeout_408),
+ NTATAG_UA_REF(ua),
+ NTATAG_UDP_MTU_REF(udp_mtu),
+ NTATAG_USER_VIA_REF(user_via),
+ NTATAG_USE_NAPTR_REF(use_naptr),
+ NTATAG_USE_SRV_REF(use_srv),
+ NTATAG_USE_TIMESTAMP_REF(use_timestamp),
#ifdef TPTAG_THRPSIZE
/* If threadpool is enabled, start a separate "reaper thread" */
TPTAG_THRPSIZE_REF(threadpool),
#endif
- NTATAG_SIGCOMP_OPTIONS_REF(sigcomp),
- NTATAG_SIGCOMP_ALGORITHM_REF(algorithm),
TAG_END());
+ nC = tl_gets(tags,
+ NTATAG_TIMER_C_REF(timer_c),
+ TAG_END());
+ n += nC;
if (mclass != NONE)
agent->sa_mclass = mclass ? mclass : sip_default_mclass();
@@ -972,7 +1019,7 @@
m = tport_set_params(tport, TAG_NEXT(tags));
}
- if (n == 0 || m == -1)
+ if (m == -1)
return m;
n += m;
@@ -1065,6 +1112,14 @@
outgoing_queue_adjust(agent, agent->sa_out.inv_calling, sip_t1x64);
}
agent->sa_t1x64 = sip_t1x64;
+ if (nC == 1) {
+ agent->sa_use_timer_c = 1;
+ if (timer_c == 0)
+ timer_c = 185 * 1000;
+ agent->sa_timer_c = timer_c;
+ outgoing_queue_adjust(agent, agent->sa_out.inv_proceeding, timer_c);
+ }
+
agent->sa_blacklist = blacklist;
if (progress == 0)
@@ -1123,16 +1178,25 @@
* INVITE transactions, or how the @Via headers are generated.
*
* @TAGS
- * NTATAG_ALIASES_REF(), NTATAG_CANCEL_2543_REF(), NTATAG_CANCEL_487_REF(),
- * NTATAG_CONTACT_REF(), NTATAG_DEBUG_DROP_PROB_REF(),
- * NTATAG_DEFAULT_PROXY_REF(), NTATAG_EXTRA_100_REF(), NTATAG_MAXSIZE_REF(),
- * NTATAG_MAX_FORWARDS_REF(),
- * NTATAG_MERGE_482_REF(), NTATAG_PASS_100_REF(), NTATAG_PRELOAD_REF(),
- * NTATAG_REL100_REF(), NTATAG_RPORT_REF(), NTATAG_SIPFLAGS_REF(),
- * NTATAG_SIP_T1X64_REF(), NTATAG_SIP_T1_REF(), NTATAG_SIP_T2_REF(),
+ * NTATAG_ALIASES_REF(), NTATAG_BLACKLIST_REF(),
+ * NTATAG_CANCEL_2543_REF(), NTATAG_CANCEL_487_REF(),
+ * NTATAG_CLIENT_RPORT_REF(), NTATAG_CONTACT_REF(),
+ * NTATAG_DEBUG_DROP_PROB_REF(), NTATAG_DEFAULT_PROXY_REF(),
+ * NTATAG_EXTRA_100_REF(),
+ * NTATAG_MAXSIZE_REF(), NTATAG_MAX_FORWARDS_REF(), NTATAG_MCLASS_REF(),
+ * NTATAG_MERGE_482_REF(),
+ * NTATAG_PASS_100_REF(), NTATAG_PASS_408_REF(), NTATAG_PRELOAD_REF(),
+ * NTATAG_PROGRESS_REF(),
+ * NTATAG_REL100_REF(),
+ * NTATAG_SERVER_RPORT_REF(),
+ * NTATAG_SIGCOMP_ALGORITHM_REF(), NTATAG_SIGCOMP_OPTIONS_REF(),
+ * NTATAG_SIPFLAGS_REF(),
+ * NTATAG_SIP_T1_REF(), NTATAG_SIP_T1X64_REF(), NTATAG_SIP_T2_REF(),
* NTATAG_SIP_T4_REF(), NTATAG_SMIME_REF(), NTATAG_STATELESS_REF(),
- * NTATAG_TAG_3261_REF(), NTATAG_TIMEOUT_408_REF(), NTATAG_PASS_408_REF(),
- * NTATAG_UA_REF(), NTATAG_USER_VIA_REF(), and NTATAG_USE_TIMESTAMP_REF().
+ * NTATAG_TAG_3261_REF(), NTATAG_TIMEOUT_408_REF(), NTATAG_TIMER_C_REF(),
+ * NTATAG_UA_REF(), NTATAG_UDP_MTU_REF(), NTATAG_USER_VIA_REF(),
+ * NTATAG_USE_NAPTR_REF(), NTATAG_USE_SRV_REF(),
+ * and NTATAG_USE_TIMESTAMP_REF().
*
*/
int nta_agent_get_params(nta_agent_t *agent,
@@ -1145,12 +1209,11 @@
ta_start(ta, tag, value);
n = agent_get_params(agent, ta_args(ta));
ta_end(ta);
- } else {
- su_seterrno(EINVAL);
- n = -1;
+ return n;
}
- return n;
+ su_seterrno(EINVAL);
+ return -1;
}
/** Get NTA parameters */
@@ -1159,46 +1222,49 @@
{
return
tl_tgets(tags,
- NTATAG_MCLASS(agent->sa_mclass),
- NTATAG_CONTACT(agent->sa_contact),
NTATAG_ALIASES(agent->sa_aliases),
- NTATAG_UA(agent->sa_is_a_uas),
- NTATAG_STATELESS(agent->sa_is_stateless),
- NTATAG_MAXSIZE(agent->sa_maxsize),
- NTATAG_MAX_FORWARDS(agent->sa_max_forwards->mf_count),
- NTATAG_UDP_MTU(agent->sa_udp_mtu),
- NTATAG_SIP_T1(agent->sa_t1),
- NTATAG_SIP_T2(agent->sa_t2),
- NTATAG_SIP_T4(agent->sa_t4),
- NTATAG_SIP_T1X64(agent->sa_t1x64),
NTATAG_BLACKLIST(agent->sa_blacklist),
+ NTATAG_CANCEL_2543(agent->sa_cancel_2543),
+ NTATAG_CANCEL_487(agent->sa_cancel_487),
+ NTATAG_CLIENT_RPORT(agent->sa_rport),
+ NTATAG_CONTACT(agent->sa_contact),
NTATAG_DEBUG_DROP_PROB(agent->sa_drop_prob),
- NTATAG_USER_VIA(agent->sa_user_via),
+ NTATAG_DEFAULT_PROXY(agent->sa_default_proxy),
NTATAG_EXTRA_100(agent->sa_extra_100),
+ NTATAG_MAXSIZE(agent->sa_maxsize),
+ NTATAG_MAX_FORWARDS(agent->sa_max_forwards->mf_count),
+ NTATAG_MCLASS(agent->sa_mclass),
+ NTATAG_MERGE_482(agent->sa_merge_482),
NTATAG_PASS_100(agent->sa_pass_100),
- NTATAG_TIMEOUT_408(agent->sa_timeout_408),
NTATAG_PASS_408(agent->sa_pass_408),
- NTATAG_MERGE_482(agent->sa_merge_482),
- NTATAG_DEFAULT_PROXY(agent->sa_default_proxy),
- NTATAG_CANCEL_2543(agent->sa_cancel_2543),
- NTATAG_CANCEL_487(agent->sa_cancel_487),
- NTATAG_TAG_3261(1),
+ NTATAG_PRELOAD(agent->sa_preload),
+ NTATAG_PROGRESS(agent->sa_progress),
NTATAG_REL100(agent->sa_invite_100rel),
- NTATAG_USE_TIMESTAMP(agent->sa_timestamp),
- NTATAG_USE_NAPTR(agent->sa_use_naptr),
- NTATAG_USE_SRV(agent->sa_use_srv),
+ NTATAG_SERVER_RPORT(agent->sa_server_rport),
+ NTATAG_SIGCOMP_ALGORITHM(agent->sa_algorithm),
+ NTATAG_SIGCOMP_OPTIONS(agent->sa_sigcomp_options ?
+ agent->sa_sigcomp_options :
+ "sip"),
+ NTATAG_SIPFLAGS(agent->sa_flags),
+ NTATAG_SIP_T1(agent->sa_t1),
+ NTATAG_SIP_T1X64(agent->sa_t1x64),
+ NTATAG_SIP_T2(agent->sa_t2),
+ NTATAG_SIP_T4(agent->sa_t4),
#if HAVE_SOFIA_SMIME
NTATAG_SMIME(agent->sa_smime),
#else
NTATAG_SMIME(NULL),
#endif
- NTATAG_SIPFLAGS(agent->sa_flags),
- NTATAG_RPORT(agent->sa_rport),
- NTATAG_PRELOAD(agent->sa_preload),
- NTATAG_SIGCOMP_ALGORITHM(agent->sa_algorithm),
- NTATAG_SIGCOMP_OPTIONS(agent->sa_sigcomp_options ?
- agent->sa_sigcomp_options :
- "sip"),
+ NTATAG_STATELESS(agent->sa_is_stateless),
+ NTATAG_TAG_3261(1),
+ NTATAG_TIMEOUT_408(agent->sa_timeout_408),
+ NTATAG_TIMER_C(agent->sa_timer_c),
+ NTATAG_UA(agent->sa_is_a_uas),
+ NTATAG_UDP_MTU(agent->sa_udp_mtu),
+ NTATAG_USER_VIA(agent->sa_user_via),
+ NTATAG_USE_NAPTR(agent->sa_use_naptr),
+ NTATAG_USE_SRV(agent->sa_use_srv),
+ NTATAG_USE_TIMESTAMP(agent->sa_timestamp),
TAG_END());
}
@@ -1207,8 +1273,38 @@
* The nta_agent_get_stats() function retrieves the stack statistics.
*
* @TAGS
- * @TAG NTATAG_S_*
- *
+ * NTATAG_S_ACKED_TR_REF(),
+ * NTATAG_S_BAD_MESSAGE_REF(),
+ * NTATAG_S_BAD_REQUEST_REF(),
+ * NTATAG_S_BAD_RESPONSE_REF(),
+ * NTATAG_S_CANCELED_TR_REF(),
+ * NTATAG_S_CLIENT_TR_REF(),
+ * NTATAG_S_DIALOG_TR_REF(),
+ * NTATAG_S_DROP_REQUEST_REF(),
+ * NTATAG_S_DROP_RESPONSE_REF(),
+ * NTATAG_S_IRQ_HASH_REF(),
+ * NTATAG_S_IRQ_HASH_USED_REF(),
+ * NTATAG_S_LEG_HASH_REF(),
+ * NTATAG_S_LEG_HASH_USED_REF(),
+ * NTATAG_S_MERGED_REQUEST_REF(),
+ * NTATAG_S_ORQ_HASH_REF(),
+ * NTATAG_S_ORQ_HASH_USED_REF(),
+ * NTATAG_S_RECV_MSG_REF(),
+ * NTATAG_S_RECV_REQUEST_REF(),
+ * NTATAG_S_RECV_RESPONSE_REF(),
+ * NTATAG_S_RECV_RETRY_REF(),
+ * NTATAG_S_RETRY_REQUEST_REF(),
+ * NTATAG_S_RETRY_RESPONSE_REF(),
+ * NTATAG_S_SENT_MSG_REF(),
+ * NTATAG_S_SENT_REQUEST_REF(),
+ * NTATAG_S_SENT_RESPONSE_REF(),
+ * NTATAG_S_SERVER_TR_REF(),
+ * NTATAG_S_TOUT_REQUEST_REF(),
+ * NTATAG_S_TOUT_RESPONSE_REF(),
+ * NTATAG_S_TRLESS_200_REF(),
+ * NTATAG_S_TRLESS_REQUEST_REF(),
+ * NTATAG_S_TRLESS_RESPONSE_REF(), and
+ * NTATAG_S_TRLESS_TO_TR_REF(),
*/
int nta_agent_get_stats(nta_agent_t *agent,
tag_type_t tag, tag_value_t value, ...)
@@ -1622,7 +1718,6 @@
tport_tcreate(self, nta_agent_class, self->sa_root,
TPTAG_SDWN_ERROR(0),
TPTAG_IDLE(1800000),
- TPTAG_DEBUG_DROP(self->sa_drop_prob),
TAG_NEXT(tags));
if (!self->sa_tports)
@@ -2119,6 +2214,16 @@
URL_PRINT_ARGS(sip->sip_request->rq_url),
sip->sip_request->rq_version, cseq));
+ if (agent->sa_drop_prob && !tport_is_reliable(tport)) {
+ if ((unsigned)su_randint(0, 1000) < agent->sa_drop_prob) {
+ SU_DEBUG_5(("nta: %s (%u) is %s\n",
+ method_name, cseq, "dropped simulating packet loss"));
+ agent->sa_stats->as_drop_request++;
+ msg_destroy(msg);
+ return;
+ }
+ }
+
stream = tport_is_stream(tport);
/* Try to use compression on reverse direction if @Via has comp=sigcomp */
@@ -2304,8 +2409,9 @@
}
else {
agent->sa_stats->as_trless_request++;
- SU_DEBUG_5(("nta: %s (%u) no place to go: %d %s\n",
- method_name, cseq, SIP_501_NOT_IMPLEMENTED));
+ SU_DEBUG_5(("nta: %s (%u) %s\n",
+ method_name, cseq,
+ "not processed by application: returning 501"));
if (method != sip_method_ack)
nta_msg_treply(agent, msg, SIP_501_NOT_IMPLEMENTED,
NTATAG_TPORT(tport),
@@ -2493,6 +2599,16 @@
SU_DEBUG_5(("nta: received %03d %s for %s (%u)\n",
status, phrase, method, cseq));
+ if (agent->sa_drop_prob && !tport_is_reliable(tport)) {
+ if ((unsigned)su_randint(0, 1000) < agent->sa_drop_prob) {
+ SU_DEBUG_5(("nta: %03d %s %s\n",
+ status, phrase, "dropped simulating packet loss"));
+ agent->sa_stats->as_drop_response++;
+ msg_destroy(msg);
+ return;
+ }
+ }
+
if (agent->sa_bad_resp_mask)
errors = msg_extract_errors(msg) & agent->sa_bad_resp_mask;
else
@@ -2505,7 +2621,10 @@
agent->sa_stats->as_bad_response++;
agent->sa_stats->as_bad_message++;
- SU_DEBUG_5(("nta: %03d %s failed sanity check\n", status, phrase));
+ SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase,
+ errors
+ ? "has fatal syntax errors"
+ : "failed sanity check"));
for (h = (sip_header_t const *)sip->sip_error; h; h = h->sh_next) {
if (h->sh_class->hc_name) {
@@ -2532,7 +2651,7 @@
/* Drop response messages to ACK */
agent->sa_stats->as_bad_response++;
agent->sa_stats->as_bad_message++;
- SU_DEBUG_5(("nta: %03d %s is response to ACK\n", status, phrase));
+ SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "is response to ACK"));
msg_destroy(msg);
return;
}
@@ -2540,7 +2659,8 @@
/* XXX - should check if msg should be discarded based on via? */
if ((orq = outgoing_find(agent, msg, sip, sip->sip_via))) {
- SU_DEBUG_5(("nta: %03d %s going to a transaction\n", status, phrase));
+ SU_DEBUG_5(("nta: %03d %s %s\n",
+ status, phrase, "is going to a transaction"));
if (outgoing_recv(orq, status, msg, sip) == 0)
return;
}
@@ -2548,12 +2668,13 @@
agent->sa_stats->as_trless_response++;
if ((orq = agent->sa_default_outgoing)) {
- SU_DEBUG_5(("nta: %03d %s to the default transaction\n", status, phrase));
+ SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase,
+ "to the default transaction"));
outgoing_default_recv(orq, status, msg, sip);
return;
}
else if (agent->sa_callback) {
- SU_DEBUG_5(("nta: %03d %s to message callback\n", status, phrase));
+ SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "to message callback"));
/*
* Store message and transport to hook for the duration of the callback
* so that the transport can be obtained by nta_transport().
@@ -2569,13 +2690,15 @@
&& sip->sip_via && !sip->sip_via->v_next
&& agent_has_via(agent, sip->sip_via)) {
agent->sa_stats->as_trless_200++;
- /* Orphan 200 Ok to INVITE. ACK and BYE it */
- SU_DEBUG_5(("nta: %03d %s must be ACK&BYE\n", status, phrase));
- if (nta_msg_ackbye(agent, msg) != -1)
- return;
+ if (agent->sa_is_a_uas) {
+ /* Orphan 200 Ok to INVITE. ACK and BYE it */
+ SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "is ACK&BYE"));
+ if (nta_msg_ackbye(agent, msg) != -1)
+ return;
+ }
}
- SU_DEBUG_5(("nta: %03d %s was discarded\n", status, phrase));
+ SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "was discarded"));
msg_destroy(msg);
}
@@ -2817,6 +2940,7 @@
NTATAG_TPORT_REF(tport),
NTATAG_INCOMPLETE_REF(incomplete),
TPTAG_COMPARTMENT_REF(cc),
+ /* XXX - should also check ntatag_sigcomp_close() */
TAG_END());
if (reply == NULL) {
@@ -3340,6 +3464,7 @@
nta_leg_t *leg;
su_home_t *home;
url_t *url;
+ char const *what = NULL;
if (agent == NULL)
return su_seterrno(EINVAL), NULL;
@@ -3423,32 +3548,35 @@
leg->leg_url = url;
if (from && from != NONE && leg->leg_local == NULL) {
- SU_DEBUG_3(("nta_leg_tcreate(): cannot duplicate local address\n"));
+ what = "cannot duplicate local address";
goto err;
}
else if (to && to != NONE && leg->leg_remote == NULL) {
- SU_DEBUG_3(("nta_leg_tcreate(): cannot duplicate remote address\n"));
+ what = "cannot duplicate remote address";
goto err;
}
else if (route && route != NONE && leg->leg_route == NULL) {
- SU_DEBUG_3(("nta_leg_tcreate(): cannot duplicate route\n"));
+ what = "cannot duplicate route";
goto err;
}
else if (contact && contact != NONE && leg->leg_target == NULL) {
- SU_DEBUG_3(("nta_leg_tcreate(): cannot duplicate target\n"));
+ what = "cannot duplicate target";
goto err;
}
else if (url_string && leg->leg_url == NULL) {
- SU_DEBUG_3(("nta_leg_tcreate(): cannot duplicate local destination\n"));
+ what = "cannot duplicate local destination";
goto err;
}
if (!no_dialog) {
if (!leg->leg_local || !leg->leg_remote) {
/* To and/or From header missing */
- SU_DEBUG_3(("nta_leg_tcreate(): missing%s%s header\n",
- !leg->leg_remote ? " To" : "",
- !leg->leg_local ? " From" : ""));
+ if (leg->leg_remote)
+ what = "Missing local dialog address";
+ else if (leg->leg_local)
+ what = "Missing remote dialog address";
+ else
+ what = "Missing dialog addresses";
goto err;
}
@@ -3462,7 +3590,7 @@
leg->leg_id = sip_call_id_create(home, NULL);
if (!leg->leg_id) {
- SU_DEBUG_3(("nta_leg_tcreate(): cannot create Call-ID\n"));
+ what = "cannot create Call-ID";
goto err;
}
@@ -3498,7 +3626,7 @@
else {
/* This is "default leg" without a destination URL. */
if (agent->sa_default_leg) {
- SU_DEBUG_1(("leg_create(): tried to create second default leg\n"));
+ SU_DEBUG_1(("%s(): %s\n", "nta_leg_tcreate", "tried to create second default leg"));
su_seterrno(EEXIST);
goto err;
}
@@ -3515,11 +3643,14 @@
leg_insert(agent, leg);
- SU_DEBUG_9(("nta_leg_create(%p)\n", (void *)leg));
+ SU_DEBUG_9(("%s(%p)\n", "nta_leg_tcreate", (void *)leg));
return leg;
err:
+ if (what)
+ SU_DEBUG_9(("%s(): %s\n", "nta_leg_tcreate", what));
+
su_home_zap(leg->leg_home);
return NULL;
@@ -4478,7 +4609,7 @@
}
else {
queue = agent->sa_in.proceeding;
- /* draft-sparks-sip-nit-actions-03:
+ /* RFC 4320 (nit-actions-03):
Blacklisting on a late response occurs even over reliable transports.
Thus, if an element processing a request received over a reliable
@@ -5661,7 +5792,7 @@
irq->irq_method != sip_method_invite &&
!agent->sa_pass_408 &&
!irq->irq_default) {
- /* draft-sparks-sip-nit-actions-03 Action 2:
+ /* RFC 4320 nit-actions-03 Action 2:
A transaction-stateful SIP element MUST NOT send a response with
Status-Code of 408 to a non-INVITE request. As a consequence, an
@@ -6199,6 +6330,9 @@
static size_t outgoing_timer_bf(outgoing_queue_t *q,
char const *timer,
su_duration_t now);
+static size_t outgoing_timer_c(outgoing_queue_t *q,
+ char const *timer,
+ su_duration_t now);
static void outgoing_ack(nta_outgoing_t *orq, msg_t *msg, sip_t *sip);
static msg_t *outgoing_ackmsg(nta_outgoing_t *, sip_method_t, char const *,
@@ -6303,7 +6437,7 @@
* NTATAG_STATELESS(), NTATAG_DELAY_SENDING(), NTATAG_BRANCH_KEY(),
* NTATAG_ACK_BRANCH(), NTATAG_DEFAULT_PROXY(), NTATAG_PASS_100(),
* NTATAG_USE_TIMESTAMP(), NTATAG_USER_VIA(), TPTAG_IDENT(), NTATAG_TPORT(). All
- * SIP tags from <sip_tag.h> can be used to manipulate the request message.
+ * SIP tags from <sofia-sip/sip_tag.h> can be used to manipulate the request message.
* SIP tags after SIPTAG_END() are ignored, however.
*/
nta_outgoing_t *nta_outgoing_tcreate(nta_leg_t *leg,
@@ -6385,13 +6519,13 @@
* transaction is freed before returning from the function.
*
* @sa
- * nta_outgoing_tcreate(), nnta_outgoing_tcancel(), nta_outgoing_destroy().
+ * nta_outgoing_tcreate(), nta_outgoing_tcancel(), nta_outgoing_destroy().
*
* @TAGS
* NTATAG_STATELESS(), NTATAG_DELAY_SENDING(), NTATAG_BRANCH_KEY(),
* NTATAG_ACK_BRANCH(), NTATAG_DEFAULT_PROXY(), NTATAG_PASS_100(),
* NTATAG_USE_TIMESTAMP(), NTATAG_USER_VIA(), TPTAG_IDENT(), NTATAG_TPORT(). All
- * SIP tags from <sip_tag.h> can be used to manipulate the request message.
+ * SIP tags from <sofia-sip/sip_tag.h> can be used to manipulate the request message.
* SIP tags after SIPTAG_END() are ignored, however.
*/
nta_outgoing_t *nta_outgoing_mcreate(nta_agent_t *agent,
@@ -6611,7 +6745,7 @@
return orq != NULL && orq != NONE ? orq->orq_delay : UINT_MAX;
}
-/** Get the branch parameter. */
+/** Get the branch parameter. @NEW_1_12_7 */
char const *nta_outgoing_branch(nta_outgoing_t const *orq)
{
return orq != NULL && orq != NONE && orq->orq_branch
@@ -6713,6 +6847,8 @@
char const *scheme = NULL;
char const *port = NULL;
int invalid, resolved, stateless = 0, user_via = agent->sa_user_via;
+ int invite_100rel = agent->sa_invite_100rel;
+
tagi_t const *t;
tport_t const *override_tport = NULL;
@@ -6777,6 +6913,9 @@
else if (ntatag_tport == tt) {
override_tport = (tport_t *)t->t_value;
}
+ else if (ntatag_rel100 == tt) {
+ invite_100rel = t->t_value != 0;
+ }
}
orq->orq_agent = agent;
@@ -6798,6 +6937,8 @@
orq->orq_delay = UINT_MAX;
orq->orq_stateless = stateless != 0;
orq->orq_user_via = user_via != 0 && sip->sip_via;
+ orq->orq_100rel = invite_100rel;
+
if (cc)
orq->orq_cc = nta_compartment_ref(cc);
@@ -7332,17 +7473,18 @@
supported[i = 0] = NULL;
if (orq->orq_method == sip_method_invite) {
- int add_100rel = agent->sa_invite_100rel;
int require_100rel = sip_has_feature(sip->sip_require, "100rel");
- tl_gets(tags,
- NTATAG_REL100_REF(add_100rel),
- TAG_END());
- if (add_100rel && !require_100rel &&
- !sip_has_feature(sip->sip_supported, "100rel"))
- supported[i++] = "100rel";
-
- orq->orq_must_100rel = require_100rel;
+ if (require_100rel) {
+ orq->orq_must_100rel = 1;
+ orq->orq_100rel = 1;
+ }
+ else if (sip_has_feature(sip->sip_supported, "100rel")) {
+ orq->orq_100rel = 1;
+ }
+ else if (orq->orq_100rel) {
+ supported[i++] = "100rel";
+ }
}
if (i) {
@@ -7404,7 +7546,8 @@
latest = set_timeout(sa, queue->q_timeout = timeout);
for (orq = queue->q_head; orq; orq = orq->orq_next) {
- if (orq->orq_timeout - latest > 0)
+ if (orq->orq_timeout == 0 ||
+ orq->orq_timeout - latest > 0)
orq->orq_timeout = latest;
}
}
@@ -7659,6 +7802,7 @@
sa->sa_out.inv_calling->q_length;
size_t completed = sa->sa_out.completed->q_length +
sa->sa_out.inv_completed->q_length;
+ outgoing_queue_t *proceeding = sa->sa_out.inv_proceeding;
outgoing_queue_init(sa->sa_out.free = rq, 0);
@@ -7712,9 +7856,12 @@
timeout
= outgoing_timer_bf(sa->sa_out.inv_calling, "B", now)
+ + outgoing_timer_c(proceeding, "C", now)
+ outgoing_timer_bf(sa->sa_out.trying, "F", now);
next = NEXT_TIMEOUT(next, sa->sa_out.inv_calling->q_head, orq_timeout, now);
+ if (proceeding->q_timeout)
+ next = NEXT_TIMEOUT(next, proceeding->q_head, orq_timeout, now);
next = NEXT_TIMEOUT(next, sa->sa_out.trying->q_head, orq_timeout, now);
destroyed = outgoing_mass_destroy(sa, rq);
@@ -7791,6 +7938,38 @@
return timeout;
}
+/** Handle timer C */
+static
+size_t outgoing_timer_c(outgoing_queue_t *q,
+ char const *timer,
+ su_duration_t now)
+{
+ nta_outgoing_t *orq;
+ size_t timeout = 0;
+
+ if (q->q_timeout == 0)
+ return 0;
+
+ while ((orq = q->q_head)) {
+ if (orq->orq_timeout - now > 0 || timeout >= timer_max_timeout)
+ break;
+
+ timeout++;
+
+ SU_DEBUG_5(("nta: timer %s fired, %s %s (%u)\n",
+ timer, "CANCEL and timeout",
+ orq->orq_method_name, orq->orq_cseq->cs_seq));
+
+ nta_outgoing_tcancel(orq, NULL, NULL, TAG_NULL());
+
+ outgoing_timeout(orq, now);
+
+ assert(q->q_head != orq);
+ }
+
+ return timeout;
+}
+
/** @internal Signal transaction timeout to the application. */
void outgoing_timeout(nta_outgoing_t *orq, su_duration_t now)
{
@@ -8074,6 +8253,13 @@
orq->orq_status = status;
outgoing_queue(sa->sa_out.inv_proceeding, orq);
}
+ else if (orq->orq_queue == sa->sa_out.inv_proceeding) {
+ orq->orq_status = status;
+ if (sa->sa_out.inv_proceeding->q_timeout) {
+ outgoing_remove(orq);
+ outgoing_queue(sa->sa_out.inv_proceeding, orq);
+ }
+ }
/* Handle 100rel */
if (sip && sip->sip_rseq)
@@ -8092,6 +8278,10 @@
return 0;
if (sip && sa->sa_is_a_uas) {
+ /*
+ * We silently discard duplicate final responses to INVITE below
+ * with outgoing_duplicate()
+ */
su_home_t *home = msg_home(orq->orq_request);
orq->orq_tag = su_strdup(home, sip->sip_to->a_tag);
}
@@ -8119,6 +8309,10 @@
assert(orq_status < 200); (void)orq_status;
if (status < 200) {
+ /* @RFC3261 17.1.2.1:
+ * retransmissions continue for unreliable transports,
+ * but at an interval of T2
+ */
if (!orq->orq_reliable)
outgoing_set_timer(orq, sa->sa_t2);
}
@@ -8324,6 +8518,33 @@
if (!sip)
return NULL;
+ if (tags) {
+ sip_add_tl(msg, sip, TAG_NEXT(tags));
+ /* Bug sf.net # 173323:
+ * Ensure that request-URI, topmost Via, From, To, Call-ID, CSeq,
+ * Max-Forward, Route, Accept-Contact, Reject-Contact and
+ * Request-Disposition are copied from original request
+ */
+ if (sip->sip_from)
+ sip_header_remove(msg, sip, (void *)sip->sip_from);
+ if (sip->sip_to)
+ sip_header_remove(msg, sip, (void *)sip->sip_to);
+ if (sip->sip_call_id)
+ sip_header_remove(msg, sip, (void *)sip->sip_call_id);
+ while (sip->sip_route)
+ sip_header_remove(msg, sip, (void *)sip->sip_route);
+ while (sip->sip_accept_contact)
+ sip_header_remove(msg, sip, (void *)sip->sip_accept_contact);
+ while (sip->sip_reject_contact)
+ sip_header_remove(msg, sip, (void *)sip->sip_reject_contact);
+ if (sip->sip_request_disposition)
+ sip_header_remove(msg, sip, (void *)sip->sip_request_disposition);
+ while (sip->sip_via)
+ sip_header_remove(msg, sip, (void *)sip->sip_via);
+ if (sip->sip_max_forwards)
+ sip_header_remove(msg, sip, (void *)sip->sip_max_forwards);
+ }
+
sip->sip_request =
sip_request_create(home, m, mname, (url_string_t *)orq->orq_url, NULL);
@@ -8335,6 +8556,7 @@
sip_add_dup(msg, sip, (sip_header_t *)old->sip_accept_contact);
sip_add_dup(msg, sip, (sip_header_t *)old->sip_reject_contact);
sip_add_dup(msg, sip, (sip_header_t *)old->sip_request_disposition);
+ sip_add_dup(msg, sip, (sip_header_t *)old->sip_max_forwards);
if (old->sip_via) {
/* Add only the topmost Via header */
@@ -8344,12 +8566,6 @@
sip->sip_cseq = sip_cseq_create(home, old->sip_cseq->cs_seq, m, mname);
- if (tags)
- sip_add_tl(msg, sip, TAG_NEXT(tags));
-
- if (!sip->sip_max_forwards)
- sip_add_dup(msg, sip, (sip_header_t *)orq->orq_agent->sa_max_forwards);
-
if (sip->sip_request &&
sip->sip_to &&
sip->sip_from &&
@@ -8418,7 +8634,9 @@
/* Create response message, if needed */
if (!orq->orq_stateless &&
!(orq->orq_callback == outgoing_default_cb) &&
- !(status == 408 && !orq->orq_agent->sa_timeout_408)) {
+ !(status == 408 &&
+ orq->orq_method != sip_method_invite &&
+ !orq->orq_agent->sa_timeout_408)) {
char const *to_tag;
msg = nta_msg_create(agent, NTA_INTERNAL_MSG);
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta.docs Mon Aug 20 13:37:13 2007
@@ -24,8 +24,9 @@
* (#nta_incoming_t).
*
* NTA also uses SIP message objects #msg_t and #sip_t for handling
- * messages, as defined in <msg.h> and <sip.h>, respectively. The various
- * SIP headers are also defined in <sip.h>.
+ * messages, as defined in <sofia-sip/msg.h> and <sofia-sip/sip.h>,
+ * respectively. The various SIP headers are also defined in
+ * <sofia-sip/sip.h>.
*
* @section nta_agent_t Creating an NTA Agent
*
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h Mon Aug 20 13:37:13 2007
@@ -160,10 +160,13 @@
/** Progress timer - interval between provisional responses sent */
unsigned sa_progress;
+ /** SIP timer C - interval between provisional responses receivedxs */
+ unsigned sa_timer_c;
+
/** Blacklisting period */
unsigned sa_blacklist;
- /** NTA is used to test packet drop */
+ /** NTA is used to test packet drop */
unsigned sa_drop_prob : 10;
/** NTA is acting as an User Agent server */
unsigned sa_is_a_uas : 1;
@@ -226,6 +229,9 @@
/** Set when executing timer */
unsigned sa_in_timer:1;
+
+ /** Set if application has set value for timer C */
+ unsigned sa_use_timer_c:1;
unsigned :0;
@@ -307,7 +313,7 @@
/* Special queues (states) for outgoing INVITE transactions */
outgoing_queue_t inv_calling[1]; /* Timer B/A */
- outgoing_queue_t inv_proceeding[1];
+ outgoing_queue_t inv_proceeding[1]; /* Timer C */
outgoing_queue_t inv_completed[1]; /* Timer D */
/* Temporary queue for transactions waiting to be freed */
@@ -517,6 +523,7 @@
unsigned orq_sigcomp_zap:1; /**< Reset SigComp after completing */
unsigned orq_must_100rel : 1;
unsigned orq_timestamp : 1; /**< Insert @Timestamp header. */
+ unsigned orq_100rel:1; /**< Support 100rel */
unsigned : 0; /* pad */
#if HAVE_SOFIA_SRESOLV
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/nta_tag.c Mon Aug 20 13:37:13 2007
@@ -76,6 +76,7 @@
tag_typedef_t ntatag_sip_t2 = UINTTAG_TYPEDEF(sip_t2);
tag_typedef_t ntatag_sip_t4 = UINTTAG_TYPEDEF(sip_t4);
tag_typedef_t ntatag_progress = UINTTAG_TYPEDEF(progress);
+tag_typedef_t ntatag_timer_c = UINTTAG_TYPEDEF(timer_c);
tag_typedef_t ntatag_blacklist = UINTTAG_TYPEDEF(blacklist);
tag_typedef_t ntatag_debug_drop_prob = UINTTAG_TYPEDEF(debug_drop_prob);
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta_tag.h Mon Aug 20 13:37:13 2007
@@ -58,7 +58,25 @@
/* Tags for parameters */
NTA_DLL extern tag_typedef_t ntatag_mclass;
-/** Message class used by NTA. @HI */
+/** Message class used by NTA.
+ *
+ * The nta can use a custom or extended parser created with
+ * msg_mclass_clone().
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * pointer to #msg_mclass_t.
+ *
+ * @par Values
+ * - custom or extended parser created with msg_mclass_clone()
+ * - NULL - use default parser
+ *
+ * @sa NTATAG_SIPFLAGS()
+ */
#define NTATAG_MCLASS(x) ntatag_mclass, tag_cptr_v((x))
NTA_DLL extern tag_typedef_t ntatag_mclass_ref;
@@ -68,9 +86,33 @@
/** Mask for bad request messages.
*
* If an incoming request has erroneous headers matching with the mask, nta
- * automatically returns a 400 Bad Message response to them. If no mask is
- * specified, all requests with any bad header are dropped.
+ * automatically returns a 400 Bad Message response to them.
+ *
+ * If mask ~0U (all bits set) is specified, all requests with any bad header
+ * are dropped. By default only the requests with bad headers essential for
+ * request processing or proxying are dropped.
*
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - bitwise or of enum #sip_bad_mask values
+ *
+ * @sa enum #sip_bad_mask, NTATAG_BAD_RESP_MASK()
+ *
+ * @note
+ * The following headers are considered essential by default:
+ * - @ref sip_request \"request line\"", @From, @To, @CSeq, @CallID,
+ * @ContentLength, @Via, @ContentType, @ContentDisposition,
+ * @ContentEncoding, @Supported, @Contact, @Require, @RecordRoute, @RAck,
+ * @RSeq, @Event, @Expires, @SubscriptionState, @SessionExpires,
+ * @MinSE, @SIPEtag, and @SIPIfMatch.
+ *
*/
#define NTATAG_BAD_REQ_MASK(x) ntatag_bad_req_mask, tag_uint_v((x))
@@ -81,8 +123,32 @@
/** Mask for bad response messages.
*
* If an incoming response has erroneous headers matching with the mask, nta
- * drops the response message. If no mask is specified, all responses with
- * any bad header are dropped.
+ * drops the response message.
+ *
+ * If mask ~0U (all bits set) is specified, all responses with any bad header
+ * are dropped. By default only the responses with bad headers essential for
+ * response processing or proxying are dropped.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - bitwise or of enum #sip_bad_mask values
+ *
+ * @sa enum #sip_bad_mask, NTATAG_BAD_REQ_MASK()
+ *
+ * @note
+ * The following headers are considered essential by default:
+ * - @ref sip_status \"status line\"", @From, @To, @CSeq, @CallID,
+ * @ContentLength, @Via, @ContentType, @ContentDisposition,
+ * @ContentEncoding, @Supported, @Contact, @Require, @RecordRoute, @RAck,
+ * @RSeq, @Event, @Expires, @SubscriptionState, @SessionExpires,
+ * @MinSE, @SIPEtag, and @SIPIfMatch.
*/
#define NTATAG_BAD_RESP_MASK(x) ntatag_bad_resp_mask, tag_uint_v((x))
@@ -90,18 +156,37 @@
#define NTATAG_BAD_RESP_MASK_REF(x) ntatag_bad_resp_mask_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_default_proxy;
-/** URL for (default) proxy. @HI */
-#define NTATAG_DEFAULT_PROXY(x) \
-ntatag_default_proxy, urltag_url_v((x))
+/** URL for (default) proxy.
+ *
+ * The requests are sent towards the <i>default outbound proxy</i> regardless
+ * the values of request-URI or @Route headers in the request. The URL of
+ * the default proxy is not added to the request in the @Route header or in
+ * the request-URI (against the recommendation of @RFC3261 section 8.1.2).
+ *
+ * The outbound proxy set by NTATAG_DEFAULT_PROXY() is used even if the
+ * dialog had an established route set or registration provided User-Agent
+ * with a @ServiceRoute set.
+ *
+ * @par Used with
+ * nua_create(), nta_agent_create(), nta_agent_set_params() \n
+ * nta_outgoing_mcreate(), nta_outgoing_tcreate(),
+ * nta_outgoing_tcancel(), nta_outgoing_prack(), nta_msg_tsend()
+ *
+ * @par Parameter type
+ * Pointer to a url_t structure or a string containg a SIP or SIPS URI
+ *
+ * @par Values
+ * - Valid SIP or SIPS URI
+ */
+#define NTATAG_DEFAULT_PROXY(x) ntatag_default_proxy, urltag_url_v((x))
NTA_DLL extern tag_typedef_t ntatag_default_proxy_ref;
#define NTATAG_DEFAULT_PROXY_REF(x) \
ntatag_default_proxy_ref, urltag_url_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_contact;
-/** Contact used by NTA. @HI */
-#define NTATAG_CONTACT(x) \
-ntatag_contact, siptag_contact_v((x))
+/** Contact used by NTA. */
+#define NTATAG_CONTACT(x) ntatag_contact, siptag_contact_v((x))
NTA_DLL extern tag_typedef_t ntatag_contact_ref;
#define NTATAG_CONTACT_REF(x) \
@@ -136,21 +221,42 @@
NTA_DLL extern tag_typedef_t ntatag_ack_branch;
/** Branch for ACKed transaction. @HI */
-#define NTATAG_ACK_BRANCH(x) \
-ntatag_ack_branch, tag_str_v((x))
+#define NTATAG_ACK_BRANCH(x) ntatag_ack_branch, tag_str_v((x))
NTA_DLL extern tag_typedef_t ntatag_ack_branch_ref;
-#define NTATAG_ACK_BRANCH_REF(x) \
-ntatag_ack_branch_ref, tag_str_vr(&(x))
+#define NTATAG_ACK_BRANCH_REF(x) ntatag_ack_branch_ref, tag_str_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_comp;
-/** Compression algorithm. @HI */
-#define NTATAG_COMP(x) \
-ntatag_comp, tag_str_v((x))
+/** Compression algorithm.
+ *
+ * Set compression algorithm for request as described in @RFC3486.
+ *
+ * @note This tag is has no effect without a compression plugin.
+ *
+ * @par Used with
+ * nta_outgoing_mcreate(), nta_outgoing_tcreate(),
+ * nta_outgoing_tcancel(), nta_outgoing_prack(), nta_msg_tsend()
+ *
+ * @par
+ * Note that NTATAG_COMP(NULL) can be used with nta_incoming_set_params()
+ * and nta_incoming_treply(), too. It indicates that the response is sent
+ * uncompressed, no matter what the client has in @a comp parameter of @Via
+ * header.
+ *
+ * @par Parameter type
+ * string
+ *
+ * @par Values
+ * - name of the compression algorithm ("sigcomp")
+ *
+ * @sa @RFC3320, @RFC3486, TPTAG_COMPARTMENT(),
+ * NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_AWARE(),
+ * NTATAG_SIGCOMP_CLOSE(), NTATAG_SIGCOMP_OPTIONS()
+ */
+#define NTATAG_COMP(x) ntatag_comp, tag_str_v((x))
NTA_DLL extern tag_typedef_t ntatag_comp_ref;
-#define NTATAG_COMP_REF(x) \
-ntatag_comp_ref, tag_str_vr(&(x))
+#define NTATAG_COMP_REF(x) ntatag_comp_ref, tag_str_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_msg;
/** Pass a SIP message to treply()/tcreate() functions. @HI */
@@ -181,14 +287,49 @@
#define NTATAG_SMIME_REF(x) ntatag_smime_ref, tag_ptr_vr(&(x), (x))
NTA_DLL extern tag_typedef_t ntatag_maxsize;
-/** Maximum size of incoming message. @HI */
+/** Maximum size of incoming message. @HI
+ *
+ * If the size of an incoming request message would exceed the
+ * given limit, the stack will automatically respond with <i>413 Request
+ * Entity Too Large</i>.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * usize_t
+ *
+ * @par Values
+ * - Maximum acceptable size of an incoming request message.
+ * Default value is 2 megabytes (2097152 bytes).
+ *
+ * @sa msg_maxsize()
+ */
#define NTATAG_MAXSIZE(x) ntatag_maxsize, tag_usize_v((x))
NTA_DLL extern tag_typedef_t ntatag_maxsize_ref;
#define NTATAG_MAXSIZE_REF(x) ntatag_maxsize_ref, tag_usize_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_udp_mtu;
-/** Maximum size of outgoing UDP request. @HI */
+/** Maximum size of outgoing UDP request. @HI
+ *
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ *
+ *
+ * @par Values
+ * -
+ *
+ * @sa
+ *
+ */
#define NTATAG_UDP_MTU(x) ntatag_udp_mtu, tag_usize_v((x))
NTA_DLL extern tag_typedef_t ntatag_udp_mtu_ref;
@@ -197,8 +338,22 @@
NTA_DLL extern tag_typedef_t ntatag_max_forwards;
/** Default value for @MaxForwards header.
*
+ * The default value of @MaxForwards header added to the requests. The
+ * initial value recommended by @RFC3261 is 70, but usually SIP proxies use
+ * much lower default value, such as 24.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned
+ *
+ * @par Values
+ * - Default value added to the @MaxForwards header in the sent requests
+ *
* @since New in @VERSION_1_12_2.
- * @hideinitializer
*/
#define NTATAG_MAX_FORWARDS(x) ntatag_max_forwards, tag_uint_v((x))
@@ -206,42 +361,194 @@
#define NTATAG_MAX_FORWARDS_REF(x) ntatag_max_forwards_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sip_t1;
-/** Initial retransmission interval (in milliseconds) @HI */
+/** Initial retransmission interval (in milliseconds) @HI
+ *
+ * Set the T1 retransmission interval used by the SIP transaction engine. The
+ * T1 is the initial duration used by request retransmission timers A and E
+ * (UDP) as well as response retransmission timer G.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - Value of SIP T1 in milliseconds
+ *
+ * @sa @RFC3261 appendix A, NTATAG_SIP_T1X4(), NTATAG_SIP_T1(), NTATAG_SIP_T4()
+ */
#define NTATAG_SIP_T1(x) ntatag_sip_t1, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_sip_t1_ref;
#define NTATAG_SIP_T1_REF(x) ntatag_sip_t1_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sip_t1x64;
-/** Transaction timeout (defaults to T1 * 64). @HI */
+/** Transaction timeout (defaults to T1 * 64). @HI
+ *
+ * Set the T1x64 timeout value used by the SIP transaction engine. The T1x64 is
+ * duration used for timers B, F, H, and J (UDP) by the SIP transaction engine.
+ * The timeout value T1x64 can be adjusted separately from the initial
+ * retransmission interval T1, which is set with NTATAG_SIP_T1().
+ *
+ * The default value for T1x64 is 64 times value of T1, or 32000 milliseconds.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - Value of T1x64 in milliseconds
+ *
+ * @sa @RFC3261 appendix A, NTATAG_SIP_T1(), NTATAG_SIP_T2(), NTATAG_SIP_T4()
+ *
+ */
#define NTATAG_SIP_T1X64(x) ntatag_sip_t1x64, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_sip_t1x64_ref;
#define NTATAG_SIP_T1X64_REF(x) ntatag_sip_t1x64_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sip_t2;
-/** Maximum retransmission interval (in milliseconds) @HI */
+/** Maximum retransmission interval (in milliseconds) @HI
+ *
+ * Set the maximum retransmission interval used by the SIP transaction
+ * engine. The T2 is the maximum duration used for the timers E (UDP) and G
+ * by the SIP transaction engine. Note that the timer A is not capped by T2.
+ * Retransmission interval of INVITE requests grows exponentially until the
+ * timer B fires.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - Value of SIP T2 in milliseconds
+ *
+ * @sa @RFC3261 appendix A, NTATAG_SIP_T1(), NTATAG_SIP_T1X4(), NTATAG_SIP_T4()
+ */
#define NTATAG_SIP_T2(x) ntatag_sip_t2, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_sip_t2_ref;
#define NTATAG_SIP_T2_REF(x) ntatag_sip_t2_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sip_t4;
-/** Transaction lifetime (in milliseconds) @HI */
+/** Transaction lifetime (in milliseconds) @HI
+ *
+ * Set the lifetime for completed transactions used by the SIP transaction
+ * engine. A completed transaction is kept around for the duration of T4 in
+ * order to catch late responses. The T4 is the maximum duration for the
+ * messages to stay in the network and the duration of SIP timer K.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - Value of SIP T4 in milliseconds
+ *
+ * @sa @RFC3261 appendix A, NTATAG_SIP_T1(), NTATAG_SIP_T1X4(), NTATAG_SIP_T2()
+ */
#define NTATAG_SIP_T4(x) ntatag_sip_t4, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_sip_t4_ref;
#define NTATAG_SIP_T4_REF(x) ntatag_sip_t4_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_progress;
-/** Progress timer for User-Agents (interval for retranmitting 1XXs) @HI */
+/** Progress timer for User-Agents (interval for retranmitting 1XXs) @HI.
+ *
+ * The UAS should retransmit preliminary responses to the INVITE
+ * transactions every minute in order to re-set the timer C within the
+ * intermediate proxies.
+ *
+ * The default value for the progress timer is 60000.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * Value of progress timer in milliseconds.
+ *
+ * @sa @RFC3261 sections 13.3.1.1, 16.7 and 16.8, NTATAG_TIMER_C(),
+ * NTATAG_SIP_T1(), NTATAG_SIP_T1X4(), NTATAG_SIP_T2(), NTATAG_SIP_T4()
+ */
#define NTATAG_PROGRESS(x) ntatag_progress, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_progress_ref;
#define NTATAG_PROGRESS_REF(x) ntatag_progress_ref, tag_uint_vr(&(x))
+NTA_DLL extern tag_typedef_t ntatag_timer_c;
+/** Value for timer C in milliseconds. @HI
+ *
+ * By default the INVITE transaction will not timeout after a preliminary
+ * response has been received. However, an intermediate proxy can timeout
+ * the transaction using timer C. Timer C is reset every time a response
+ * belonging to the transaction is received.
+ *
+ * The default value for the timer C is 185000 milliseconds (3 minutes and 5
+ * seconds). By default, timer C is not run on user agents (if NTATAG_UA(1)
+ * without NTATAG_TIMER_C() is fgiven).
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * Value of SIP timer C in milliseconds. The default value is used
+ * instead if NTATAG_TIMER_C(0) is given.
+ *
+ * @sa @RFC3261 sections 13.3.1.1, 16.7 and 16.8,
+ * NTATAG_UA(1), NTATAG_TIMER_C(),
+ * NTATAG_SIP_T1(), NTATAG_SIP_T1X4(), NTATAG_SIP_T2(), NTATAG_SIP_T4()
+ */
+#define NTATAG_TIMER_C(x) ntatag_timer_c, tag_uint_v((x))
+
+NTA_DLL extern tag_typedef_t ntatag_timer_c_ref;
+#define NTATAG_TIMER_C_REF(x) ntatag_timer_c_ref, tag_uint_vr(&(x))
+
NTA_DLL extern tag_typedef_t ntatag_blacklist;
-/** Add Retry-After header to internally-generated error messages. @HI */
+/** Add Retry-After header to internally-generated error messages. @HI
+ *
+ * The NTATAG_BLACKLIST() provides a default value for @RetryAfter header
+ * added to the internally generated responses such as <i>503 DNS Error</i>
+ * or <i>408 Timeout</i>. The idea is that the application can retain its
+ * current state and retry the operation after a while.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - Value of @RetryAfter header (in seconds)
+ *
+ * @sa NTATAG_TIMEOUT_408()
+ */
#define NTATAG_BLACKLIST(x) ntatag_blacklist, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_blacklist_ref;
@@ -250,38 +557,134 @@
NTA_DLL extern tag_typedef_t ntatag_debug_drop_prob;
/** Packet drop probability for debugging.
*
- * The packet drop probability parameter is useful mainly in proxies for
- * debugging purposes. The stack drops an incoming message with the given
- * probability. The range is in 0 .. 1000, 500 means p=0.5.
- @HI */
+ * The packet drop probability parameter is useful mainly for debugging
+ * purposes. The stack drops an incoming message received over an unreliable
+ * transport (such as UDP) with the given probability. The range is in 0 ..
+ * 1000, 500 means p=0.5.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned integer
+ *
+ * @par Values
+ * - Valid values are in range 0 ... 1000
+ * - Probablity to drop a given message is value / 1000.
+ *
+ * @HI
+ */
#define NTATAG_DEBUG_DROP_PROB(x) ntatag_debug_drop_prob, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_debug_drop_prob_ref;
#define NTATAG_DEBUG_DROP_PROB_REF(x) ntatag_debug_drop_prob_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sigcomp_options;
-/** Semicolon-separate SigComp options. @HI */
+/** Semicolon-separated SigComp options.
+ *
+ * @note This tag is has no effect without a SigComp plugin.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ * nta_agent_add_tport() \n
+ *
+ * @par Parameter type
+ * string
+ *
+ * @par Values
+ * - semicolon-separated parameter-value pairs, passed to the SigComp plugin
+ *
+ * @sa NTATAG_COMP(), NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_AWARE(),
+ * NTATAG_SIGCOMP_CLOSE(), @RFC3320
+ * @HI
+ */
#define NTATAG_SIGCOMP_OPTIONS(x) ntatag_sigcomp_options, tag_str_v((x))
NTA_DLL extern tag_typedef_t ntatag_sigcomp_options_ref;
#define NTATAG_SIGCOMP_OPTIONS_REF(x) ntatag_sigcomp_options_ref, tag_str_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sigcomp_close;
-/** Close SigComp compartment after completing transaction. @HI */
+/** Close SigComp compartment after completing transaction.
+ *
+ * @note This tag is has no effect without a SigComp plugin.
+ *
+ * @par Used with
+ * nta_incoming_set_params(), nta_incoming_treply()
+ * nta_outgoing_mcreate(), nta_outgoing_tcreate(),
+ * nta_outgoing_tmcreate(), nta_outgoing_tcancel()
+ * nta_outgoing_prack(), nta_msg_tsend(), nta_msg_treply()
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - application takes care of compartment management
+ * - false - stack manages compartments
+ *
+ * @sa NTATAG_COMP(), TPTAG_COMPARTMENT(),
+ * NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_AWARE(),
+ * NTATAG_SIGCOMP_OPTIONS(), @RFC3320
+ * @HI
+ */
#define NTATAG_SIGCOMP_CLOSE(x) ntatag_sigcomp_close, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_sigcomp_close_ref;
#define NTATAG_SIGCOMP_CLOSE_REF(x) ntatag_sigcomp_close_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sigcomp_aware;
-/** Indicate that the application is SigComp-aware. */
+/** Indicate that the application is SigComp-aware.
+ *
+ * @note This tag is has no effect without a SigComp plugin.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - application takes care of compartment management
+ * - false - stack manages compartments
+ *
+ * @sa NTATAG_COMP(), NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_CLOSE(),
+ * NTATAG_SIGCOMP_OPTIONS(), @RFC3320
+ *
+ * @HI
+ */
#define NTATAG_SIGCOMP_AWARE(x) ntatag_sigcomp_aware, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_sigcomp_aware_ref;
#define NTATAG_SIGCOMP_AWARE_REF(x) ntatag_sigcomp_aware_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sigcomp_algorithm;
-/** Specify SigComp algorithm. For example, NULL, LZSS, or LZSS-POC.
+/** Specify SigComp algorithm.
+ *
+ * @note This tag is has no effect without a SigComp plugin.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ * nta_agent_add_tport() \n
+ *
+ * @par Parameter type
+ * string
+ *
+ * @par Values
+ * - opaque string passed to the SigComp plugin
+ *
+ * @sa NTATAG_COMP(), NTATAG_SIGCOMP_AWARE(), NTATAG_SIGCOMP_CLOSE(),
+ * NTATAG_SIGCOMP_OPTIONS(), @RFC3320
+ *
+ * @HI
*/
#define NTATAG_SIGCOMP_ALGORITHM(x) ntatag_sigcomp_algorithm, tag_str_v((x))
@@ -290,49 +693,227 @@
ntatag_sigcomp_algorithm_ref, tag_str_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_ua;
-/** If true, NTA acts as User Agent Server or Client by default. @HI */
+/** If true, NTA acts as User Agent Server or Client by default.
+ *
+ * When acting as an UA, the NTA stack will
+ * - respond with 481 to a PRACK request with no matching "100rel" response
+ * - check for out-of-order CSeq headers for each #nta_leg_t dialog object
+ * - if NTATAG_MERGE_482(1) is also used, return <i>482 Request Merged</i> to
+ * a duplicate request with same @CallID, @CSeq, @From tag but different
+ * topmost @Via header (see @RFC3261 section 8.2.2.2 Merged Requests)
+ * - silently discard duplicate final responses to INVITE
+ * - retransmit preliminary responses (101..199) to INVITE request in regular
+ * intervals ("timer N2")
+ * - retransmit 2XX response to INVITE request with exponential intervals
+ * - handle ACK sent in 2XX response to an INVITE using the
+ * #nta_ack_cancel_f callback bound to #nta_incoming_t with
+ * nta_incoming_bind()
+ * - not use timer C unless its value has been explicitly set
+ *
+ * @note This NUTAG_UA(1) is set internally by nua_create()
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - act as an UA
+ * - false - act as an proxy
+ *
+ * @sa NTATAG_MERGE_482()
+ */
#define NTATAG_UA(x) ntatag_ua, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_ua_ref;
#define NTATAG_UA_REF(x) ntatag_ua_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_stateless;
-/** If true, agent processes incoming requests statelessly by default. @HI */
+/** Enable stateless processing. @HI
+ *
+ * @par Server side
+ * The incoming requests are processed statefully if there is a default leg
+ * (created with nta_leg_default()). This option is provided for proxies or
+ * other server elements that process requests statelessly.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Values
+ * - true - do not pass incoming requests to default leg
+ * - false - pass incoming requests to default leg, if it exists
+ *
+ * @par Client side
+ * The outgoing requests can be sent statelessly, too, if the
+ * NTATAG_STATELESS(1) is included in the tag list of nta_outgoing_tcreate().
+ *
+ * @par Used with
+ * nta_outgoing_mcreate(), nta_outgoing_tcreate(),
+ * nta_outgoing_tcancel(), nta_outgoing_prack()
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - create only a transient #nta_outgoing_t transaction object
+ * - false - create an ordinary client transaction object
+ *
+ * @sa NTATAG_IS_UA(), nta_incoming_default(), nta_outgoing_default(),
+ * nta_leg_default()
+ */
#define NTATAG_STATELESS(x) ntatag_stateless, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_stateless_ref;
#define NTATAG_STATELESS_REF(x) ntatag_stateless_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_user_via;
-/** Allow application to insert Via headers. @HI */
+/** Allow application to insert Via headers. @HI
+ *
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true -
+ * - false -
+ *
+ * @sa
+ *
+ */
#define NTATAG_USER_VIA(x) ntatag_user_via, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_user_via_ref;
#define NTATAG_USER_VIA_REF(x) ntatag_user_via_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_extra_100;
-/** Respond with "100 Trying" if application has not responded. @HI */
+/** Respond with "100 Trying" if application has not responded.
+ *
+ * As per recommended by @RFC4320, the stack can generate a 100 Trying
+ * response to the non-INVITE requests if the application has not responded
+ * to a request within half of the SIP T2 (the default value for T2 is 4000
+ * milliseconds, so the extra <i>100 Trying<i/> would be sent after 2 seconds).
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - send extra 100 Trying if application does not respond
+ * - false - do not send 100 Trying (default)
+ *
+ * @sa @RFC4320, NTATAG_PASS_408(), NTATAG_TIMEOUT_408()
+ */
#define NTATAG_EXTRA_100(x) ntatag_extra_100, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_extra_100_ref;
#define NTATAG_EXTRA_100_REF(x) ntatag_extra_100_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_pass_100;
-/** Pass "100 Trying" provisional answers to the application. @HI */
+/** Pass "100 Trying" provisional answers to the application. @HI
+ *
+ * By default, the stack silently processes the <i>100 Trying</i> responses
+ * from the server. Usually the <i>100 Trying</i> responses are not
+ * important to the application but rather sent by the outgoing proxy
+ * immediately after it has received the request. However, the application
+ * can ask nta for them by setting NTATAG_PASS_100(1) if, for instance, the
+ * <i>100 Trying</i> responses are needed for user feedback.
+ *
+ * @par Used with
+ * nua_create(), nta_agent_create(), nta_agent_set_params() \n
+ * nta_outgoing_mcreate(), nta_outgoing_tcreate(),
+ * nta_outgoing_tcancel(), nta_outgoing_prack(), nta_msg_tsend()
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - pass <i>100 Trying</i> to application
+ * - false - silently process <i>100 Trying</i> responses
+ *
+ * @sa NTATAG_EXTRA_100(), NTATAG_DEFAULT_PROXY()
+ */
#define NTATAG_PASS_100(x) ntatag_pass_100, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_pass_100_ref;
#define NTATAG_PASS_100_REF(x) ntatag_pass_100_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_timeout_408;
-/** Generate "408 Request Timeout" response when request times out. @HI */
+/** Generate "408 Request Timeout" response when request times out. @HI
+ *
+ * This tag is used to prevent stack from generating extra 408 response
+ * messages to non-INVITE requests upon timeout. As per recommended by
+ * @RFC4320, the <i>408 Request Timeout</i> responses to non-INVITE
+ * transaction are not sent over the network to the client by default. The
+ * application can ask stack to pass the 408 responses with
+ * NTATAG_PASS_408(1).
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - generate 408 response
+ * - false - invoke #nta_response_f callback with NULL sip pointer
+ * when a non-INVITE transaction times out
+ *
+ * @sa @RFC4320, NTATAG_PASS_408(), NTATAG_EXTRA_100(),
+ */
#define NTATAG_TIMEOUT_408(x) ntatag_timeout_408, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_timeout_408_ref;
#define NTATAG_TIMEOUT_408_REF(x) ntatag_timeout_408_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_pass_408;
-/** Pass "408 Request Timeout" responses to client. @HI */
+/** Pass "408 Request Timeout" responses to the client. @HI
+ *
+ * As per recommended by @RFC4320, the <i>408 Request Timeout</i> responses
+ * to non-INVITE transaction are not sent over the network to the client by
+ * default. The application can ask stack to pass the 408 responses with
+ * NTATAG_PASS_408(1).
+ *
+ * Note that unlike NTATAG_PASS_100(), this tags changes the way server side
+ * works.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - pass superfluous 408 responses
+ * - false - discard superfluous 408 responses
+ *
+ * @sa @RFC4320, NTATAG_EXTRA_100(), NTATAG_TIMEOUT_408()
+ *
+ */
#define NTATAG_PASS_408(x) ntatag_pass_408, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_pass_408_ref;
@@ -346,70 +927,306 @@
#define NTATAG_NO_DIALOG_REF(x) ntatag_no_dialog_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_merge_482;
-/** Merge requests, send 482 to other requests. @HI */
+/** Merge requests, send 482 to other requests. @HI
+ *
+ * If an User-Agent receives a duplicate request with same @CallID, @CSeq,
+ * @From tag but different topmost @Via header (see @RFC3261 section 8.2.2.2
+ * Merged Requests), it should return <i>482 Request Merged</i> response to
+ * the duplicate request. Such a duplicate request has been originally
+ * generated by a forking proxy and usually routed via different route to
+ * the User-Agent. The User-Agent should only respond meaningfully to the
+ * first request and return the 482 response to the following forked
+ * requests.
+ *
+ * Note that also NTATAG_UA(1) should be set before nta detects merges and
+ * responds with 482 to them.
+ *
+ * @note If your application is an multi-lined user-agent, you may consider
+ * disabling request merging. However, you have to somehow handle merging
+ * within a single line.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - detect duplicate requests and respond with 482 to them
+ * - false - process duplicate requests separately
+ *
+ * @sa NTATAG_UA(1)
+ */
#define NTATAG_MERGE_482(x) ntatag_merge_482, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_merge_482_ref;
#define NTATAG_MERGE_482_REF(x) ntatag_merge_482_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_cancel_2543;
-/** Send a CANCEL to an INVITE without an provisional response. @HI */
+/**Follow @RFC2543 semantics with CANCEL.
+ *
+ * By default, the nta follows "@RFC3261" semantics when CANCELing a
+ * request. The CANCEL does not terminate transaction, rather, it is just a
+ * hint to the server that it should respond immediately (with <i>487
+ * Request Terminated</i> if it has no better response). Also, if the
+ * original request was sent over unreliable transport such as UDP, the
+ * CANCEL is delayed until the server has sent a preliminary response to the
+ * original request.
+ *
+ * If NTATAG_CANCEL_2543(1) is given, the transaction is canceled
+ * immediately internally (a 487 response is generated locally) and the
+ * CANCEL request is sent without waiting for an provisional response.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ * nta_outgoing_tcancel()
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - follow "RFC 2543" semantics with CANCEL
+ * - false - follow "RFC 3261" semantics with CANCEL
+ *
+ * @sa NTATAG_CANCEL_408()
+ *
+ * @HI
+ */
#define NTATAG_CANCEL_2543(x) ntatag_cancel_2543, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_cancel_2543_ref;
#define NTATAG_CANCEL_2543_REF(x) ntatag_cancel_2543_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_cancel_408;
-/** Do not send a CANCEL but just timeout the request. @HI */
+/** Do not send a CANCEL but just timeout the request.
+ *
+ * Calling nta_outgoing_tcancel() with this tag set marks request as
+ * canceled but does not actually send a CANCEL request. If
+ * NTATAG_CANCEL_2543(1) is also included, a 487 response is generated
+ * internally.
+ *
+ * @par Used with
+ * nta_outgoing_tcancel() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - do not send CANCEL
+ * - false - let request to timeout
+ *
+ * @sa NTATAG_CANCEL_2543()
+ */
#define NTATAG_CANCEL_408(x) ntatag_cancel_408, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_cancel_408_ref;
#define NTATAG_CANCEL_408_REF(x) ntatag_cancel_408_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_tag_3261;
-/** When responding to requests, use unique tags. @HI */
+/** When responding to requests, use unique tags. @HI
+ *
+ * If set the UA would generate an unique @From/@To tag for all dialogs. If
+ * unset UA would reuse same tag in order to make it easier to re-establish
+ * dialog state after a reboot.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - use different tag for each dialog
+ * - false - use same tag for all dialogs
+ *
+ * @sa @RFC3261 section 12.2.2
+ */
#define NTATAG_TAG_3261(x) ntatag_tag_3261, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_tag_3261_ref;
#define NTATAG_TAG_3261_REF(x) ntatag_tag_3261_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_use_timestamp;
-/** Use Timestamp header. @HI */
+/** Use @Timestamp header. @HI
+ *
+ * If set, a @Timestamp header would be added to stateful requests. The
+ * header can be used to calculate the roundtrip transport latency between
+ * client and server.
+ *
+ * @par Used with
+ * nua_create(),
+ * nta_agent_create(),
+ * nta_agent_set_params(),
+ * nta_outgoing_mcreate(), nta_outgoing_tcreate(),
+ * nta_outgoing_tcancel(), and nta_outgoing_prack().
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - Add @Timestamp header
+ * - false - do not add @Timestamp header
+ *
+ * @sa @RFC3261 section 8.2.6
+ */
#define NTATAG_USE_TIMESTAMP(x) ntatag_use_timestamp, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_use_timestamp_ref;
#define NTATAG_USE_TIMESTAMP_REF(x) ntatag_use_timestamp_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_method;
-/** Method name. @HI */
+/**Method name. @HI
+ *
+ * Create a dialogless #nta_leg_t object matching only requests with
+ * the specified method.
+ *
+ * @par Used with
+ * nta_leg_tcreate()
+ *
+ * @par Parameter type
+ * String containing method name.
+ *
+ * @par Values
+ * SIP method name (e.g., "SUBSCRIBE").
+ *
+ */
#define NTATAG_METHOD(x) ntatag_method, tag_str_v((x))
NTA_DLL extern tag_typedef_t ntatag_method_ref;
#define NTATAG_METHOD_REF(x) ntatag_method_ref, tag_str_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_cancel_487;
-/** When a CANCEL is received, reply with 487 response. True by default. @HI */
+/** When a CANCEL is received, automatically return 487 response to original request.
+ *
+ * When the CANCEL is received for an ongoing server transaction
+ * #nta_incoming_t, the stack will automatically return a <i>487 Request
+ * Terminated</i> response to the client after returning from the
+ * #nta_incoming_f callback bound to the transaction with
+ * nta_incoming_bind()
+ *
+ * The application can delay sending the response to the original request
+ * when NTATAG_CANCEL_408(0) is used. This is useful, for instance, with a
+ * proxy that forwards the CANCEL downstream and the forwards the response
+ * back to upstream.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - respond automatically to the CANCELed transaction
+ * - false - application takes care of responding
+ *
+ * @sa NTATAG_CANCEL_2543(), nta_incoming_bind()
+ *
+ * @HI
+ */
#define NTATAG_CANCEL_487(x) ntatag_cancel_487, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_cancel_487_ref;
#define NTATAG_CANCEL_487_REF(x) ntatag_cancel_487_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_rel100;
-/** Include rel100 in INVITE requests. @HI */
+/** Include rel100 in INVITE requests. @HI
+ *
+ * Include feature tag "100rel" in @Supported header of the INVITE requests.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - include "100rel"
+ * - false - do not include "100rel"
+ *
+ * @sa nta_outgoing_prack(), nta_reliable_treply(), nta_reliable_mreply()
+ */
#define NTATAG_REL100(x) ntatag_rel100, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_rel100_ref;
#define NTATAG_REL100_REF(x) ntatag_rel100_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_sipflags;
-/** Set SIP parser flags. @HI */
+/** Set SIP parser flags. @HI
+ *
+ * The SIP parser flags affect how the messages are parsed and the result
+ * presented to the application. They also control encoding of messages.
+ * The most important flags are as follows:
+ * - MSG_FLG_COMPACT - use compact form
+ * (single-letter header names, minimum whitespace)
+ * - MSG_FLG_EXTRACT_COPY - cache printable copy of headers when parsing.
+ * Using this flag can speed up proxy processing considerably. It is
+ * implied when the parsed messages are logged (because #TPORT_LOG
+ * environment variable is set, or TPTAG_LOG() is used.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned int
+ *
+ * @par Values
+ * - Bitwise OR of SIP parser flags (enum #msg_flg_user)
+ *
+ * @sa NTATAG_PRELOAD(), enum #msg_flg_user, sip_s::sip_flags
+ */
#define NTATAG_SIPFLAGS(x) ntatag_sipflags, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_sipflags_ref;
#define NTATAG_SIPFLAGS_REF(x) ntatag_sipflags_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_client_rport;
-/** Add rport at client. @HI */
+/** Enable client-side "rport". @HI
+ *
+ * This tag controls @RFC3581 support on client side. The "rport" parameter
+ * is used when the response has to be routed symmetrically through a NAT box.
+ *
+ * The client-side support involves just adding the "rport" parameter to the topmost
+ * @Via header before the request is sent.
+ *
+ * @note By default, the client "rport" is disabled when nta is used, and
+ * enabled when nua is used.
+ *
+ * @par Used with
+ * nua_create() (nua uses NTATAG_CLIENT_RPORT(1) by default) \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - add "rport" parameter
+ * - false - do not add "rport" parameter
+ *
+ * @note The NTATAG_RPORT() is a synonym for this.
+ *
+ * @sa @RFC3581, NTATAG_SERVER_RPORT(), @Via
+ */
#define NTATAG_CLIENT_RPORT(x) ntatag_client_rport, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_client_rport_ref;
@@ -419,42 +1236,158 @@
#define NTATAG_RPORT_REF(x) ntatag_client_rport_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_server_rport;
-/** Use rport at server. @HI */
+/** Use rport parameter at server.
+ *
+ * This tag controls @RFC3581 support on server side. The "rport" parameter
+ * is used when the response has to be routed symmetrically through a NAT
+ * box.
+ *
+ * If the topmost @Via header has an "rport" parameter, the server stores
+ * the port number from which the request was sent in it. When sending the
+ * response back to the client, the server uses the port number in the
+ * "rport" parameter rather than the client-supplied port number in @Via
+ * header.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - use "rport" parameter (default)
+ * - false - do not use "rport" parameterx
+ *
+ * @sa @RFC3581, NTATAG_CLIENT_RPORT(), @Via
+ */
#define NTATAG_SERVER_RPORT(x) ntatag_server_rport, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_server_rport_ref;
#define NTATAG_SERVER_RPORT_REF(x) ntatag_server_rport_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_tcp_rport;
-/** Use rport with TCP, too. @HI */
+/** Use rport with TCP, too. @HI
+ *
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true -
+ * - false -
+ *
+ * @sa
+ *
+ */
#define NTATAG_TCP_RPORT(x) ntatag_tcp_rport, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_tcp_rport_ref;
#define NTATAG_TCP_RPORT_REF(x) ntatag_tcp_rport_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_preload;
-/** Preload by N bytes. @HI */
+/** Preload by N bytes. @HI
+ *
+ * When the memory block is allocated for an incoming request by the stack,
+ * the stack can allocate some extra memory for the parser in addition to
+ * the memory used by the actual message contents.
+ *
+ * While wasting some memory, this can speed up parsing considerably.
+ * Recommended amount of preloading per packet is 1500 bytes.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * unsigned
+ *
+ * @par Values
+ * Amount of extra per-message memory allocated for parser.
+ *
+ * @sa NTATAG_SIPFLAGS() and #MSG_FLG_EXTRACT_COPY
+ */
#define NTATAG_PRELOAD(x) ntatag_preload, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_preload_ref;
#define NTATAG_PRELOAD_REF(x) ntatag_preload_ref, tag_uint_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_use_naptr;
-/** If true, try to use NAPTR records when resolving. @HI */
+/** If true, try to use NAPTR records when resolving. @HI
+ *
+ * The application can disable NTA from using NAPTR records when resolving
+ * SIP URIs.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - enable NAPTR resolving
+ * - false - disable NAPTR resolving
+ *
+ * @bug NAPTRs are not used with SIPS URIs in any case.
+ *
+ * @sa @RFC3263, NTATAG_USE_SRV()
+ */
#define NTATAG_USE_NAPTR(x) ntatag_use_naptr, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_use_naptr_ref;
#define NTATAG_USE_NAPTR_REF(x) ntatag_use_naptr_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_use_srv;
-/** If true, try to use SRV records when resolving. @HI */
+/** If true, try to use SRV records when resolving.
+ *
+ * The application can disable NTA from using SRV records when resolving
+ * SIP URIs.
+ *
+ * @par Used with
+ * nua_create() \n
+ * nta_agent_create() \n
+ * nta_agent_set_params() \n
+ *
+ * @par Parameter type
+ * boolean: true (non-zero or non-NULL pointer)
+ * or false (zero or NULL pointer)
+ *
+ * @par Values
+ * - true - enable SRV resolving
+ * - false - disable SRV resolving
+ *
+ * @sa @RFC3263, NTATAG_USE_NAPTR()
+ */
#define NTATAG_USE_SRV(x) ntatag_use_srv, tag_bool_v((x))
NTA_DLL extern tag_typedef_t ntatag_use_srv_ref;
#define NTATAG_USE_SRV_REF(x) ntatag_use_srv_ref, tag_bool_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_rseq;
-/** RSeq value for nta_outgoing_prack(), @HI */
+
+/** @RSeq value for nta_outgoing_prack(). @HI
+ *
+ * @par Used with
+ * nta_outgoing_prack()
+ *
+ * @par Parameter type
+ * @c unsigned @c int
+ *
+ * @par Values
+ * Response sequence number from the @RSeq header.
+*/
#define NTATAG_RSEQ(x) ntatag_rseq, tag_uint_v((x))
NTA_DLL extern tag_typedef_t ntatag_rseq_ref;
@@ -467,24 +1400,56 @@
#define NTATAG_S_IRQ_HASH(x) ntatag_s_irq_hash, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_irq_hash_ref;
+/** Get size of hash table for server-side transactions.
+ *
+ * Return number of transactions that fit in the hash table for server-side
+ * transactions.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_IRQ_HASH_USED_REF(),
+ * NTATAG_S_ORQ_HASH_REFxs(), NTATAG_S_LEG_HASH_REF()
+ */
#define NTATAG_S_IRQ_HASH_REF(x) ntatag_s_irq_hash_ref, tag_usize_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_s_orq_hash;
#define NTATAG_S_ORQ_HASH(x) ntatag_s_orq_hash, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_orq_hash_ref;
+/** Get size of hash table for client-side transactions.
+ *
+ * Return number of transactions that fit in the hash table for client-side
+ * transactions.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_ORQ_HASH_USED_REF(),
+ * NTATAG_S_IRQ_HASH_REF(), NTATAG_S_LEG_HASH_REF()
+ */
#define NTATAG_S_ORQ_HASH_REF(x) ntatag_s_orq_hash_ref, tag_usize_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_s_leg_hash;
#define NTATAG_S_LEG_HASH(x) ntatag_s_leg_hash, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_leg_hash_ref;
+/** Get size of hash table for dialogs.
+ *
+ * Return number of dialog objects that fit in the hash table for dialogs.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_LEG_HASH_USED_REF(),
+ * NTATAG_S_IRQ_HASH_REF(), NTATAG_S_ORQ_HASH_REF()
+ */
#define NTATAG_S_LEG_HASH_REF(x) ntatag_s_leg_hash_ref, tag_usize_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_s_irq_hash_used;
#define NTATAG_S_IRQ_HASH_USED(x) ntatag_s_irq_hash_used, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_irq_hash_used_ref;
+/** Get number of server-side transactions in the hash table.
+ *
+ * Return number of server-side transactions objects in the hash table. The
+ * number includes all transactions destroyed by the application which have
+ * not expired yet.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_IRQ_HASH_REF(),
+ * NTATAG_S_ORQ_HASH_USED_REF(), NTATAG_S_LEG_HASH_USED_REF()
+ */
#define NTATAG_S_IRQ_HASH_USED_REF(x) \
ntatag_s_irq_hash_used_ref, tag_usize_vr(&(x))
@@ -492,6 +1457,15 @@
#define NTATAG_S_ORQ_HASH_USED(x) ntatag_s_orq_hash_used, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_orq_hash_used_ref;
+/** Get number of client-side transactions in the hash table.
+ *
+ * Return number of client-side transactions objects in the hash table. The
+ * number includes all transactions destroyed by the application which have
+ * not expired yet.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_ORQ_HASH_REF(),
+ * NTATAG_S_IRQ_HASH_USED_REF(), NTATAG_S_LEG_HASH_USED_REF()
+ */
#define NTATAG_S_ORQ_HASH_USED_REF(x) \
ntatag_s_orq_hash_used_ref, tag_usize_vr(&(x))
@@ -499,6 +1473,15 @@
#define NTATAG_S_LEG_HASH_USED(x) ntatag_s_leg_hash_used, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_leg_hash_used_ref;
+/** Get number of dialogs in the hash table.
+ *
+ * Return number of dialog objects in the hash table. Note that the
+ * nta_leg_t objects created with NTATAG_NO_DIALOG(1) and this not
+ * corresponding to a dialog are not included in the number.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_LEG_HASH_REF(),
+ * NTATAG_S_IRQ_HASH_USED_REF(), NTATAG_S_ORQ_HASH_USED_REF()
+ */
#define NTATAG_S_LEG_HASH_USED_REF(x) \
ntatag_s_leg_hash_used_ref, tag_usize_vr(&(x))
@@ -506,12 +1489,28 @@
#define NTATAG_S_RECV_MSG(x) ntatag_s_recv_msg, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_recv_msg_ref;
+/** Get number of SIP messages received.
+ *
+ * Return number SIP messages that has been received. The number includes
+ * also bad and unparsable messages.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_BAD_MESSAGE_REF(),
+ * NTATAG_S_RECV_REQUEST_REF(), NTATAG_S_RECV_RESPONSE_REF()
+ */
#define NTATAG_S_RECV_MSG_REF(x) ntatag_s_recv_msg_ref, tag_usize_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_s_recv_request;
#define NTATAG_S_RECV_REQUEST(x) ntatag_s_recv_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_recv_request_ref;
+/** Get number of SIP requests received.
+ *
+ * Return number SIP requests that has been received. The number includes
+ * also number of bad requests available with NTATAG_S_BAD_REQUEST_REF().
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_BAD_REQUEST_REF(),
+ * NTATAG_S_RECV_MSG_REF(), NTATAG_S_RECV_RESPONSE_REF()
+ */
#define NTATAG_S_RECV_REQUEST_REF(x)\
ntatag_s_recv_request_ref, tag_usize_vr(&(x))
@@ -519,6 +1518,15 @@
#define NTATAG_S_RECV_RESPONSE(x) ntatag_s_recv_response, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_recv_response_ref;
+/** Get number of SIP responses received.
+ *
+ * Return number SIP responses that has been received. The number includes
+ * also number of bad and unusable responses available with
+ * NTATAG_S_BAD_RESPONSE_REF().
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_BAD_RESPONSE_REF(),
+ * NTATAG_S_RECV_MSG_REF(), NTATAG_S_RECV_REQUEST_REF()
+ */
#define NTATAG_S_RECV_RESPONSE_REF(x)\
ntatag_s_recv_response_ref, tag_usize_vr(&(x))
@@ -526,6 +1534,13 @@
#define NTATAG_S_BAD_MESSAGE(x) ntatag_s_bad_message, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_bad_message_ref;
+/** Get number of bad SIP messages received.
+ *
+ * Return number of bad SIP messages that has been received.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_RECV_MSG_REF(),
+ * NTATAG_S_BAD_REQUEST_REF(), NTATAG_S_BAD_RESPONSE_REF().
+ */
#define NTATAG_S_BAD_MESSAGE_REF(x)\
ntatag_s_bad_message_ref, tag_usize_vr(&(x))
@@ -533,6 +1548,13 @@
#define NTATAG_S_BAD_REQUEST(x) ntatag_s_bad_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_bad_request_ref;
+/** Get number of bad SIP requests received.
+ *
+ * Return number of bad SIP requests that has been received.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_BAD_MESSAGE_REF(),
+ * NTATAG_S_BAD_RESPONSE_REF().
+ */
#define NTATAG_S_BAD_REQUEST_REF(x)\
ntatag_s_bad_request_ref, tag_usize_vr(&(x))
@@ -540,6 +1562,13 @@
#define NTATAG_S_BAD_RESPONSE(x) ntatag_s_bad_response, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_bad_response_ref;
+/** Get number of bad SIP responses received.
+ *
+ * Return number of bad SIP responses that has been received.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_BAD_MESSAGE_REF(),
+ * NTATAG_S_BAD_REQUEST_REF()
+ */
#define NTATAG_S_BAD_RESPONSE_REF(x)\
ntatag_s_bad_response_ref, tag_usize_vr(&(x))
@@ -547,6 +1576,16 @@
#define NTATAG_S_DROP_REQUEST(x) ntatag_s_drop_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_drop_request_ref;
+/** Get number of SIP requests dropped.
+ *
+ * Return number of SIP requests that has been randomly dropped after
+ * receiving them because of NTATAG_DEBUG_DROP_PROB() has been set.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_DEBUG_DROP_PROB(),
+ * NTATAG_S_DROP_RESPONSE_REF()
+ *
+ * @note The value was not calculated before @VERSION_1_12_7.
+ */
#define NTATAG_S_DROP_REQUEST_REF(x)\
ntatag_s_drop_request_ref, tag_usize_vr(&(x))
@@ -554,6 +1593,16 @@
#define NTATAG_S_DROP_RESPONSE(x) ntatag_s_drop_response, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_drop_response_ref;
+/** Get number of SIP responses dropped.
+ *
+ * Return number of SIP responses that has been randomly dropped after
+ * receiving them because of NTATAG_DEBUG_DROP_PROB() has been set.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_DEBUG_DROP_PROB(),
+ * NTATAG_S_DROP_REQUEST_REF()
+ *
+ * @note The value was not calculated before @VERSION_1_12_7.
+ */
#define NTATAG_S_DROP_RESPONSE_REF(x)\
ntatag_s_drop_response_ref, tag_usize_vr(&(x))
@@ -561,6 +1610,18 @@
#define NTATAG_S_CLIENT_TR(x) ntatag_s_client_tr, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_client_tr_ref;
+/** Get number of client transactions created.
+ *
+ * Return number of client transactions created. The number also includes
+ * client transactions with which stack failed to send the request because
+ * the DNS resolving failed or the transport failed.
+ *
+ * @note The number include stateless requests sent with nta_msg_tsend(),
+ * too.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_SENT_REQUEST_REF(),
+ * NTATAG_S_SERVER_TR_REF().
+ */
#define NTATAG_S_CLIENT_TR_REF(x)\
ntatag_s_client_tr_ref, tag_usize_vr(&(x))
@@ -568,6 +1629,13 @@
#define NTATAG_S_SERVER_TR(x) ntatag_s_server_tr, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_server_tr_ref;
+/** Get number of server transactions created.
+ *
+ * Return number of server transactions created.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_RECV_RESPONSE_REF(),
+ * NTATAG_S_CLIENT_TR_REF(), NTATAG_S_DIALOG_TR_REF(),
+ */
#define NTATAG_S_SERVER_TR_REF(x)\
ntatag_s_server_tr_ref, tag_usize_vr(&(x))
@@ -575,6 +1643,15 @@
#define NTATAG_S_DIALOG_TR(x) ntatag_s_dialog_tr, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_dialog_tr_ref;
+/** Get number of in-dialog server transactions created.
+ *
+ * Return number of in-dialog server transactions created. The number
+ * includes only those transactions that were correlated with a dialog
+ * object.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_SERVER_TR_REF(),
+ * NTATAG_S_CLIENT_TR_REF(), NTATAG_S_RECV_RESPONSE_REF().
+ */
#define NTATAG_S_DIALOG_TR_REF(x)\
ntatag_s_dialog_tr_ref, tag_usize_vr(&(x))
@@ -582,12 +1659,29 @@
#define NTATAG_S_ACKED_TR(x) ntatag_s_acked_tr, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_acked_tr_ref;
+/** Get number of server transactions that have received ACK.
+ *
+ * Return number of INVITE server transactions for which an ACK request has
+ * been received.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_SERVER_TR_REF(),
+ * NTATAG_S_CANCELED_TR_REF()
+ */
#define NTATAG_S_ACKED_TR_REF(x) ntatag_s_acked_tr_ref, tag_usize_vr(&(x))
NTA_DLL extern tag_typedef_t ntatag_s_canceled_tr;
#define NTATAG_S_CANCELED_TR(x) ntatag_s_canceled_tr, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_canceled_tr_ref;
+/** Get number of server transactions that have been CANCELed.
+ *
+ * Return number of server transactions for which an CANCEL request has been
+ * received. Currently, the count includes only INVITE server transactions
+ * that have been CANCELed.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_SERVER_TR_REF(),
+ * NTATAG_S_ACKED_TR_REF().
+ */
#define NTATAG_S_CANCELED_TR_REF(x) \
ntatag_s_canceled_tr_ref, tag_usize_vr(&(x))
@@ -595,6 +1689,17 @@
#define NTATAG_S_TRLESS_REQUEST(x) ntatag_s_trless_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_trless_request_ref;
+/** Get number of requests that were processed stateless.
+ *
+ * Return number of received requests that were processed statelessly,
+ * either with #nta_message_f message callback given with the
+ * nta_agent_create() or, missing the callback, by returning a <i>501 Not
+ * Implemented</i> response to the request.
+ *
+ * @sa nta_agent_get_stats(), <sofia-sip/nta_stateless.h>,
+ * nta_agent_create(), #nta_message_f, NTATAG_S_TRLESS_TO_TR_REF(),
+ * NTATAG_S_TRLESS_RESPONSE_REF()
+ */
#define NTATAG_S_TRLESS_REQUEST_REF(x)\
ntatag_s_trless_request_ref, tag_usize_vr(&(x))
@@ -602,6 +1707,14 @@
#define NTATAG_S_TRLESS_TO_TR(x) ntatag_s_trless_to_tr, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_trless_to_tr_ref;
+/** Get number of requests converted to transactions by message callback.
+ *
+ * Return number of requests that were converted to a server transaction
+ * with nta_incoming_create().
+ *
+ * @sa nta_agent_get_stats(), nta_incoming_create(), nta_agent_create(),
+ * #nta_message_f, NTATAG_S_TRLESS_REQUEST_REF()
+ */
#define NTATAG_S_TRLESS_TO_TR_REF(x)\
ntatag_s_trless_to_tr_ref, tag_usize_vr(&(x))
@@ -609,6 +1722,23 @@
#define NTATAG_S_TRLESS_RESPONSE(x) ntatag_s_trless_response, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_trless_response_ref;
+/** Get number of responses without matching request.
+ *
+ * Return number of received responses for which no matching client
+ * transaction was found. Such responses are processed either by the default
+ * client transaction created with nta_outgoing_default(), the
+ * #nta_message_f message callback given to nta_agent_create(), or, missing
+ * both the default client transaction and message callback, they are
+ * silently discarded.
+ *
+ * When stack is in UA mode, the successful 2XX responses to the INVITE
+ * transaction are an exception: when such a response is received the stack
+ * tries to send an ACK and BYE requests to the originator of 2XX response.
+ *
+ * @sa nta_agent_get_stats(), nta_outgoing_default(), nta_agent_create(),
+ * <sofia-sip/nta_stateless.h>, #nta_message_f, nta_msg_ackbye(),
+ * NTATAG_S_TRLESS_REQUEST_REF(), NTATAG_S_TRLESS_200_REF().
+ */
#define NTATAG_S_TRLESS_RESPONSE_REF(x)\
ntatag_s_trless_response_ref, tag_usize_vr(&(x))
@@ -616,6 +1746,21 @@
#define NTATAG_S_TRLESS_200(x) ntatag_s_trless_200, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_trless_200_ref;
+/** Get number of successful responses missing INVITE client transaction.
+ *
+ * Return number of received 2XX responses to INVITE transaction for which
+ * no matching client transaction was found nor which were processed by a
+ * default client transaction created with nta_outgoing_default() or
+ * #nta_message_f message callback given to nta_agent_create().
+ *
+ * When such a successful 2XX responses to the INVITE is received but it is
+ * not processed, the stack tries to send an ACK and BYE requests to the
+ * originator of 2XX response if stack is in UA mode (set by NTATAG_UA(1).
+ *
+ * @sa nta_agent_get_stats(), nta_outgoing_default(), nta_agent_create(),
+ * <sofia-sip/nta_stateless.h>, #nta_message_f, nta_msg_ackbye(),
+ * NTATAG_S_TRLESS_RESPONSE_REF().
+ */
#define NTATAG_S_TRLESS_200_REF(x)\
ntatag_s_trless_200_ref, tag_usize_vr(&(x))
@@ -623,6 +1768,14 @@
#define NTATAG_S_MERGED_REQUEST(x) ntatag_s_merged_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_merged_request_ref;
+/** Get number of requests merged by UAS.
+ *
+ * Return number of requests for which UAS already has returned a response
+ * and which were merged (that is, returned a <i>482 Request Merged</i>
+ * response).
+ *
+ * @sa nta_agent_get_stats(), NTATAG_UA(1), @RFC3261 section 8.2.2.2
+ */
#define NTATAG_S_MERGED_REQUEST_REF(x)\
ntatag_s_merged_request_ref, tag_usize_vr(&(x))
@@ -630,6 +1783,15 @@
#define NTATAG_S_SENT_MSG(x) ntatag_s_sent_msg, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_sent_msg_ref;
+/** Get number of SIP messages sent by stack.
+ *
+ * Return number of SIP messages given to the transport layer for
+ * transmission by the SIP stack. The number includes also messages which
+ * the transport layer failed to send for different reasons.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_RECV_MSG_REF(),
+ * NTATAG_S_SENT_REQUEST_REF(), NTATAG_S_SENT_RESPONSE_REF()
+ */
#define NTATAG_S_SENT_MSG_REF(x)\
ntatag_s_sent_msg_ref, tag_usize_vr(&(x))
@@ -637,6 +1799,15 @@
#define NTATAG_S_SENT_REQUEST(x) ntatag_s_sent_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_sent_request_ref;
+/** Get number of SIP requests sent by stack.
+ *
+ * Return number of SIP requests given to the transport layer for
+ * transmission by the SIP stack. The number includes retransmissions and
+ * messages which the transport layer failed to send for different reasons.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_RECV_REQUEST_REF(),
+ * NTATAG_S_SENT_MSG_REF(), NTATAG_S_SENT_RESPONSE_REF()
+ */
#define NTATAG_S_SENT_REQUEST_REF(x)\
ntatag_s_sent_request_ref, tag_usize_vr(&(x))
@@ -644,6 +1815,15 @@
#define NTATAG_S_SENT_RESPONSE(x) ntatag_s_sent_response, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_sent_response_ref;
+/** Get number of SIP responses sent by stack.
+ *
+ * Return number of SIP responses given to the transport layer for
+ * transmission by the SIP stack. The number includes retransmissions and
+ * messages which the transport layer failed to send for different reasons.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_RECV_RESPONSE_REF(),
+ * NTATAG_S_SENT_MSG_REF(), NTATAG_S_SENT_REQUEST_REF()
+ */
#define NTATAG_S_SENT_RESPONSE_REF(x)\
ntatag_s_sent_response_ref, tag_usize_vr(&(x))
@@ -651,6 +1831,15 @@
#define NTATAG_S_RETRY_REQUEST(x) ntatag_s_retry_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_retry_request_ref;
+/** Get number of SIP requests retransmitted by stack.
+ *
+ * Return number of SIP requests given to the transport layer for
+ * retransmission by the SIP stack. The number includes messages which the
+ * transport layer failed to send for different reasons.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_SENT_MSG_REF(),
+ * NTATAG_S_SENT_REQUEST_REF(), NTATAG_S_RETRY_RESPONSE_REF()
+ */
#define NTATAG_S_RETRY_REQUEST_REF(x)\
ntatag_s_retry_request_ref, tag_usize_vr(&(x))
@@ -658,6 +1847,15 @@
#define NTATAG_S_RETRY_RESPONSE(x) ntatag_s_retry_response, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_retry_response_ref;
+/** Get number of SIP responses retransmitted by stack.
+ *
+ * Return number of SIP responses given to the transport layer for
+ * retransmission by the SIP stack. The number includes messages which the
+ * transport layer failed to send for different reasons.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_SENT_MSG_REF(),
+ * NTATAG_S_SENT_REQUEST_REF(), NTATAG_S_RETRY_REQUEST_REF()
+ */
#define NTATAG_S_RETRY_RESPONSE_REF(x)\
ntatag_s_retry_response_ref, tag_usize_vr(&(x))
@@ -665,6 +1863,14 @@
#define NTATAG_S_RECV_RETRY(x) ntatag_s_recv_retry, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_recv_retry_ref;
+/** Get number of retransmitted SIP requests received by stack.
+ *
+ * Return number of SIP requests received by the stack. This number only
+ * includes retransmission for which a matching server transaction object
+ * was found.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_RETRY_REQUEST_REF().
+ */
#define NTATAG_S_RECV_RETRY_REF(x)\
ntatag_s_recv_retry_ref, tag_usize_vr(&(x))
@@ -672,6 +1878,12 @@
#define NTATAG_S_TOUT_REQUEST(x) ntatag_s_tout_request, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_tout_request_ref;
+/** Get number of SIP client transactions that has timeout.
+ *
+ * Return number of SIP client transactions that has timeout.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_TOUT_RESPONSE_REF().
+ */
#define NTATAG_S_TOUT_REQUEST_REF(x)\
ntatag_s_tout_request_ref, tag_usize_vr(&(x))
@@ -679,6 +1891,14 @@
#define NTATAG_S_TOUT_RESPONSE(x) ntatag_s_tout_response, tag_usize_v(x)
NTA_DLL extern tag_typedef_t ntatag_s_tout_response_ref;
+/** Get number of SIP server transactions that has timeout.
+ *
+ * Return number of SIP server transactions that has timeout. The number
+ * includes only the INVITE transactions for which the stack has received no
+ * ACK requests.
+ *
+ * @sa nta_agent_get_stats(), NTATAG_S_TOUT_REQUEST_REF().
+ */
#define NTATAG_S_TOUT_RESPONSE_REF(x)\
ntatag_s_tout_response_ref, tag_usize_vr(&(x))
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta.c Mon Aug 20 13:37:13 2007
@@ -70,6 +70,10 @@
#include <assert.h>
#include <unistd.h>
+#if HAVE_OPEN_C
+#include <sys/param.h>
+#endif
+
SOFIAPUBVAR su_log_t nta_log[];
SOFIAPUBVAR su_log_t tport_log[];
@@ -87,6 +91,10 @@
#define NONE ((void *)-1)
+int expensive_checks;
+
+#define EXPENSIVE_CHECKS (expensive_checks)
+
struct sigcomp_compartment;
char const name[] = "test_nta";
@@ -107,6 +115,7 @@
nta_outgoing_t *ag_orq;
int ag_status;
+ unsigned ag_canceled:1, ag_acked:1, :0;
char const *ag_comp;
struct sigcomp_compartment *ag_client_compartment;
@@ -412,6 +421,30 @@
}
}
+void
+nta_test_run_until_acked(agent_t *ag)
+{
+ ag->ag_status = 0;
+ for (ag->ag_acked = 0; !ag->ag_acked;) {
+ if (tstflags & tst_verbatim) {
+ fputs(".", stdout); fflush(stdout);
+ }
+ su_root_step(ag->ag_root, 500L);
+ }
+}
+
+void
+nta_test_run_until_canceled(agent_t *ag)
+{
+ ag->ag_status = 0;
+ for (ag->ag_canceled = 0; !ag->ag_canceled;) {
+ if (tstflags & tst_verbatim) {
+ fputs(".", stdout); fflush(stdout);
+ }
+ su_root_step(ag->ag_root, 500L);
+ }
+}
+
#include <sofia-sip/msg_mclass.h>
int test_init(agent_t *ag, char const *resolv_conf)
@@ -420,13 +453,15 @@
su_sockaddr_t su;
socklen_t sulen, sulen0;
su_socket_t s;
- int af;
+ int af, err = -1;
BEGIN();
- TEST_1(ag->ag_root = su_root_create(ag));
+ ag->ag_root = su_root_create(ag);
+ TEST_1(ag->ag_root);
- TEST_1(ag->ag_mclass = msg_mclass_clone(sip_default_mclass(), 0, 0));
+ ag->ag_mclass = msg_mclass_clone(sip_default_mclass(), 0, 0);
+ TEST_1(ag->ag_mclass);
#if SU_HAVE_IN6
if (str0cmp(getenv("ipv6"), "true") == 0) {
@@ -448,7 +483,7 @@
contact = getenv("SIPCONTACT");
/* Sink server */
- s = socket(af, SOCK_DGRAM, 0); TEST_1(s != INVALID_SOCKET);
+ s = su_socket(af, SOCK_DGRAM, 0); TEST_1(s != INVALID_SOCKET);
memset(&su, 0, sulen = sulen0);
su.su_family = af;
if (getenv("sink")) {
@@ -461,7 +496,7 @@
ag->ag_sink_socket = s;
/* Down server */
- s = socket(af, SOCK_STREAM, 0); TEST_1(s != INVALID_SOCKET);
+ s = su_socket(af, SOCK_STREAM, 0); TEST_1(s != INVALID_SOCKET);
memset(&su, 0, sulen = sulen0);
su.su_family = af;
if (getenv("down")) {
@@ -471,17 +506,18 @@
ag->ag_down_socket = s;
/* Create agent */
- TEST_1(ag->ag_agent = nta_agent_create(ag->ag_root,
- (url_string_t *)contact,
- NULL,
- NULL,
- NTATAG_MCLASS(ag->ag_mclass),
- NTATAG_USE_TIMESTAMP(1),
- SRESTAG_RESOLV_CONF(resolv_conf),
- NTATAG_USE_NAPTR(0),
- NTATAG_USE_SRV(0),
- NTATAG_PRELOAD(2048),
- TAG_END()));
+ ag->ag_agent = nta_agent_create(ag->ag_root,
+ (url_string_t *)contact,
+ NULL,
+ NULL,
+ NTATAG_MCLASS(ag->ag_mclass),
+ NTATAG_USE_TIMESTAMP(1),
+ SRESTAG_RESOLV_CONF(resolv_conf),
+ NTATAG_USE_NAPTR(0),
+ NTATAG_USE_SRV(0),
+ NTATAG_PRELOAD(2048),
+ TAG_END());
+ TEST_1(ag->ag_agent);
{
/* Initialize our headers */
@@ -545,29 +581,32 @@
m->m_next = ag->ag_aliases;
ag->ag_aliases = m;
- TEST(nta_agent_set_params(ag->ag_agent,
- NTATAG_ALIASES(ag->ag_aliases),
- NTATAG_REL100(1),
- NTATAG_UA(1),
- NTATAG_USE_NAPTR(1),
- NTATAG_USE_SRV(1),
- NTATAG_MAX_FORWARDS(20),
- TAG_END()),
- 6);
-
- TEST(nta_agent_set_params(ag->ag_agent,
- NTATAG_ALIASES(ag->ag_aliases),
- NTATAG_DEFAULT_PROXY("sip:127.0.0.1"),
- TAG_END()), 2);
-
- TEST(nta_agent_set_params(ag->ag_agent,
- NTATAG_ALIASES(ag->ag_aliases),
- NTATAG_DEFAULT_PROXY(NULL),
- TAG_END()), 2);
-
- TEST(nta_agent_set_params(ag->ag_agent,
- NTATAG_DEFAULT_PROXY("tel:+35878008000"),
- TAG_END()), -1);
+ err = nta_agent_set_params(ag->ag_agent,
+ NTATAG_ALIASES(ag->ag_aliases),
+ NTATAG_REL100(1),
+ NTATAG_UA(1),
+ NTATAG_USE_NAPTR(1),
+ NTATAG_USE_SRV(1),
+ NTATAG_MAX_FORWARDS(20),
+ TAG_END());
+ TEST(err, 6);
+
+ err = nta_agent_set_params(ag->ag_agent,
+ NTATAG_ALIASES(ag->ag_aliases),
+ NTATAG_DEFAULT_PROXY("sip:127.0.0.1"),
+ TAG_END());
+ TEST(err, 2);
+
+ err = nta_agent_set_params(ag->ag_agent,
+ NTATAG_ALIASES(ag->ag_aliases),
+ NTATAG_DEFAULT_PROXY(NULL),
+ TAG_END());
+ TEST(err, 2);
+
+ err = nta_agent_set_params(ag->ag_agent,
+ NTATAG_DEFAULT_PROXY("tel:+35878008000"),
+ TAG_END());
+ TEST(err, -1);
}
@@ -577,12 +616,13 @@
/* Create the server leg */
*url = *ag->ag_aliases->m_url;
url->url_user = "%";
- TEST_1(ag->ag_server_leg = nta_leg_tcreate(ag->ag_agent,
- leg_callback_200,
- ag,
- NTATAG_NO_DIALOG(1),
- URLTAG_URL(url),
- TAG_END()));
+ ag->ag_server_leg = nta_leg_tcreate(ag->ag_agent,
+ leg_callback_200,
+ ag,
+ NTATAG_NO_DIALOG(1),
+ URLTAG_URL(url),
+ TAG_END());
+ TEST_1(ag->ag_server_leg);
}
END();
@@ -859,7 +899,7 @@
ag->ag_expect_leg = ag->ag_default_leg;
su_free(ag->ag_home, (void *)ag->ag_out_via), ag->ag_out_via = NULL;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg,
outgoing_callback, ag,
ag->ag_obp,
@@ -870,7 +910,8 @@
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
SIPTAG_HEADER_STR(p_acid),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 200);
@@ -900,7 +941,7 @@
ag->ag_expect_leg = ag->ag_default_leg;
su_free(ag->ag_home, (void *)ag->ag_out_via), ag->ag_out_via = NULL;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg,
outgoing_callback, ag,
ag->ag_obp,
@@ -910,7 +951,8 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 200);
@@ -948,7 +990,7 @@
ag->ag_expect_leg = ag->ag_server_leg;
su_free(ag->ag_home, (void *)ag->ag_out_via), ag->ag_out_via = NULL;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -959,7 +1001,8 @@
SIPTAG_TO(ag->ag_alice),
SIPTAG_CONTACT(ag->ag_m_bob),
SIPTAG_PAYLOAD(pl),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
su_free(ag->ag_home, pl);
nta_test_run(ag);
@@ -988,18 +1031,19 @@
TEST_1(pl = test_payload(ag->ag_home, size));
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
- nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
- NULL,
- SIP_METHOD_MESSAGE,
- (url_string_t *)url,
- SIPTAG_SUBJECT_STR("Test 0.2"),
- SIPTAG_FROM(ag->ag_bob),
- SIPTAG_TO(ag->ag_alice),
- SIPTAG_CONTACT(ag->ag_m_bob),
- SIPTAG_PAYLOAD(pl),
- NTATAG_DEFAULT_PROXY(ag->ag_obp),
- TAG_END()));
+ ag->ag_orq =
+ nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
+ NULL,
+ SIP_METHOD_MESSAGE,
+ (url_string_t *)url,
+ SIPTAG_SUBJECT_STR("Test 0.2"),
+ SIPTAG_FROM(ag->ag_bob),
+ SIPTAG_TO(ag->ag_alice),
+ SIPTAG_CONTACT(ag->ag_m_bob),
+ SIPTAG_PAYLOAD(pl),
+ NTATAG_DEFAULT_PROXY(ag->ag_obp),
+ TAG_END());
+ TEST_1(ag->ag_orq);
su_free(ag->ag_home, pl);
nta_test_run(ag);
@@ -1023,17 +1067,18 @@
TEST_1(pl = test_payload(ag->ag_home, size));
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
- nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
- ag->ag_obp,
- SIP_METHOD_MESSAGE,
- (url_string_t *)url,
- SIPTAG_SUBJECT_STR("Test 0.3"),
- SIPTAG_FROM(ag->ag_bob),
- SIPTAG_TO(ag->ag_alice),
- SIPTAG_CONTACT(ag->ag_m_bob),
- SIPTAG_PAYLOAD(pl),
- TAG_END()));
+ ag->ag_orq =
+ nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
+ ag->ag_obp,
+ SIP_METHOD_MESSAGE,
+ (url_string_t *)url,
+ SIPTAG_SUBJECT_STR("Test 0.3"),
+ SIPTAG_FROM(ag->ag_bob),
+ SIPTAG_TO(ag->ag_alice),
+ SIPTAG_CONTACT(ag->ag_m_bob),
+ SIPTAG_PAYLOAD(pl),
+ TAG_END());
+ TEST_1(ag->ag_orq);
su_free(ag->ag_home, pl);
nta_test_run(ag);
@@ -1058,17 +1103,18 @@
su_free(ag->ag_home, (void *)ag->ag_out_via), ag->ag_out_via = NULL;
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
- nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
- ag->ag_obp,
- SIP_METHOD_MESSAGE,
- (url_string_t *)url,
- SIPTAG_SUBJECT_STR("Test 0.4.1"),
- SIPTAG_FROM(ag->ag_bob),
- SIPTAG_TO(ag->ag_alice),
- SIPTAG_CONTACT(ag->ag_m_bob),
- SIPTAG_PAYLOAD(pl),
- TAG_END()));
+ ag->ag_orq =
+ nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
+ ag->ag_obp,
+ SIP_METHOD_MESSAGE,
+ (url_string_t *)url,
+ SIPTAG_SUBJECT_STR("Test 0.4.1"),
+ SIPTAG_FROM(ag->ag_bob),
+ SIPTAG_TO(ag->ag_alice),
+ SIPTAG_CONTACT(ag->ag_m_bob),
+ SIPTAG_PAYLOAD(pl),
+ TAG_END());
+ TEST_1(ag->ag_orq);
su_free(ag->ag_home, pl);
nta_test_run(ag);
@@ -1102,17 +1148,18 @@
su_free(ag->ag_home, ag->ag_in_via), ag->ag_in_via = NULL;
- TEST_1(ag->ag_orq =
- nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
- ag->ag_obp,
- SIP_METHOD_MESSAGE,
- (url_string_t *)url,
- SIPTAG_SUBJECT_STR("Test 0.4.2"),
- SIPTAG_FROM(ag->ag_bob),
- SIPTAG_TO(ag->ag_alice),
- SIPTAG_CONTACT(ag->ag_m_bob),
- SIPTAG_PAYLOAD(pl),
- TAG_END()));
+ ag->ag_orq =
+ nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
+ ag->ag_obp,
+ SIP_METHOD_MESSAGE,
+ (url_string_t *)url,
+ SIPTAG_SUBJECT_STR("Test 0.4.2"),
+ SIPTAG_FROM(ag->ag_bob),
+ SIPTAG_TO(ag->ag_alice),
+ SIPTAG_CONTACT(ag->ag_m_bob),
+ SIPTAG_PAYLOAD(pl),
+ TAG_END());
+ TEST_1(ag->ag_orq);
su_free(ag->ag_home, pl);
nta_test_run(ag);
@@ -1141,18 +1188,19 @@
su_free(ag->ag_home, (void *)ag->ag_out_via), ag->ag_out_via = NULL;
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
- nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
- ag->ag_obp,
- SIP_METHOD_MESSAGE,
- (url_string_t *)url,
- SIPTAG_SUBJECT_STR("Test 0.5"),
- SIPTAG_FROM(ag->ag_bob),
- SIPTAG_TO(ag->ag_alice),
- SIPTAG_CONTACT(ag->ag_m_bob),
- SIPTAG_PAYLOAD(pl),
- TPTAG_MTU(0xffffffff),
- TAG_END()));
+ ag->ag_orq =
+ nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
+ ag->ag_obp,
+ SIP_METHOD_MESSAGE,
+ (url_string_t *)url,
+ SIPTAG_SUBJECT_STR("Test 0.5"),
+ SIPTAG_FROM(ag->ag_bob),
+ SIPTAG_TO(ag->ag_alice),
+ SIPTAG_CONTACT(ag->ag_m_bob),
+ SIPTAG_PAYLOAD(pl),
+ TPTAG_MTU(0xffffffff),
+ TAG_END());
+ TEST_1(ag->ag_orq);
su_free(ag->ag_home, pl);
nta_test_run(ag);
@@ -1184,7 +1232,7 @@
TAG_END());
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg,
magic_callback, ag,
ag->ag_obp,
@@ -1195,7 +1243,8 @@
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
SIPTAG_VIA(via),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1226,7 +1275,7 @@
TEST_1(pl = test_payload(ag->ag_home, size));
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1236,8 +1285,9 @@
SIPTAG_TO(ag->ag_alice),
SIPTAG_CONTACT(ag->ag_m_bob),
SIPTAG_PAYLOAD(pl),
- TAG_END()));
- su_free(ag->ag_home, pl);
+ TAG_END());
+ TEST_1(ag->ag_orq);
+ su_free(ag->ag_home, pl);
nta_test_run(ag);
TEST(ag->ag_status, 200);
@@ -1262,7 +1312,7 @@
ag->ag_expect_leg = ag->ag_server_leg;
ag->ag_latest_leg = NULL;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1272,7 +1322,8 @@
SIPTAG_TO(ag->ag_alice),
SIPTAG_CONTACT(ag->ag_m_bob),
SIPTAG_PAYLOAD(pl),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
su_free(ag->ag_home, pl);
nta_test_run(ag);
@@ -1306,7 +1357,7 @@
ag->ag_expect_leg = ag->ag_server_leg;
ag->ag_latest_leg = NULL;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1315,8 +1366,9 @@
SIPTAG_FROM(ag->ag_bob),
SIPTAG_TO(ag->ag_alice),
SIPTAG_CONTACT(ag->ag_m_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 408);
TEST_P(ag->ag_orq, NULL);
@@ -1388,7 +1440,7 @@
ag->ag_expect_leg = ag->ag_default_leg;
nta_leg_bind(ag->ag_default_leg, leg_callback_destroy, ag);
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg,
outgoing_callback, ag,
ag->ag_obp,
@@ -1397,8 +1449,9 @@
SIPTAG_SUBJECT_STR("Test 3.1"),
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
-
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 500);
TEST_P(ag->ag_orq, NULL);
@@ -1409,7 +1462,7 @@
*/
nta_leg_bind(ag->ag_default_leg, leg_callback_save, ag);
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg,
outgoing_callback, ag,
ag->ag_obp,
@@ -1418,7 +1471,8 @@
SIPTAG_SUBJECT_STR("Test 3.1"),
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 1000);
@@ -1473,7 +1527,7 @@
* Send a message to sip:example.org
*/
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1482,7 +1536,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1495,7 +1551,7 @@
*/
url->url_host = "srv.example.org";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1504,7 +1560,8 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1517,7 +1574,7 @@
*/
url->url_host = "ipv.example.org";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1526,7 +1583,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1539,7 +1598,7 @@
*/
url->url_host = "down.example.org";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1548,8 +1607,10 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
- nta_test_run(ag);
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
+ nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
TEST_P(ag->ag_latest_leg, ag->ag_default_leg);
@@ -1562,7 +1623,7 @@
*/
url->url_host = "na503.example.org";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1571,7 +1632,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 503);
TEST_P(ag->ag_orq, NULL);
@@ -1584,7 +1647,7 @@
*/
url->url_host = "nona.example.org";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1593,7 +1656,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1608,7 +1673,7 @@
*/
url->url_host = "nosrv.example.org";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1617,7 +1682,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1632,7 +1699,7 @@
url->url_host = "srv.example.org";
url->url_params = "transport=tcp";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1641,7 +1708,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1657,7 +1726,7 @@
url->url_host = "srv.example.org";
url->url_params = "transport=udp";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1666,7 +1735,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1682,7 +1753,7 @@
url->url_host = "srv2.example.org";
url->url_params = "transport=udp";
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1691,7 +1762,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1707,7 +1780,7 @@
url->url_host = "srv.example.org";
url->url_port = ag->ag_contact->m_url->url_port;
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1716,7 +1789,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 503);
TEST_P(ag->ag_orq, NULL);
@@ -1731,7 +1806,7 @@
url->url_host = "a.example.org";
url->url_port = ag->ag_contact->m_url->url_port;
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1740,7 +1815,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -1781,7 +1858,7 @@
url->url_host = "down2.example.org";
url->url_port = ag->ag_contact->m_url->url_port;
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -1790,7 +1867,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2192,7 +2271,7 @@
url2->url_port = "9"; /* discard service */
ag->ag_expect_leg = ag->ag_default_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
(url_string_t *)url,
SIP_METHOD_MESSAGE,
@@ -2201,7 +2280,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2223,19 +2304,20 @@
* Alice sends a message to Bob, then Bob back to the Alice, and again
* Alice to Bob.
*/
- TEST_1(ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
+ ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
leg_callback_200,
ag,
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_alice_leg);
TEST_1(nta_leg_tag(ag->ag_alice_leg, NULL));
nta_leg_bind(ag->ag_server_leg, new_leg_callback_200, ag);
/* Send message from Alice to Bob establishing the dialog */
ag->ag_expect_leg = ag->ag_server_leg;
ag->ag_tag_remote = ag->ag_alice_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_alice_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_MESSAGE,
@@ -2244,7 +2326,9 @@
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2255,13 +2339,15 @@
/* Send message from Bob to Alice */
ag->ag_expect_leg = ag->ag_alice_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_bob_leg, outgoing_callback, ag,
NULL,
SIP_METHOD_MESSAGE,
(url_string_t *)ag->ag_m_alice->m_url,
SIPTAG_SUBJECT_STR("Test 2.2"),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2269,13 +2355,15 @@
/* Send again message from Alice to Bob */
ag->ag_expect_leg = ag->ag_bob_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_alice_leg, outgoing_callback, ag,
NULL,
SIP_METHOD_MESSAGE,
(url_string_t *)ag->ag_m_bob->m_url,
SIPTAG_SUBJECT_STR("Test 2.3"),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2286,13 +2374,15 @@
*/
{
ag->ag_expect_leg = ag->ag_alice_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_bob_leg, outgoing_callback, ag,
NULL,
SIP_METHOD_MESSAGE,
(url_string_t *)ag->ag_m_alice->m_url,
SIPTAG_SUBJECT_STR("Test 2.4"),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2578,18 +2668,20 @@
*
* Alice sends a INVITE to Bob, then Bob sends 200 Ok.
*/
- TEST_1(ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
+ ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
alice_leg_callback,
ag,
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_alice_leg);
+
TEST_1(nta_leg_tag(ag->ag_alice_leg, NULL));
nta_leg_bind(ag->ag_server_leg, bob_leg_callback, ag);
/* Send INVITE */
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_call_leg = ag->ag_alice_leg,
outgoing_invite_callback, ag,
ag->ag_obp,
@@ -2602,8 +2694,9 @@
SIPTAG_PAYLOAD(sdp),
NTATAG_USE_TIMESTAMP(1),
NTATAG_PASS_100(1),
- TAG_END()));
-
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
/* Try to CANCEL it immediately */
TEST_1(nta_outgoing_cancel(ag->ag_orq) == 0);
/* As Bob immediately answers INVITE with 200 Ok,
@@ -2628,7 +2721,7 @@
* waits for PRACKs, then sends 200, waits for ACK.
*/
ag->ag_expect_leg = ag->ag_alice_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_call_leg = ag->ag_bob_leg,
outgoing_invite_callback, ag,
NULL,
@@ -2639,7 +2732,8 @@
SIPTAG_SUPPORTED_STR("foo"),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2651,7 +2745,7 @@
/* Send BYE from Bob to Alice */
old_leg = ag->ag_expect_leg = ag->ag_alice_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_bob_leg, outgoing_callback, ag,
NULL,
SIP_METHOD_BYE,
@@ -2662,8 +2756,9 @@
SIPTAG_CONTACT(ag->ag_m_alice),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
-
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -2690,11 +2785,11 @@
if (method == sip_method_ack) {
TEST(method, sip_method_ack);
-
- ag->ag_status = 200;
+ ag->ag_acked = 1;
}
else if (method == sip_method_cancel) {
nta_incoming_treply(irq, SIP_487_REQUEST_CANCELLED, TAG_END());
+ ag->ag_canceled = 1;
}
else {
if (ag->ag_bob_leg) {
@@ -2818,6 +2913,9 @@
orq = tagged;
}
+ if (status > ag->ag_status)
+ ag->ag_status = status;
+
if (status > 100 && status < 200 && sip->sip_rseq) {
nta_outgoing_t *prack;
prack = nta_outgoing_prack(ag->ag_call_leg, orq, NULL, NULL,
@@ -2857,9 +2955,6 @@
nta_outgoing_destroy(ack);
msg_destroy(msg);
}
- else {
- ag->ag_status = status;
- }
TEST_1(sip->sip_to && sip->sip_to->a_tag);
@@ -2876,16 +2971,22 @@
sip_t const *sip)
{
agent_t *ag = (agent_t *)arg;
- if (ag->ag_irq) {
+
+ if (irq) {
+ return 200;
+ }
+ else if (ag->ag_irq) {
nta_incoming_treply(ag->ag_irq,
504, "Reliable Response Timeout",
TAG_END());
nta_incoming_destroy(ag->ag_irq);
+ return 487;
}
- return 504;
+
+ return 487;
}
-/* send invite, wait for 183, send CANCEL */
+/* respond with 183 when receiving invite */
int bob_leg_callback3(agent_t *ag,
nta_leg_t *leg,
nta_incoming_t *irq,
@@ -2931,7 +3032,8 @@
if (sip->sip_request->rq_method != sip_method_invite) {
return 200;
- } else {
+ }
+ else {
nta_reliable_t *rel;
nta_incoming_bind(irq, test_for_ack_or_timeout, ag);
rel = nta_reliable_treply(irq, process_prack, ag,
@@ -3033,7 +3135,7 @@
ag->ag_expect_leg = ag->ag_server_leg;
ag->ag_latest_leg = NULL;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_default_leg, outgoing_callback, ag,
ag->ag_obp,
SIP_METHOD_PRACK,
@@ -3043,25 +3145,29 @@
SIPTAG_TO(ag->ag_bob),
SIPTAG_CONTACT(ag->ag_m_alice),
SIPTAG_RACK_STR("1432432 42332432 INVITE"),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 481);
TEST_P(ag->ag_orq, NULL);
TEST_P(ag->ag_latest_leg, NULL);
}
- TEST_1(ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
+ ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
alice_leg_callback,
ag,
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_alice_leg);
+
TEST_1(nta_leg_tag(ag->ag_alice_leg, NULL));
/* Send INVITE */
nta_leg_bind(ag->ag_server_leg, bob_leg_callback2, ag);
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_call_leg = ag->ag_alice_leg,
invite_prack_callback, ag,
ag->ag_obp,
@@ -3072,8 +3178,10 @@
SIPTAG_REQUIRE_STR("100rel"),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
- nta_test_run(ag);
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
+ nta_test_run_until_acked(ag);
TEST(ag->ag_status, 200);
/*TEST(ag->ag_tag_status, 183);*/
TEST_P(ag->ag_orq, NULL);
@@ -3082,7 +3190,7 @@
/* Send BYE from Bob to Alice */
old_leg = ag->ag_expect_leg = ag->ag_alice_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_bob_leg, outgoing_callback, ag,
NULL,
SIP_METHOD_BYE,
@@ -3093,8 +3201,9 @@
SIPTAG_CONTACT(ag->ag_m_alice),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
-
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
TEST_P(ag->ag_orq, NULL);
@@ -3104,20 +3213,24 @@
nta_leg_destroy(ag->ag_bob_leg), ag->ag_bob_leg = NULL;
ag->ag_latest_leg = NULL;
ag->ag_call_leg = NULL;
+ if (ag->ag_call_tag)
+ su_free(ag->ag_home, (void *)ag->ag_call_tag), ag->ag_call_tag = NULL;
/* Test CANCELing a call after received PRACK */
- TEST_1(ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
+ ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
alice_leg_callback,
ag,
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_alice_leg);
+
TEST_1(nta_leg_tag(ag->ag_alice_leg, NULL));
/* Send INVITE */
nta_leg_bind(ag->ag_server_leg, bob_leg_callback3, ag);
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_call_leg = ag->ag_alice_leg,
invite_183_cancel_callback, ag,
ag->ag_obp,
@@ -3128,7 +3241,9 @@
SIPTAG_REQUIRE_STR("100rel"),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST_1(ag->ag_status == 487 || ag->ag_status == 504);
TEST_P(ag->ag_orq, NULL);
@@ -3139,7 +3254,7 @@
ag->ag_latest_leg = NULL;
ag->ag_call_leg = NULL;
- if (getenv("EXPENSIVE_CHECKS")) {
+ if (EXPENSIVE_CHECKS) {
printf("%s: starting 100rel timeout test, test will complete in 4 seconds\n",
name);
@@ -3148,12 +3263,14 @@
NTATAG_SIP_T1X64(64 * 25),
TAG_END()), 2);
- TEST_1(ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
+ ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
alice_leg_callback,
ag,
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_alice_leg);
+
TEST_1(nta_leg_tag(ag->ag_alice_leg, NULL));
/* Send INVITE,
@@ -3163,7 +3280,7 @@
*/
nta_leg_bind(ag->ag_server_leg, bob_leg_callback2, ag);
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_call_leg = ag->ag_alice_leg,
outgoing_callback, ag,
ag->ag_obp,
@@ -3174,7 +3291,9 @@
SIPTAG_REQUIRE_STR("100rel"),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 503);
TEST_P(ag->ag_orq, NULL);
@@ -3186,14 +3305,60 @@
NTATAG_SIP_T1X64(64 * 500),
TAG_END()), 2);
}
- END();
-/*
+
+ if (EXPENSIVE_CHECKS || 1) {
+ printf("%s: starting timer C, test will complete in 1 seconds\n",
+ name);
+
+ TEST(nta_agent_set_params(ag->ag_agent,
+ NTATAG_TIMER_C(1000),
+ TAG_END()), 1);
+
+ TEST_1(ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
+ alice_leg_callback,
+ ag,
+ SIPTAG_FROM(ag->ag_alice),
+ SIPTAG_TO(ag->ag_bob),
+ TAG_END()));
+ TEST_1(nta_leg_tag(ag->ag_alice_leg, NULL));
+
+ /* Send INVITE,
+ * send precious provisional response
+ * timeout after timer C
+ */
+ nta_leg_bind(ag->ag_server_leg, bob_leg_callback3, ag);
+ ag->ag_expect_leg = ag->ag_server_leg;
+ TEST_1(ag->ag_orq =
+ nta_outgoing_tcreate(ag->ag_call_leg = ag->ag_alice_leg,
+ invite_prack_callback, ag,
+ ag->ag_obp,
+ SIP_METHOD_INVITE,
+ (url_string_t *)ag->ag_m_bob->m_url,
+ SIPTAG_SUBJECT_STR("Call 4"),
+ SIPTAG_CONTACT(ag->ag_m_alice),
+ SIPTAG_REQUIRE_STR("100rel"),
+ SIPTAG_CONTENT_TYPE(c),
+ SIPTAG_PAYLOAD(sdp),
+ TAG_END()));
+ nta_test_run_until_canceled(ag);
+ TEST(ag->ag_status, 408);
+ TEST_1(ag->ag_canceled != 0);
+ TEST_P(ag->ag_orq, NULL);
+ TEST_P(ag->ag_latest_leg, ag->ag_server_leg);
+ TEST_1(ag->ag_bob_leg);
+ nta_leg_destroy(ag->ag_bob_leg), ag->ag_bob_leg = NULL;
+
+ TEST(nta_agent_set_params(ag->ag_agent,
+ NTATAG_TIMER_C(185 * 1000),
+ TAG_END()), 1);
+
nta_leg_destroy(ag->ag_bob_leg), ag->ag_bob_leg = NULL;
ag->ag_latest_leg = NULL;
ag->ag_call_leg = NULL;
if (ag->ag_call_tag)
su_free(ag->ag_home, (void *)ag->ag_call_tag), ag->ag_call_tag = NULL;
-*/
+ }
+ END();
}
int alice_leg_callback2(agent_t *ag,
@@ -3285,12 +3450,14 @@
BEGIN();
- TEST_1(ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
+ ag->ag_alice_leg = nta_leg_tcreate(ag->ag_agent,
alice_leg_callback2,
ag,
SIPTAG_FROM(ag->ag_alice),
SIPTAG_TO(ag->ag_bob),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_alice_leg);
+
TEST_1(nta_leg_tag(ag->ag_alice_leg, NULL));
ag->ag_bob_leg = NULL;
ag->ag_call_tag = NULL;
@@ -3298,7 +3465,7 @@
/* Send INVITE */
nta_leg_bind(ag->ag_server_leg, bob_leg_callback2, ag);
ag->ag_expect_leg = ag->ag_server_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_call_leg = ag->ag_alice_leg,
invite_prack_callback, ag,
ag->ag_obp,
@@ -3309,7 +3476,9 @@
SIPTAG_REQUIRE_STR("100rel"),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
+ TAG_END());
+ TEST_1(ag->ag_orq);
+
nta_test_run(ag);
TEST(ag->ag_status, 200);
/*TEST(ag->ag_tag_status, 183);*/
@@ -3319,7 +3488,7 @@
/* Send BYE from Bob to Alice */
old_leg = ag->ag_expect_leg = ag->ag_alice_leg;
- TEST_1(ag->ag_orq =
+ ag->ag_orq =
nta_outgoing_tcreate(ag->ag_bob_leg, outgoing_callback, ag,
NULL,
SIP_METHOD_BYE,
@@ -3330,8 +3499,8 @@
SIPTAG_CONTACT(ag->ag_m_alice),
SIPTAG_CONTENT_TYPE(c),
SIPTAG_PAYLOAD(sdp),
- TAG_END()));
-
+ TAG_END());
+ TEST_1(ag->ag_orq);
nta_test_run(ag);
TEST(ag->ag_status, 200);
@@ -3365,6 +3534,7 @@
" -v | --verbose be verbose\n"
" -a | --abort abort() on error\n"
" -q | --quiet be quiet\n"
+ " --expensive run expensive tests, too\n"
" -1 quit on first error\n"
" -l level set logging level (0 by default)\n"
" -p uri specify uri of outbound proxy\n"
@@ -3388,6 +3558,8 @@
agent_t ag[1] = {{ { SU_HOME_INIT(ag) }, 0, NULL }};
+ expensive_checks = getenv("EXPENSIVE_CHECKS") != NULL;
+
for (i = 1; argv[i]; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
tstflags |= tst_verbatim;
@@ -3395,6 +3567,8 @@
tstflags |= tst_abort;
else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0)
tstflags &= ~tst_verbatim;
+ else if (strcmp(argv[i], "--expensive") == 0)
+ expensive_checks = 1;
else if (strcmp(argv[i], "-1") == 0)
quit_on_single_failure = 1;
else if (strncmp(argv[i], "-l", 2) == 0) {
@@ -3459,6 +3633,16 @@
}
#endif
+#if HAVE_OPEN_C
+ tstflags |= tst_verbatim;
+ su_log_soft_set_level(su_log_default, 9);
+ su_log_soft_set_level(nta_log, 9);
+ su_log_soft_set_level(tport_log, 9);
+ setenv("SU_DEBUG", "9", 1);
+ setenv("NUA_DEBUG", "9", 1);
+ setenv("NTA_DEBUG", "9", 1);
+ setenv("TPORT_DEBUG", "9", 1);
+#endif
su_init();
if (!(TSTFLAGS & tst_verbatim)) {
@@ -3466,11 +3650,18 @@
su_log_soft_set_level(tport_log, 0);
}
+#if HAVE_OPEN_C
#define SINGLE_FAILURE_CHECK() \
- do { fflush(stdout); \
- if (retval && quit_on_single_failure) { su_deinit(); return retval; } \
- } while(0)
-
+ do { fflush(stdout); \
+ if (retval && quit_on_single_failure) { su_deinit(); sleep(7); return retval; } \
+ } while(0)
+#else
+ #define SINGLE_FAILURE_CHECK() \
+ do { fflush(stdout); \
+ if (retval && quit_on_single_failure) { su_deinit(); return retval; } \
+ } while(0)
+#endif
+
retval |= test_init(ag, argv[i]); SINGLE_FAILURE_CHECK();
if (retval == 0) {
retval |= test_bad_messages(ag); SINGLE_FAILURE_CHECK();
@@ -3490,5 +3681,9 @@
su_deinit();
+#if HAVE_OPEN_C
+ sleep(7);
+#endif
+
return retval;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nta/test_nta_api.c Mon Aug 20 13:37:13 2007
@@ -453,84 +453,129 @@
sip_contact_t const *aliases = (void *)-1;
msg_mclass_t *mclass = (void *)-1;
+ sip_contact_t *contact = (void *)-1;
+ url_string_t const *default_proxy = (void *)-1;
+ void *smime = (void *)-1;
+
+ unsigned blacklist = -1;
+ unsigned debug_drop_prob = -1;
+ unsigned max_forwards = -1;
+ unsigned maxsize = -1;
+ unsigned preload = -1;
+ unsigned progress = -1;
unsigned sip_t1 = -1;
unsigned sip_t2 = -1;
- unsigned sip_t4 = -1;
- unsigned debug_drop_prob = -1;
- int ua = -1;
- int user_via = -1;
+ unsigned sip_t4 = -1;
+ unsigned timer_c = -1;
+ unsigned udp_mtu = -1;
+
+ int cancel_2543 = -1;
+ int cancel_487 = -1;
+ int client_rport = -1;
int extra_100 = -1;
+ int merge_482 = -1;
int pass_100 = -1;
- int timeout_408 = -1;
int pass_408 = -1;
- int merge_482 = -1;
- int cancel_2543 = -1;
- int cancel_487 = -1;
int rel100 = -1;
- int use_timestamp = -1;
+ int server_rport = -1;
+ int stateless = -1;
+ int tag_3261 = -1;
+ int timeout_408 = -1;
+ int ua = -1;
int use_naptr = -1;
int use_srv = -1;
- unsigned preload = (unsigned)-1;
+ int use_timestamp = -1;
+ int user_via = -1;
+
char const *s = NONE;
TEST_1(nta = nta_agent_create(ag->ag_root, (url_string_t *)"sip:*:*",
NULL, NULL, TAG_END()));
TEST(nta_agent_get_params(nta,
- NTATAG_MCLASS_REF(mclass),
NTATAG_ALIASES_REF(aliases),
- NTATAG_SIP_T1_REF(sip_t1),
- NTATAG_SIP_T2_REF(sip_t2),
- NTATAG_SIP_T4_REF(sip_t4),
+ NTATAG_BLACKLIST_REF(blacklist),
+ NTATAG_CANCEL_2543_REF(cancel_2543),
+ NTATAG_CANCEL_487_REF(cancel_487),
+ NTATAG_CLIENT_RPORT_REF(client_rport),
+ NTATAG_CONTACT_REF(contact),
NTATAG_DEBUG_DROP_PROB_REF(debug_drop_prob),
- NTATAG_UA_REF(ua),
- NTATAG_USER_VIA_REF(user_via),
+ NTATAG_DEFAULT_PROXY_REF(default_proxy),
NTATAG_EXTRA_100_REF(extra_100),
+ NTATAG_MAXSIZE_REF(maxsize),
+ NTATAG_MAX_FORWARDS_REF(max_forwards),
+ NTATAG_MCLASS_REF(mclass),
+ NTATAG_MERGE_482_REF(merge_482),
NTATAG_PASS_100_REF(pass_100),
- NTATAG_TIMEOUT_408_REF(timeout_408),
NTATAG_PASS_408_REF(pass_408),
- NTATAG_MERGE_482_REF(merge_482),
- NTATAG_CANCEL_2543_REF(cancel_2543),
- NTATAG_CANCEL_487_REF(cancel_487),
+ NTATAG_PRELOAD_REF(preload),
+ NTATAG_PROGRESS_REF(progress),
NTATAG_REL100_REF(rel100),
- NTATAG_USE_TIMESTAMP_REF(use_timestamp),
+ NTATAG_SERVER_RPORT_REF(server_rport),
+ NTATAG_SIP_T1_REF(sip_t1),
+ NTATAG_SIP_T2_REF(sip_t2),
+ NTATAG_SIP_T4_REF(sip_t4),
+ NTATAG_SMIME_REF(smime),
+ NTATAG_STATELESS_REF(stateless),
+ NTATAG_TAG_3261_REF(tag_3261),
+ NTATAG_TIMEOUT_408_REF(timeout_408),
+ NTATAG_TIMER_C_REF(timer_c),
+ NTATAG_UA_REF(ua),
+ NTATAG_UDP_MTU_REF(udp_mtu),
+ NTATAG_USER_VIA_REF(user_via),
NTATAG_USE_NAPTR_REF(use_naptr),
NTATAG_USE_SRV_REF(use_srv),
+ NTATAG_USE_TIMESTAMP_REF(use_timestamp),
TAG_END()),
- /* Number of parameters */ 19);
+ /* Number of parameters */ 33);
TEST_P(mclass, sip_default_mclass());
TEST_P(aliases, NULL);
+ TEST_1(contact != (void *)-1 && contact != NULL);
+ TEST_1(default_proxy == NULL);
+ TEST_1(smime == NULL);
+
+ TEST_1(blacklist != -1);
+ TEST(debug_drop_prob, 0);
+ TEST_1(max_forwards >= 20);
+ TEST_1(maxsize >= 65536);
+ TEST_1(preload != -1);
+ TEST_1(progress <= 60 * 1000);
TEST(sip_t1, NTA_SIP_T1);
TEST(sip_t2, NTA_SIP_T2);
TEST(sip_t4, NTA_SIP_T4);
- TEST(debug_drop_prob, 0);
- TEST(ua, 0);
- TEST(user_via, 0);
- TEST(extra_100, 0);
- TEST(pass_100, 0);
- TEST(timeout_408, 1);
- TEST(pass_408, 0);
- TEST(merge_482, 0);
- TEST(cancel_2543, 0);
- TEST(cancel_487, 1);
- TEST(rel100, 0);
- TEST(use_timestamp, 0);
- TEST(use_naptr, 1);
- TEST(use_srv, 1);
+ TEST_1(timer_c > 180 * 1000);
+ TEST(udp_mtu, 1300);
+
+ TEST_1(cancel_2543 != -1);
+ TEST_1(cancel_487 != -1);
+ TEST_1(client_rport != -1);
+ TEST_1(extra_100 != -1);
+ TEST_1(merge_482 != -1);
+ TEST_1(pass_100 != -1);
+ TEST_1(pass_408 != -1);
+ TEST_1(rel100 != -1);
+ TEST_1(server_rport != -1);
+ TEST_1(stateless == 0);
+ TEST_1(timeout_408 != -1);
+ TEST_1(ua == 0);
+ TEST_1(use_naptr != -1);
+ TEST_1(use_srv != -1);
+ TEST_1(use_timestamp != -1);
+ TEST_1(user_via == 0);
TEST(nta_agent_set_params(NULL,
- NTATAG_PRELOAD(2048),
- TAG_END()), -1);
+ NTATAG_PRELOAD(2048),
+ TAG_END()), -1);
TEST(nta_agent_get_params(NULL,
- NTATAG_PRELOAD_REF(preload),
- TAG_END()), -1);
+ NTATAG_PRELOAD_REF(preload),
+ TAG_END()), -1);
TEST(nta_agent_set_params(nta,
- NTATAG_PRELOAD(2048),
- TAG_END()), 1);
+ NTATAG_PRELOAD(2048),
+ TAG_END()), 1);
TEST(nta_agent_get_params(nta,
- NTATAG_PRELOAD_REF(preload),
- TAG_END()), 1);
+ NTATAG_PRELOAD_REF(preload),
+ TAG_END()), 1);
TEST(preload, 2048);
TEST(nta_agent_set_params(nta,
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth.docs Mon Aug 20 13:37:13 2007
@@ -6,8 +6,8 @@
*
* NTH provides interface to simple HTTP transaction engines for both HTTP
* servers and clients. The transaction interface for both client and server
- * is available through <nth.h>, tags controlling the options in
- * <nth_tag.h>.
+ * is available through <sofia-sip/nth.h>, tags controlling the options in
+ * <sofia-sip/nth_tag.h>.
*
* @CONTACT Pekka Pessi <Pekka.Pessi(a)nokia.com>
*
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c Mon Aug 20 13:37:13 2007
@@ -174,7 +174,7 @@
* The NTH_DEBUG environment variable is used to determine the debug
* logging level for @b nth module. The default level is 1.
*
- * @sa <su_debug.h>, nth_client_log, #SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, nth_client_log, #SOFIA_DEBUG
*/
extern char const NTH_DEBUG[];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c Mon Aug 20 13:37:13 2007
@@ -172,7 +172,7 @@
* The NTH_DEBUG environment variable is used to determine the debug
* logging level for @b nth module. The default level is 1.
*
- * @sa <su_debug.h>, nth_server_log, SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, nth_server_log, SOFIA_DEBUG
*/
extern char const NTH_DEBUG[];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.c Mon Aug 20 13:37:13 2007
@@ -101,11 +101,11 @@
* NUTAG_URL() \n
* NUTAG_SIPS_URL() \n
* NUTAG_SIP_PARSER() \n
- * NUTAG_UICC() \n
* NUTAG_CERTIFICATE_DIR() \n
- * and all tags listed in nua_set_params(), \n
- * and all relevant NTATAG_* are passed to NTA \n
- * and all tport tags listed in <sofia-sip/tport_tag.h>
+ * all tags listed in nua_set_params(), \n
+ * all NTATAG_* are passed to NTA listed in <sofia-sip/nta_tag.h> \n
+ * all tport tags listed in <sofia-sip/tport_tag.h> \n
+ * STUNTAG_DOMAIN(), STUNTAG_SERVER() \n
*
* @note
* From the @VERSION_1_12_2 all the nua_set_params() tags are processed.
@@ -119,7 +119,7 @@
* @par Events:
* none
*
- * @sa nua_shutdown(), nua_destroy(), nua_handle()
+ * @sa nua_shutdown(), nua_destroy(), nua_handle(), nta_agent_create().
*/
nua_t *nua_create(su_root_t *root,
nua_callback_f callback,
@@ -1040,19 +1040,30 @@
su_msg_destroy(nua->nua_current);
}
-/** Get current request message. @NEW_1_12_4. */
+/** Get current request message. @NEW_1_12_4.
+ *
+ * @note A response message is returned when processing response message.
+ *
+ * @sa #nua_event_e, nua_respond(), NUTAG_WITH_CURRENT()
+ */
msg_t *nua_current_request(nua_t const *nua)
{
return nua && nua->nua_current ? su_msg_data(nua->nua_current)->e_msg : NULL;
}
-/** Get request message from saved nua event. @NEW_1_12_4. */
+/** Get request message from saved nua event. @NEW_1_12_4.
+ *
+ * @sa nua_save_event(), nua_respond(), NUTAG_WITH_SAVED(),
+ */
msg_t *nua_saved_event_request(nua_saved_event_t const *saved)
{
return saved && saved[0] ? su_msg_data(saved)->e_msg : NULL;
}
-/** Save nua event and its arguments */
+/** Save nua event and its arguments.
+ *
+ * @sa #nua_event_e, nua_event_data() nua_saved_event_request(), nua_destroy_event()
+ */
int nua_save_event(nua_t *nua, nua_saved_event_t return_saved[1])
{
if (nua && return_saved) {
@@ -1066,13 +1077,19 @@
return 0;
}
-/** Get event data */
+/** Get event data.
+ *
+ * @sa #nua_event_e, nua_event_save(), nua_saved_event_request(), nua_destroy_event().
+ */
nua_event_data_t const *nua_event_data(nua_saved_event_t const saved[1])
{
return saved ? su_msg_data(saved) : NULL;
}
-/** Destroy saved event */
+/** Destroy saved event.
+ *
+ * @sa #nua_event_e, nua_event_save(), nua_event_data(), nua_saved_event_request().
+ */
void nua_destroy_event(nua_saved_event_t saved[1])
{
if (su_msg_is_non_null(saved)) {
@@ -1136,7 +1153,14 @@
int early_only)
{
if (nh && nh->nh_valid && nh->nh_nua) {
+#if HAVE_OPEN_C
+ struct nua_stack_handle_make_replaces_args a = { NULL, NULL, NULL, 0 };
+ a.nh = nh;
+ a.home = home;
+ a.early_only = early_only;
+#else
struct nua_stack_handle_make_replaces_args a = { NULL, nh, home, early_only };
+#endif
if (su_task_execute(nh->nh_nua->nua_server,
nua_stack_handle_make_replaces_call, (void *)&a,
@@ -1176,7 +1200,14 @@
nua_handle_t *nua_handle_by_replaces(nua_t *nua, sip_replaces_t const *r)
{
if (nua) {
+#if HAVE_OPEN_C
+ struct nua_stack_handle_by_replaces_args a;
+ a.retval = NULL;
+ a.nua = nua;
+ a.r = r;
+#else
struct nua_stack_handle_by_replaces_args a = { NULL, nua, r };
+#endif
if (su_task_execute(nua->nua_server,
nua_stack_handle_by_replaces_call, (void *)&a,
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua.docs Mon Aug 20 13:37:13 2007
@@ -26,18 +26,18 @@
full control to the SIP protocol engine�below it. NUA provides the call
semantics on top of existing transaction semantics found in
<a href="../nta/index.html"><b>nta</b></a> module.
-API makes it possible to create different kind of User Agents,
+With NUA it is possible to create different kind of SIP User Agents,
like terminals, gateways or MCUs.
The @b nua engine hides many low-level signaling and media management
aspects from the application programmer. It is possible to use different
kind of media interfaces - even remote ones - in a fully transparent way.
-The application and the protocol engine within User Agent library can be
-run in separate threads. Communications from the protocol engine is
-conveyed through a callback function. The callback function is called
-within context of the application, so the application must provide
-appropriate handle to a #su_root_t object.
+The application and the protocol engine within User Agent library can be run
+in separate threads. The protocol engine communicates with the application
+using @ref nua_event_e "events", delivered to the application with a a
+callback function. The callback function is called within the thread context
+of the application, represented with a #su_root_t object.
@section nua_concepts_user Sofia Concepts for NUA User
@@ -74,14 +74,14 @@
can access its context information (magic) and thread-synchronization
features like wait objects, timers, and messages.
-An application using NUA services must create a root object and the
-callback routine to handle events. The root object is created with
-su_root_create() function and the callback routine is registered with
+An application using NUA services must create a root object and the callback
+routine to handle @ref nua_event_e "NUA events". The root object is created
+with su_root_create() function and the callback routine is registered with
nua_create() function.
Root object has type #su_root_t.
-See documentation of <su_wait.h> and <su_root.c> for more information
+See documentation of <sofia-sip/su_wait.h> and <su_root.c> for more information
of root object.
See section #nua_event_e for more information of the callback function.
@@ -109,8 +109,8 @@
An application using NUA services can use the memory management services
provided by the SU library but it is not mandatory.
-See documentation of <su_alloc.h> for more information of memory management
-services.
+See documentation of <sofia-sip/su_alloc.h> for more information of memory
+management services.
@subsection nua_tags Tags
@@ -169,14 +169,14 @@
parameters to functions. See nua_invite() for discussion on how a SIP
message is constructed from the tags.
-See documentation of <su_tag.h> for more information of tags and the
+See documentation of <sofia-sip/su_tag.h> for more information of tags and the
module-specific documentation of each Sofia module for information of
tags specific for that module.
@subsection nua_debugandlogging Debugging and Logging
The modules of Sofia stack contain configurable debugging and logging
-functionality based on the services defined in <su_log.h>. The debugging
+functionality based on the services defined in <sofia-sip/su_log.h>. The debugging
and logging details (for example level of details on output and output
file name) can be configured by environment variables, directives in
configuration files and compilation directives in the source files.
@@ -201,7 +201,7 @@
An application using NUA services can also use the debugging and
logging services provided by the Sofia stack but it is not mandatory.
-See documentation of <su_log.h> for more information of debugging and
+See documentation of <sofia-sip/su_log.h> for more information of debugging and
logging services.
@section nua_concepts NUA Concepts
@@ -2089,6 +2089,8 @@
* #nua_r_unregister \n
* #nua_r_unsubscribe \n
* #nua_r_update
+ *
+ * @sa nua_event_is_incoming_request(), nua_event_name()
*/
/** @NUA_EVENT nua_i_chat
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_common.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_common.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_common.c Mon Aug 20 13:37:13 2007
@@ -235,7 +235,7 @@
* ...
* @endcode
*
- * @sa #nua_event_t, nua_respond()
+ * @sa nua_respond(), #nua_event_e, #nua_event_t, nua_event_name()
*
* @NEW_1_12_6
*/
@@ -260,7 +260,10 @@
}
}
-/** Get name for a NUA event. */
+/** Get name for a NUA event.
+ *
+ * @sa #nua_event_e, #nua_event_t, nua_callstate_name(), nua_substate_name()
+ */
char const *nua_event_name(nua_event_t event)
{
switch (event) {
@@ -329,7 +332,10 @@
}
}
-/** Return name of call state */
+/** Return name of call state.
+ *
+ * @sa enum #nua_callstate, nua_event_name(), nua_substate_name()
+ */
char const *nua_callstate_name(enum nua_callstate state)
{
switch (state) {
@@ -348,7 +354,10 @@
}
}
-/** Return name of subscription state. @NEW_1_12_5. */
+/** Return name of subscription state. @NEW_1_12_5.
+ *
+ * @sa enum #nua_substate, nua_event_name(), nua_callstate_name()
+ */
char const *nua_substate_name(enum nua_substate substate)
{
switch (substate) {
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_extension.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_extension.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_extension.c Mon Aug 20 13:37:13 2007
@@ -63,7 +63,7 @@
* NUTAG_METHOD() \n
* NUTAG_URL() \n
* Tags of nua_set_hparams() \n
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_method
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_message.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_message.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_message.c Mon Aug 20 13:37:13 2007
@@ -64,7 +64,7 @@
* @par Related Tags:
* NUTAG_URL() \n
* Tags of nua_set_hparams() \n
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_message
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c Mon Aug 20 13:37:13 2007
@@ -366,7 +366,7 @@
* @par Related Tags:
* NUTAG_SUBSTATE() \n
* Tags of nua_set_hparams() \n
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_notify
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_options.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_options.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_options.c Mon Aug 20 13:37:13 2007
@@ -58,7 +58,7 @@
* nothing
*
* @par Related Tags:
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_options
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c Mon Aug 20 13:37:13 2007
@@ -1088,6 +1088,11 @@
/** Save taglist to a handle */
int nua_handle_save_tags(nua_handle_t *nh, tagi_t *tags)
{
+#if HAVE_OPEN_C
+ /* Nice. An old symbian compiler */
+ tagi_t tagfilter[2];
+ tagi_t paramfilter[2];
+#else
tagi_t const tagfilter[] = {
{ TAG_FILTER(nua_handle_tags_filter) },
{ TAG_NULL() }
@@ -1096,6 +1101,7 @@
{ TAG_FILTER(nua_handle_param_filter) },
{ TAG_NULL() }
};
+#endif
/* Initialization parameters */
url_string_t const *url = NULL;
@@ -1112,6 +1118,18 @@
int error;
+#if HAVE_OPEN_C
+ tagfilter[0].t_tag = tag_filter;
+ tagfilter[0].t_value = tag_filter_v(nua_handle_tags_filter);
+ tagfilter[1].t_tag = (tag_type_t)0;
+ tagfilter[1].t_value = (tag_value_t)0;
+
+ paramfilter[0].t_tag = tag_filter;
+ paramfilter[0].t_value = tag_filter_v(nua_handle_param_filter);
+ paramfilter[1].t_tag = (tag_type_t)0;
+ paramfilter[1].t_value = (tag_value_t)0;
+#endif
+
for (t = tags; t; t = tl_next(t)) {
if (t->t_tag == NULL)
break;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_publish.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_publish.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_publish.c Mon Aug 20 13:37:13 2007
@@ -138,7 +138,7 @@
* @par Related Tags:
* NUTAG_URL() \n
* Tags of nua_set_hparams() \n
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_publish
@@ -196,7 +196,7 @@
* SIPTAG_IF_MATCH(), SIPTAG_IF_MATCH_STR() \n
* SIPTAG_EVENT(), SIPTAG_EVENT_STR() \n
* Tags of nua_set_hparams() \n
- * Tags in <sip_tag.h>
+ * Other header tags defined in <sofia-sip/sip_tag.h> except SIPTAG_EXPIRES() or SIPTAG_EXPIRES_STR()
*
* @par Events:
* #nua_r_unpublish
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c Mon Aug 20 13:37:13 2007
@@ -48,7 +48,7 @@
#include <sofia-sip/sip_util.h>
#include <sofia-sip/sip_status.h>
-#define NTA_UPDATE_MAGIC_T struct nua_handle_s
+#define NTA_UPDATE_MAGIC_T struct nua_s
#include "nua_stack.h"
@@ -516,7 +516,7 @@
*
* @par Related tags:
* NUTAG_REGISTRAR() \n
- * Tags in <sip_tag.h> except SIPTAG_EXPIRES() or SIPTAG_EXPIRES_STR()
+ * Header tags defined in <sofia-sip/sip_tag.h> except SIPTAG_EXPIRES() or SIPTAG_EXPIRES_STR()
*
* @par Events:
* #nua_r_unregister
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c Mon Aug 20 13:37:13 2007
@@ -999,7 +999,7 @@
* nothing
*
* @par Related Tags:
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_i_media_error \n
@@ -1217,7 +1217,7 @@
* nothing
*
* @par Related Tags:
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_cancel, #nua_i_state (#nua_i_active, #nua_i_terminated)
@@ -2714,7 +2714,7 @@
* nothing
*
* @par Related Tags:
- * Tags in <sip_tag.h>.
+ * Header tags defined in <sofia-sip/sip_tag.h>.
*
* @par Events:
* #nua_r_info
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c Mon Aug 20 13:37:13 2007
@@ -781,10 +781,6 @@
if (nua_stack_set_params(nua, nh, nua_i_error, ta_args(ta)) < 0)
retval = -1;
- if (!retval && nh->nh_soa)
- if (soa_set_params(nh->nh_soa, ta_tags(ta)) < 0)
- retval = -1;
-
ta_end(ta);
if (retval || nh->nh_init) /* Already initialized? */
@@ -1338,7 +1334,7 @@
* SOATAG_AF() \n
* SOATAG_HOLD() \n
* Tags used with nua_set_hparams() \n
- * Tags in <sip_tag.h>.
+ * Header tags defined in <sofia-sip/sip_tag.h>.
*
* @par Events:
* #nua_i_state \n
@@ -1445,13 +1441,25 @@
nua_handle_t *nh = sr->sr_owner;
sip_method_t method = sr->sr_method;
struct { msg_t *msg; sip_t *sip; } next = { NULL, NULL };
- tagi_t next_tags[2] = {{ SIPTAG_END() }, { TAG_NEXT(tags) }};
int retval;
+#if HAVE_OPEN_C
+ /* Nice. And old arm symbian compiler; see below. */
+ tagi_t next_tags[2];
+#else
+ tagi_t next_tags[2] = {{ SIPTAG_END() }, { TAG_NEXT(tags) }};
+#endif
msg_t *msg = sr->sr_response.msg;
sip_t *sip = sr->sr_response.sip;
sip_contact_t *m = sr->sr_request.sip->sip_contact;
+#if HAVE_OPEN_C
+ next_tags[0].t_tag = siptag_end;
+ next_tags[0].t_value = (tag_value_t)0;
+ next_tags[1].t_tag = tag_next;
+ next_tags[1].t_value = (tag_value_t)(tags);
+#endif
+
if (sr->sr_response.msg == NULL) {
assert(sr->sr_status == 500);
goto internal_error;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h Mon Aug 20 13:37:13 2007
@@ -62,7 +62,7 @@
#ifndef NUA_DIALOG_H
#define NUA_OWNER_T struct nua_handle_s
-#include <nua_dialog.h>
+#include "nua_dialog.h"
#endif
SOFIA_BEGIN_DECLS
@@ -72,7 +72,7 @@
#endif
#ifndef NUA_PARAMS_H
-#include <nua_params.h>
+#include "nua_params.h"
#endif
typedef struct event_s event_t;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c Mon Aug 20 13:37:13 2007
@@ -138,7 +138,7 @@
*
* @par Related Tags:
* NUTAG_URL()
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_subscribe \n
@@ -164,7 +164,7 @@
*
* @par Related Tags:
* SIPTAG_EVENT() or SIPTAG_EVENT_STR() \n
- * Tags in <sip_tag.h> except SIPTAG_EXPIRES() or SIPTAG_EXPIRES_STR()
+ * Header tags defined in <sofia-sip/sip_tag.h> except SIPTAG_EXPIRES() or SIPTAG_EXPIRES_STR()
*
* @par Events:
* #nua_r_unsubscribe
@@ -401,9 +401,10 @@
/* let nua_base_client_tresponse to remove usage */
cr->cr_terminated = 1;
}
-
+
return nua_base_client_tresponse(cr, status, phrase, sip,
NUTAG_SUBSTATE(substate),
+ SIPTAG_EVENT(du ? du->du_event : NULL),
TAG_END());
}
@@ -727,7 +728,7 @@
* @par Related Tags:
* NUTAG_URL() \n
* Tags of nua_set_hparams() \n
- * Tags in <sip_tag.h>
+ * Header tags defined in <sofia-sip/sip_tag.h>
*
* @par Events:
* #nua_r_refer \n
@@ -852,6 +853,7 @@
nua_stack_tevent(nh->nh_nua, nh, NULL,
cr->cr_event, SIP_100_TRYING,
NUTAG_REFER_EVENT(event),
+ SIPTAG_EVENT(event),
TAG_END());
su_free(nh->nh_home, event);
}
@@ -885,5 +887,6 @@
return nua_base_client_tresponse(cr, status, phrase, sip,
NUTAG_SUBSTATE(substate),
+ SIPTAG_EVENT(du ? du->du_event : NULL),
TAG_END());
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/outbound.c Mon Aug 20 13:37:13 2007
@@ -36,7 +36,7 @@
#define NTA_OUTGOING_MAGIC_T struct outbound
-#include <outbound.h>
+#include "outbound.h"
#include <sofia-sip/hostdomain.h>
#include <sofia-sip/sip.h>
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua.h Mon Aug 20 13:37:13 2007
@@ -172,6 +172,7 @@
/** NUA module version */
SOFIAPUBVAR char const nua_version[];
+/** Typedef of NUA event callback. */
typedef void (*nua_callback_f)(nua_event_t event,
int status, char const *phrase,
nua_t *nua, nua_magic_t *magic,
@@ -349,9 +350,10 @@
/** Check if event can be responded with nua_respond() */
SOFIAPUBFUN int nua_event_is_incoming_request(nua_event_t e);
+/** Cast a #nua_handle_t pointer to a #su_home_t. */
#define nua_handle_home(nh) ((su_home_t *)(nh))
-/** Generate an instance identifier */
+/** Generate an instance identifier. */
SOFIAPUBFUN char const *nua_generate_instance_identifier(su_home_t *);
#ifndef NUA_SAVED_EVENT_T
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_basic_call.c Mon Aug 20 13:37:13 2007
@@ -1105,6 +1105,256 @@
END();
}
+/* ======================================================================== */
+
+/* Call with media upgrade:
+
+ A B
+ |-------INVITE------>|
+ | with audio only |
+ |<----100 Trying-----|
+ | |
+ |<----180 Ringing----|
+ | |
+ |<------200 OK-------|
+ |--------ACK-------->|
+ | |
+ |<------INVITE-------|
+ | with video |
+ |-----100 Trying---->|
+ | |
+ |-------200 OK------>|
+ | with video |
+ |<-------ACK---------|
+ | |
+ |<-------BYE---------|
+ |-------200 OK------>|
+ | |
+
+ Client transitions:
+ INIT -(C1)-> CALLING -(C2a)-> PROCEEDING -(C3+C4)-> READY
+ Server transitions:
+ INIT -(S1)-> RECEIVED -(S2a)-> EARLY -(S3b)-> COMPLETED -(S4)-> READY
+
+ B sends BYE:
+ READY -(T2)-> TERMINATING -(T3)-> TERMINATED
+ A receives BYE:
+ READY -(T1)-> TERMINATED
+
+ See @page nua_call_model in nua.docs for more information
+*/
+int accept_upgrade(CONDITION_PARAMS);
+
+int test_video_call_1(struct context *ctx)
+{
+ BEGIN();
+
+ struct endpoint *a = &ctx->a, *b = &ctx->b;
+ struct call *a_call = a->call, *b_call = b->call;
+ struct event *e;
+ sip_t *sip;
+ sdp_session_t *b_sdp;
+ sdp_media_t *m, b_video[1];
+ sdp_rtpmap_t *rm, b_h261[1];
+
+ sip_time_t se, min_se;
+
+ if (print_headings)
+ printf("TEST NUA-3.6: Basic call\n");
+
+ /* Disable session timer from proxy */
+ test_proxy_get_session_timer(ctx->p, &se, &min_se);
+ test_proxy_set_session_timer(ctx->p, 0, 0);
+
+ a_call->sdp = "m=audio 5008 RTP/AVP 8";
+ b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
+
+ TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
+
+ TEST_1(!nua_handle_has_active_call(a_call->nh));
+ TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
+
+ INVITE(a, a_call, a_call->nh,
+ TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
+ SOATAG_USER_SDP_STR(a_call->sdp),
+ NUTAG_AUTOANSWER(0),
+ TAG_END());
+
+ run_ab_until(ctx, -1, until_ready, -1, accept_call_with_early_sdp);
+
+ TEST_1(nua_handle_has_active_call(a_call->nh));
+ TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
+
+ TEST_1(nua_handle_has_active_call(b_call->nh));
+ TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
+
+ /* Client transitions:
+ INIT -(C1)-> CALLING: nua_invite(), nua_i_state
+ CALLING -(C2)-> PROCEEDING: nua_r_invite, nua_i_state
+ PROCEEDING -(C3+C4)-> READY: nua_r_invite, nua_i_state
+ */
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
+ TEST_1(is_offer_sent(e->data->e_tags));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 180);
+ TEST_1(sip = sip_object(e->data->e_msg));
+ TEST_1(sip->sip_payload);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
+ TEST_1(is_answer_recv(e->data->e_tags));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 200);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, a->events);
+
+ /*
+ Server transitions:
+ INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
+ RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
+ EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state
+ COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
+ */
+ TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
+ TEST(e->data->e_status, 100);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
+ TEST_1(is_offer_recv(e->data->e_tags));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
+ TEST_1(is_answer_sent(e->data->e_tags));
+ TEST_1(tl_find(e->data->e_tags, soatag_local_sdp));
+ TEST_1(b_sdp = sdp_session_dup(nua_handle_home(a_call->nh),
+ (sdp_session_t *)
+ tl_find(e->data->e_tags, soatag_local_sdp)
+ ->t_value));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
+ TEST_1(is_answer_sent(e->data->e_tags));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, b->events);
+
+ a_call->sdp =
+ "m=audio 5008 RTP/AVP 8\n"
+ "m=video 5014 RTP/AVP 34 31\n";
+
+ m = memset(b_video, 0, sizeof b_video);
+ m->m_size = sizeof *m;
+ m->m_session = b_sdp;
+ m->m_type = sdp_media_video, m->m_type_name = "video";
+ m->m_port = 5016;
+ m->m_proto = sdp_proto_rtp; m->m_proto_name = "RTP/AVP";
+ m->m_rtpmaps = memset(rm = b_h261, 0, sizeof b_h261);
+ rm->rm_size = sizeof *rm;
+ rm->rm_pt = 31; rm->rm_encoding = "h261"; rm->rm_rate = 90000;
+
+ b_sdp->sdp_media->m_next = m;
+
+ INVITE(b, b_call, b_call->nh,
+ SOATAG_USER_SDP(b_sdp),
+ TAG_END());
+ run_ab_until(ctx, -1, accept_upgrade, -1, until_ready);
+
+ TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
+ TEST_1(tl_find(e->data->e_tags, soatag_local_sdp_str));
+ TEST_1(strstr((char *)
+ tl_find(e->data->e_tags, soatag_local_sdp_str)->t_value,
+ "m=video"));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
+ TEST(e->data->e_status, 200);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST_1(is_answer_recv(e->data->e_tags));
+ TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, b->events);
+
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
+ TEST(e->data->e_status, 100);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
+ TEST_1(is_offer_recv(e->data->e_tags));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
+ TEST_1(is_answer_sent(e->data->e_tags));
+ TEST_1(tl_find(e->data->e_tags, soatag_local_sdp_str));
+ TEST_1(strstr((char *)
+ tl_find(e->data->e_tags, soatag_local_sdp_str)->t_value,
+ "m=video"));
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, a->events);
+
+ BYE(b, b_call, b_call->nh, TAG_END());
+ run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
+
+ /* B transitions:
+ READY --(T2)--> TERMINATING: nua_bye()
+ TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
+ */
+ TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_r_bye);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, b->events);
+
+ TEST_1(!nua_handle_has_active_call(b_call->nh));
+
+ /* A transitions:
+ READY -(T1)-> TERMINATED: nua_i_bye, nua_i_state
+ */
+ TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_bye);
+ TEST(e->data->e_status, 200);
+ TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
+ TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
+ TEST_1(!e->next);
+ free_events_in_list(ctx, a->events);
+
+ TEST_1(!nua_handle_has_active_call(a_call->nh));
+
+ nua_handle_destroy(a_call->nh), a_call->nh = NULL;
+ nua_handle_destroy(b_call->nh), b_call->nh = NULL;
+
+ test_proxy_set_session_timer(ctx->p, se, min_se);
+
+ if (print_headings)
+ printf("TEST NUA-3.6: PASSED\n");
+
+ END();
+}
+
+int accept_upgrade(CONDITION_PARAMS)
+{
+ if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
+ return 0;
+
+ save_event_in_list(ctx, event, ep, call);
+
+ if (event == nua_i_invite && status < 200) {
+ RESPOND(ep, call, nh, SIP_200_OK,
+ TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
+ TAG_END());
+ return 0;
+ }
+
+ switch (callstate(tags)) {
+ case nua_callstate_ready:
+ return 1;
+ case nua_callstate_terminated:
+ if (call)
+ nua_handle_destroy(call->nh), call->nh = NULL;
+ return 1;
+ default:
+ return 0;
+ }
+}
int test_basic_call(struct context *ctx)
{
@@ -1114,5 +1364,6 @@
|| test_basic_call_3(ctx)
|| test_basic_call_4(ctx)
|| test_basic_call_5(ctx)
+ || test_video_call_1(ctx)
;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c Mon Aug 20 13:37:13 2007
@@ -97,7 +97,10 @@
switch (callstate(tags)) {
case nua_callstate_calling:
- CANCEL(ep, call, nh, TAG_END());
+ CANCEL(ep, call, nh,
+ /* sf.net bug #173323 */
+ SIPTAG_CALL_ID_STR("non-existing-call-id"),
+ TAG_END());
return 0;
case nua_callstate_terminated:
return 1;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_init.c Mon Aug 20 13:37:13 2007
@@ -72,6 +72,7 @@
char const *appl_method = NULL;
url_t const *p_uri, *a_uri, *b_uri; /* Proxy URI */
char const *a_bind, *a_bind2;
+ int err = -1;
url_t b_proxy[1];
a_bind = a_bind2 = "sip:0.0.0.0:*";
@@ -235,13 +236,15 @@
nua_get_params(ctx->a.nua, TAG_ANY(), TAG_END());
run_a_until(ctx, nua_r_get_params, save_until_final_response);
TEST_1(e = ctx->a.specials->head);
- TEST(tl_gets(e->data->e_tags,
- NTATAG_CONTACT_REF(m),
- SIPTAG_FROM_REF(sipaddress),
- SIPTAG_ALLOW_REF(allow),
- NUTAG_APPL_METHOD_REF(appl_method),
- SIPTAG_SUPPORTED_REF(supported),
- TAG_END()), 5); TEST_1(m);
+ err = tl_gets(e->data->e_tags,
+ NTATAG_CONTACT_REF(m),
+ SIPTAG_FROM_REF(sipaddress),
+ SIPTAG_ALLOW_REF(allow),
+ NUTAG_APPL_METHOD_REF(appl_method),
+ SIPTAG_SUPPORTED_REF(supported),
+ TAG_END());
+ TEST(err, 5);
+ TEST_1(m);
TEST_1(ctx->a.contact = sip_contact_dup(ctx->home, m));
TEST_1(ctx->a.to = sip_to_dup(ctx->home, sipaddress));
TEST_1(ctx->a.allow = sip_allow_dup(ctx->home, allow));
@@ -280,13 +283,14 @@
nua_get_params(ctx->b.nua, TAG_ANY(), TAG_END());
run_b_until(ctx, nua_r_get_params, save_until_final_response);
TEST_1(e = ctx->b.specials->head);
- TEST(tl_gets(e->data->e_tags,
- NTATAG_CONTACT_REF(m),
- SIPTAG_FROM_REF(sipaddress),
- SIPTAG_ALLOW_REF(allow),
- NUTAG_APPL_METHOD_REF(appl_method),
- SIPTAG_SUPPORTED_REF(supported),
- TAG_END()), 5); TEST_1(m);
+ err = tl_gets(e->data->e_tags,
+ NTATAG_CONTACT_REF(m),
+ SIPTAG_FROM_REF(sipaddress),
+ SIPTAG_ALLOW_REF(allow),
+ NUTAG_APPL_METHOD_REF(appl_method),
+ SIPTAG_SUPPORTED_REF(supported),
+ TAG_END());
+ TEST(err, 5); TEST_1(m);
TEST_1(ctx->b.contact = sip_contact_dup(ctx->home, m));
TEST_1(ctx->b.to = sip_to_dup(ctx->home, sipaddress));
@@ -317,13 +321,15 @@
nua_get_params(ctx->c.nua, TAG_ANY(), TAG_END());
run_c_until(ctx, nua_r_get_params, save_until_final_response);
TEST_1(e = ctx->c.specials->head);
- TEST(tl_gets(e->data->e_tags,
- NTATAG_CONTACT_REF(m),
- SIPTAG_FROM_REF(sipaddress),
- SIPTAG_ALLOW_REF(allow),
- NUTAG_APPL_METHOD_REF(appl_method),
- SIPTAG_SUPPORTED_REF(supported),
- TAG_END()), 5); TEST_1(m);
+ err = tl_gets(e->data->e_tags,
+ NTATAG_CONTACT_REF(m),
+ SIPTAG_FROM_REF(sipaddress),
+ SIPTAG_ALLOW_REF(allow),
+ NUTAG_APPL_METHOD_REF(appl_method),
+ SIPTAG_SUPPORTED_REF(supported),
+ TAG_END());
+
+ TEST(err, 5); TEST_1(m);
TEST_1(ctx->c.contact = sip_contact_dup(ctx->home, m));
TEST_1(ctx->c.to = sip_to_dup(ctx->home, sipaddress));
TEST_1(ctx->c.allow = sip_allow_dup(ctx->home, allow));
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nat.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nat.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nat.c Mon Aug 20 13:37:13 2007
@@ -79,7 +79,7 @@
} \
extern int LIST_DUMMY_VARIABLE
-#include <test_nat.h>
+#include "test_nat.h"
struct nat {
su_home_t home[1];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.c Mon Aug 20 13:37:13 2007
@@ -117,6 +117,10 @@
struct context ctx[1] = {{{ SU_HOME_INIT(ctx) }}};
+#if HAVE_OPEN_C
+ dup2(1, 2);
+#endif
+
if (getenv("EXPENSIVE_CHECKS"))
o_expensive = 1;
@@ -272,6 +276,25 @@
}
#endif
+#if HAVE_OPEN_C
+ tstflags |= tst_verbatim;
+ level = 9;
+ o_inat = 1; /* No NATs */
+ ctx->threading = 1;
+ ctx->quit_on_single_failure = 1;
+ su_log_soft_set_level(nua_log, level);
+ su_log_soft_set_level(soa_log, level);
+ su_log_soft_set_level(su_log_default, level);
+ su_log_soft_set_level(nea_log, level);
+ su_log_soft_set_level(nta_log, level);
+ su_log_soft_set_level(tport_log, level);
+ setenv("SU_DEBUG", "9", 1);
+ setenv("NUA_DEBUG", "9", 1);
+ setenv("NTA_DEBUG", "9", 1);
+ setenv("TPORT_DEBUG", "9", 1);
+ o_events_a = o_events_b = 1;
+#endif
+
su_init();
if (!(TSTFLAGS & tst_verbatim)) {
@@ -279,6 +302,7 @@
level = 1;
su_log_soft_set_level(nua_log, level);
su_log_soft_set_level(soa_log, level);
+ su_log_soft_set_level(su_log_default, level);
su_log_soft_set_level(nea_log, level);
su_log_soft_set_level(nta_log, level);
su_log_soft_set_level(tport_log, level);
@@ -288,16 +312,28 @@
|| o_events_a || o_events_b || o_events_c)
print_headings = 1;
+#if !HAVE_OPEN_C
#define SINGLE_FAILURE_CHECK() \
do { fflush(stdout); \
if (retval && ctx->quit_on_single_failure) { \
su_deinit(); return retval; } \
} while(0)
+#else
+#define SINGLE_FAILURE_CHECK() \
+ do { fflush(stdout); \
+ if (retval && ctx->quit_on_single_failure) { \
+ su_deinit(); sleep(10); return retval; } \
+ } while(0)
+#endif
ctx->a.printer = o_events_init ? print_event : NULL;
+ sleep(2);
+
retval |= test_nua_api_errors(ctx); SINGLE_FAILURE_CHECK();
+
retval |= test_tag_filter(); SINGLE_FAILURE_CHECK();
+
retval |= test_nua_params(ctx); SINGLE_FAILURE_CHECK();
retval |= test_nua_init(ctx, o_iproxy, o_proxy, o_inat,
@@ -351,5 +387,9 @@
su_deinit();
+#if HAVE_OPEN_C
+ sleep(7);
+#endif
+
return retval;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h Mon Aug 20 13:37:13 2007
@@ -49,13 +49,14 @@
#include <sofia-sip/su_log.h>
#include <sofia-sip/su_tagarg.h>
#include <sofia-sip/su_tag_io.h>
+#include <sofia-sip/nua_tag.h>
#if __APPLE_CC__
#include <sofia-sip/su_osx_runloop.h>
#endif
-#include <test_proxy.h>
-#include <test_nat.h>
+#include "test_proxy.h"
+#include "test_nat.h"
#include <sofia-sip/auth_module.h>
#include <stddef.h>
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_api.c Mon Aug 20 13:37:13 2007
@@ -179,7 +179,8 @@
if (print_headings)
printf("TEST NUA-1.2.2: BYE without INVITE\n");
- TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
+ a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END());
+ TEST_1(a_call->nh);
BYE(a, a_call, a_call->nh, TAG_END());
@@ -203,7 +204,8 @@
if (print_headings)
printf("TEST NUA-1.2.3: unregister without register\n");
- TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(a->to), TAG_END()));
+ a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(a->to), TAG_END());
+ TEST_1(a_call->nh);
UNREGISTER(a, a_call, a_call->nh, TAG_END());
@@ -227,7 +229,8 @@
if (print_headings)
printf("TEST NUA-1.2.4: unpublish without publish\n");
- TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
+ a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END());
+ TEST_1(a_call->nh);
UNPUBLISH(a, a_call, a_call->nh, TAG_END());
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c Mon Aug 20 13:37:13 2007
@@ -83,7 +83,7 @@
} \
extern int LIST_DUMMY_VARIABLE
-#include <test_proxy.h>
+#include "test_proxy.h"
struct proxy {
su_home_t home[1];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c Mon Aug 20 13:37:13 2007
@@ -1180,7 +1180,7 @@
return rv;
for (am = a->sdp_media, bm = b->sdp_media;
- am || bb;
+ am || bm;
am = am->m_next, bm = bm->m_next)
if ((rv = sdp_media_cmp(am, bm)))
return rv;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip.docs Mon Aug 20 13:37:13 2007
@@ -15,7 +15,7 @@
*
* @section sip_overview Overview
*
- * The structure of each header is defined in @b <sip.h>. In addition to the
+ * The structure of each header is defined in @b <sofia-sip/sip.h>. In addition to the
* header structure, there is defined a @em header @em class structure and
* some standard functions for each header in the include file @b
* <sofia-sip/sip_header.h>. For header @c X, there are types, functions,
@@ -68,7 +68,7 @@
* structure. The fragments form a dual-linked list known as @e fragment @e
* chain as shown in the above figure. The buffers for the message, the
* fragment chain, and a whole other stuff is held by the generic message
- * type, #msg_t, defined in <msg.h>. The internal structure of #msg_t is
+ * type, #msg_t, defined in <sofia-sip/msg.h>. The internal structure of #msg_t is
* known only within @b msg module and it is hidden from other modules.
*
* The abstract message module @b msg also drives the reverse process,
@@ -168,7 +168,7 @@
* structure. The @e sip_size indicates the size of the structure - the
* application can extend the parser and #sip_t structure beyond the
* original size. The @e sip_flags contains various flags used during the
- * parsing and printing process. They are documented in the <msg.h>. These
+ * parsing and printing process. They are documented in the <sofia-sip/msg.h>. These
* boilerplate members are followed by the pointers to various message
* elements and headers.
*
@@ -572,14 +572,14 @@
/**@defgroup sip_status_codes SIP Status Codes and Reason Phrases
*
* The macros and variables for the standard SIP status codes and reason
- * phrases are defined in <sip_status.h>.
+ * phrases are defined in <sofia-sip/sip_status.h>.
*/
/**@defgroup sip_tag SIP Tags
*
* SIP headers in tag item lists and tagged argument lists.
*
- * The include file <sip_tag.h> defines tags and tag items for including SIP
+ * The include file <sofia-sip/sip_tag.h> defines tags and tag items for including SIP
* headers in tag item lists or tagged argument lists. For each header,
* there is a tag for pointer to header object and an another tag for string
* containing header value. For example, @From header has tags
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_bad_mask
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_bad_mask (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_bad_mask Mon Aug 20 13:37:13 2007
@@ -1,5 +1,5 @@
#
-# nta has a bad_mask specifying which headers cause nta to automatically
+# nta has an error mask specifying which headers cause nta to automatically
# return 400 Bad Message if a critical header or pseudoheader in a request
# has a parsing error.
#
@@ -7,14 +7,19 @@
#
# See <sip_parser.h> for definition of mask values.
#
-# The mask can be set when header is added with
-# msg_mclass_insert_header_flags().
+# The error flags for a particular header can be set when header is added
+# with msg_mclass_insert_header_flags().
#
# The flags of existing headers can be modified, if a copy of message class
# is first made with msg_mclass_clone().
#
#
+# When updating this file, please update
+# NTATAG_BAD_RESP_MASK()/NTATAG_BAD_REQ_MASK() documentation, too.
+#
+
+#
# Headers that must be valid for all requests
#
request = sip_mask_request | sip_mask_response
@@ -53,7 +58,7 @@
#
Supported = sip_mask_ua | sip_mask_proxy | sip_mask_registrar
Contact = sip_mask_ua | sip_mask_proxy | sip_mask_registrar
-Require = sip_mask_ua | sip_mask_registrar
+Require = sip_mask_ua | sip_mask_registrar | sip_mask_timer
Record-Route = sip_mask_ua | sip_mask_proxy
Expires = sip_mask_registrar | sip_mask_events
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c Mon Aug 20 13:37:13 2007
@@ -802,10 +802,10 @@
}
/** Parse @To or @From headers */
-issize_t sip_addr_d(su_home_t *home,
- sip_header_t *h,
- char *s,
- isize_t slen)
+static issize_t sip_addr_d(su_home_t *home,
+ sip_header_t *h,
+ char *s,
+ isize_t slen)
{
sip_addr_t *a = (sip_addr_t *)h;
char const *comment = NULL;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c Mon Aug 20 13:37:13 2007
@@ -202,6 +202,163 @@
NULL, 1, ei->ei_url, ei->ei_params, NULL);
}
+/* ====================================================================== */
+
+/**@SIP_HEADER sip_alert_info Alert-Info Header
+ *
+ * When present in an INVITE request, the Alert-Info header field
+ * specifies an alternative ring tone to the UAS. When present in a 180
+ * (Ringing) response, the Alert-Info header field specifies an
+ * alternative ringback tone to the UAC. A typical usage is for a proxy
+ * to insert this header field to provide a distinctive ring feature.
+ *
+ * @code
+ * Alert-Info = "Alert-Info" HCOLON alert-param *(COMMA alert-param)
+ * alert-param = LAQUOT absoluteURI RAQUOT *(SEMI generic-param)
+ * @endcode
+ *
+ * The parsed Alert-Info header is stored in #sip_alert_info_t structure.
+ *
+ * @NEW_1_12_7
+ */
+
+/**@ingroup sip_alert_info
+ * @typedef struct sip_alert_info_s sip_alert_info_t;
+ *
+ * The structure #sip_alert_info_t contains representation of an
+ * @AlertInfo header.
+ *
+ * The #sip_alert_info_t is defined as follows:
+ * @code
+ * struct sip_alert_info_s
+ * {
+ * sip_common_t ai_common[1]; // Common fragment info
+ * sip_alert_info_t *ai_next; // Link to next @AlertInfo
+ * url_t ai_url[1]; // URI to alert info
+ * msg_param_t const *ai_params; // List of optional parameters
+ * };
+ * @endcode
+ *
+ * @NEW_1_12_7
+ */
+
+msg_hclass_t sip_alert_info_class[] =
+SIP_HEADER_CLASS(alert_info, "Alert-Info", "",
+ ai_params, append, info);
+
+issize_t sip_alert_info_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
+{
+ return sip_info_d(home, h, s, slen);
+}
+
+issize_t sip_alert_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
+{
+ sip_alert_info_t *ai = (sip_alert_info_t *)h;
+ return sip_name_addr_e(b, bsiz, f, NULL, 1, ai->ai_url, ai->ai_params, NULL);
+}
+
+/* ====================================================================== */
+
+/**@SIP_HEADER sip_reply_to Reply-To Header
+ *
+ * The @b Reply-To header field contains a logical return URI that may be
+ * different from the @From header field. For example, the URI MAY be used to
+ * return missed calls or unestablished sessions. If the user wished to
+ * remain anonymous, the header field SHOULD either be omitted from the
+ * request or populated in such a way that does not reveal any private
+ * information. Its syntax is defined in @RFC3261 as follows:
+ *
+ * @code
+ * Reply-To = "Reply-To" HCOLON rplyto-spec
+ * rplyto-spec = ( name-addr / addr-spec )
+ * *( SEMI rplyto-param )
+ * rplyto-param = generic-param
+ * @endcode
+ *
+ * The parsed Reply-To header is stored in #sip_reply_to_t structure.
+ */
+
+/**@ingroup sip_reply_to
+ * @typedef struct msg_list_s sip_reply_to_t;
+ *
+ * The structure #sip_reply_to_t contains representation of SIP
+ * @ReplyTo header.
+ *
+ * The #sip_reply_to_t is defined as follows:
+ * @code
+ * struct sip_reply_to_s
+ * {
+ * sip_common_t rplyto_common[1]; // Common fragment info
+
+ * sip_error_t *rplyto_next; // Dummy link to next header
+ * char const *rplyto_display; // Display name
+ * url_t rplyto_url[1]; // Return URI
+ * msg_param_t const *rplyto_params; // List of optional parameters
+ * };
+ * @endcode
+ */
+
+static isize_t sip_reply_to_dup_xtra(sip_header_t const *h, isize_t offset);
+static char *sip_reply_to_dup_one(sip_header_t *dst,
+ sip_header_t const *src,
+ char *b,
+ isize_t xtra);
+#define sip_reply_to_update NULL
+
+msg_hclass_t sip_reply_to_class[] =
+ SIP_HEADER_CLASS(reply_to, "Reply-To", "", rplyto_params, single, reply_to);
+
+issize_t sip_reply_to_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
+{
+ sip_reply_to_t *rplyto = (sip_reply_to_t *)h;
+
+ return sip_name_addr_d(home,
+ &s,
+ &rplyto->rplyto_display,
+ rplyto->rplyto_url,
+ &rplyto->rplyto_params,
+ NULL);
+}
+
+issize_t sip_reply_to_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
+{
+ sip_reply_to_t *rplyto = (sip_reply_to_t *)h;
+
+ return sip_name_addr_e(b, bsiz,
+ flags,
+ rplyto->rplyto_display,
+ MSG_IS_CANONIC(flags), rplyto->rplyto_url,
+ rplyto->rplyto_params,
+ NULL);
+}
+
+static isize_t sip_reply_to_dup_xtra(sip_header_t const *h, isize_t offset)
+{
+ sip_reply_to_t const *rplyto = (sip_reply_to_t const *)h;
+
+ MSG_PARAMS_SIZE(offset, rplyto->rplyto_params);
+ offset += MSG_STRING_SIZE(rplyto->rplyto_display);
+ offset += url_xtra(rplyto->rplyto_url);
+
+ return offset;
+}
+
+/**@internal Duplicate one sip_reply_to_t object. */
+static char *sip_reply_to_dup_one(sip_header_t *dst, sip_header_t const *src,
+ char *b, isize_t xtra)
+{
+ sip_reply_to_t *rplyto = (sip_reply_to_t *)dst;
+ sip_reply_to_t const *o = (sip_reply_to_t *)src;
+ char *end = b + xtra;
+
+ b = msg_params_dup(&rplyto->rplyto_params, o->rplyto_params, b, xtra);
+ MSG_STRING_DUP(b, rplyto->rplyto_display, o->rplyto_display);
+ URL_DUP(b, end, rplyto->rplyto_url, o->rplyto_url);
+
+ assert(b <= end);
+
+ return b;
+}
/* ====================================================================== */
@@ -231,7 +388,7 @@
* msg_common_t k_common[1]; // Common fragment info
* msg_list_t *k_next; // Link to next header
* msg_param_t *k_items; // List of call ids
- * } sip_allow_events_t;
+ * } sip_in_reply_to_t;
* @endcode
*/
@@ -249,7 +406,6 @@
return msg_list_e(b, bsiz, h, f);
}
-
/* ====================================================================== */
/**@SIP_HEADER sip_organization Organization Header
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra_headers.txt
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra_headers.txt (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra_headers.txt Mon Aug 20 13:37:13 2007
@@ -9,6 +9,8 @@
#### EXTRA HEADER LIST STARTS HERE ####
refer_sub @NEW_1_12_5 /**< Refer-Sub header */
+alert_info @NEW_1_12_7 /**< Alert-Info header */
+reply_to @NEW_1_12_7 /**< Reply-To header */
#### EXPERIMENTAL HEADER LIST STARTS HERE ####
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_extra.h.in
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_extra.h.in (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_extra.h.in Mon Aug 20 13:37:13 2007
@@ -66,6 +66,33 @@
msg_param_t const *rs_params; /**< List of extension parameters */
};
+typedef struct sip_alert_info_s sip_alert_info_t;
+
+/**@ingroup sip_alert_info
+ * @brief Structure for @AlertInfo header.
+ */
+struct sip_alert_info_s
+{
+ sip_common_t ai_common[1]; /**< Common fragment info */
+ sip_alert_info_t *ai_next; /**< Link to next @AlertInfo */
+ url_t ai_url[1]; /**< URI to alert info */
+ msg_param_t const *ai_params; /**< List of optional parameters */
+};
+
+typedef struct sip_reply_to_s sip_reply_to_t;
+
+/**@ingroup sip_reply_to
+ * @brief Structure for @ReplyTo header.
+ */
+struct sip_reply_to_s
+{
+ sip_common_t rplyto_common[1]; /**< Common fragment info */
+ sip_error_t *rplyto_next; /**< Dummy link to next header */
+ char const *rplyto_display; /**< Display name */
+ url_t rplyto_url[1]; /**< Return URI */
+ msg_param_t const *rplyto_params; /**< List of optional parameters */
+};
+
typedef struct sip_suppress_body_if_match_s sip_suppress_body_if_match_t;
/**@ingroup sip_suppress_body_if_match
@@ -91,6 +118,8 @@
};
+/** Defined as 1 if the @ref sip_#xxxxxx# "#xxxxxxx_xxxxxxx#" is supported */
+#define SIP_HAVE_#XXXXXX# 1
SOFIA_END_DECLS
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_header.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_header.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_header.h Mon Aug 20 13:37:13 2007
@@ -354,21 +354,109 @@
(sip_method_unknown < (method) && (method) < 32 && \
(allow) && ((allow)->k_bitmap & (1 << (method))) != 0)
-/* ---------------------------------------------------------------------------
- * Bitmasks for header classifications
+/**
+ * Bitmasks for header classifications.
+ *
+ * If parsing of a particular header fails, the error bits in #msg_t are
+ * updated. The error bits can be obtained via msg_extract_errors() after
+ * parsing. The header-specific bits are stored along with the
+ * @ref msg_hclass_t "header class" in the #msg_href_t structure, found in
+ * the parser tables of the #msg_mclass_t object.
+ *
+ * @sa NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(),
+ * #msg_mclass_t, struct #msg_mclass_s, msg_mclass_clone(),
+ * msg_mclass_insert_with_mask(),
+ * #msg_href_t, struct #msg_href_s, msg_mclass_insert().
*/
-enum {
- sip_mask_request = 1,
- sip_mask_response = 2,
- sip_mask_ua = 4,
- sip_mask_proxy = 8,
- sip_mask_registrar = 16,
- sip_mask_100rel = 32,
- sip_mask_events = 64,
- sip_mask_timer = 128,
- sip_mask_privacy = 256,
- sip_mask_pref = 512,
- sip_mask_publish = 1024
+enum sip_bad_mask {
+ /** Bit marking essential headers in a request message.
+ *
+ * @ref sip_request \"request line\"", @From, @To, @CSeq, @CallID,
+ * @ContentLength, @Via
+ */
+ sip_mask_request = (1 << 0),
+
+ /** Bit marking essential headers in a response message.
+ *
+ * @ref sip_status \"status line\"", @From, @To, @CSeq, @CallID,
+ * @ContentLength, @Via
+ */
+ sip_mask_response = (1 << 1),
+
+ /** Bit marking essential headers for User-Agent.
+ *
+ * @ContentType, @ContentDisposition, @ContentEncoding, @Supported,
+ * @Contact, @Require, and @RecordRoute.
+ */
+ sip_mask_ua = (1 << 2),
+
+ /** Bit marking essential headers for proxy server.
+ *
+ * @Route, @MaxForwards, @ProxyRequire, @ProxyAuthorization, @Supported,
+ * @Contact, and @RecordRoute.
+ */
+ sip_mask_proxy = (1 << 3),
+
+ /** Bit marking essential headers for registrar server.
+ *
+ * @MinExpires, @Authorization, @Path, @Supported, @Contact, @Require, and
+ * @Expires.
+ *
+ */
+ sip_mask_registrar = (1 << 4),
+
+ /** Bit marking essential headers for 100rel extension.
+ *
+ * @RAck and @RSeq.
+ *
+ * @sa @RFC3262.
+ */
+ sip_mask_100rel = (1 << 5),
+
+ /** Bit marking essential headers for SIP events.
+ *
+ * @Event, @Expires, and @SubscriptionState.
+ *
+ * @sa @RFC3265.
+ */
+ sip_mask_events = (1 << 6),
+
+ /** Bit marking essential headers for session timer extension.
+ *
+ * @SessionExpires, and @MinSE.
+ *
+ * @RFC4028
+ */
+ sip_mask_timer = (1 << 7),
+
+ /** Bit marking essential headers for privacy extension.
+ *
+ * @Privacy.
+ *
+ * @sa @RFC3323
+ */
+ sip_mask_privacy = (1 << 8),
+
+ /** Bit marking essential headers for caller preference extension.
+ *
+ * @RequestDisposition, @AcceptContact, and @RejectContact.
+ *
+ * @sa @RFC3841.
+ */
+ sip_mask_pref = (1 << 9),
+
+ /** Bit marking essential headers for PUBLISH servers and clients.
+ *
+ * @SIPEtag, and @SIPIfMatch.
+ *
+ * @sa @RFC3903.
+ */
+ sip_mask_publish = (1 << 10)
+
+ /* NOTE:
+ * When adding bits, please update nta_agent_create() and
+ * NTATAG_BAD_RESP_MASK()/NTATAG_BAD_REQ_MASK() documentation.
+ */
};
/* ------------------------------------------------------------------------- */
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/torture_sip.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/torture_sip.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sip/torture_sip.c Mon Aug 20 13:37:13 2007
@@ -694,6 +694,40 @@
su_free(home, ci0);
}
+ {
+ sip_alert_info_t *ai, *ai0;
+
+ TEST_1(ai = sip_alert_info_make(home, "<http://www.nokia.com/ringtone.mp3>;x-format=mp3"));
+ TEST_1(ai0 = sip_alert_info_dup(home, ai));
+
+ TEST(msg_header_remove_param(ai->ai_common, "x-format"), 1);
+ TEST(msg_header_remove_param(ai0->ai_common, "x-format"), 1);
+
+ su_free(home, ai);
+ su_free(home, ai0);
+ }
+
+ {
+ sip_reply_to_t *rplyto, *rplyto0;
+
+ TEST_1(rplyto = sip_reply_to_make(home, "sip:joe@bar"));
+ TEST_1(msg_header_add_param(home, (msg_common_t *)rplyto, "x-extra=extra") == 0);
+ while (rplyto->rplyto_params && rplyto->rplyto_params[0])
+ msg_header_remove_param(rplyto->rplyto_common, rplyto->rplyto_params[0]);
+ su_free(home, rplyto);
+
+ TEST_1(!sip_reply_to_make(home, (void *)"sip:joe@[baa"));
+
+ TEST_1(rplyto = sip_reply_to_make(home, (void *)"sip:joe@bar"));
+ su_free(home, rplyto);
+
+ TEST_1(rplyto = sip_reply_to_make(home, (void *)"Joe <sip:joe@bar;user=ip>;x-extra=extra"));
+ TEST_1(rplyto0 = sip_reply_to_dup(home, rplyto));
+ su_free(home, rplyto);
+ su_free(home, rplyto0);
+ }
+
+
su_home_check(home);
su_home_zap(home);
@@ -891,6 +925,8 @@
"Warning: 399 presence.bar:5060 \"Unimplemented filter\"\r\n"
"RSeq: 421414\r\n"
"Refer-To: <sip:hsdf@cdwf.xcfw.com?Subject=test&Organization=Bar>\r\n"
+ "Alert-Info: <http://alert.example.org/test.mp3>\r\n"
+ "Reply-To: Bob <sip:bob@example.com>\r\n"
"WWW-Authenticate: Digest realm=\"foo\"\r\n"
"Proxy-Authenticate: Digest realm=\"foo\"\r\n"
"Security-Server: tls;q=0.2\r\n"
@@ -1555,6 +1591,10 @@
TEST_SIZE(sip_error_info_class->hc_params,
offsetof(sip_error_info_t, ei_params));
+ TEST_SIZE(sip_alert_info_class->hc_params,
+ offsetof(sip_alert_info_t, ai_params));
+ TEST_SIZE(sip_reply_to_class->hc_params,
+ offsetof(sip_reply_to_t, rplyto_params));
TEST_SIZE(sip_warning_class->hc_params, 0);
TEST_SIZE(sip_mime_version_class->hc_params, 0);
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa.c Mon Aug 20 13:37:13 2007
@@ -122,7 +122,7 @@
* The SOA_DEBUG environment variable is used to determine the default
* debug logging level. The normal level is 3.
*
- * @sa <su_debug.h>, su_log_global, SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, su_log_global, SOFIA_DEBUG
*/
extern char const SOA_DEBUG[];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa_tag.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa_tag.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/soa_tag.c Mon Aug 20 13:37:13 2007
@@ -41,6 +41,8 @@
#endif
#include <sofia-sip/soa.h>
+#include <sofia-sip/soa_tag.h>
+
#include <sofia-sip/su_tag_class.h>
#include <sofia-sip/sdp_tag.h>
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/test_soa.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/test_soa.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/soa/test_soa.c Mon Aug 20 13:37:13 2007
@@ -1423,6 +1423,10 @@
usage(1);
}
+#if HAVE_OPEN_C
+ tstflags |= tst_verbatim;
+#endif
+
if (o_attach) {
char line[10];
printf("%s: pid %u\n", name, getpid());
@@ -1462,5 +1466,9 @@
su_deinit();
+#if HAVE_OPEN_C
+ sleep(5);
+#endif
+
return retval;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/Makefile.am (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/Makefile.am Mon Aug 20 13:37:13 2007
@@ -17,11 +17,9 @@
noinst_LTLIBRARIES = libsresolv.la
-check_PROGRAMS = test_sresolv
+check_PROGRAMS = torture_sresolv test_sresolv
-TESTS = run_test_sresolv
-
-TESTS_ENVIRONMENT = $(SHELL)
+TESTS = torture_sresolv run_test_sresolv
CLEANFILES = resolv.conf error.conf named.conf.tmp \
.test_sresolv.api.conf.?????? \
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h Mon Aug 20 13:37:13 2007
@@ -60,7 +60,7 @@
enum {
/** Cache cleanup interval in seconds. */
- SRES_CACHE_TIMER_INTERVAL = 30,
+ SRES_CACHE_TIMER_INTERVAL = 5,
#define SRES_CACHE_TIMER_INTERVAL (SRES_CACHE_TIMER_INTERVAL)
};
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c Mon Aug 20 13:37:13 2007
@@ -557,7 +557,7 @@
* The SRESOLV_DEBUG environment variable is used to determine the debug
* logging level for @b sresolv module. The default level is 3.
*
- * @sa <su_debug.h>, sresolv_log, SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, sresolv_log, SOFIA_DEBUG
*/
#ifdef DOXYGEN
extern char const SRESOLV_DEBUG[]; /* dummy declaration for Doxygen */
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c Mon Aug 20 13:37:13 2007
@@ -65,6 +65,7 @@
#include <sofia-sip/su_alloc.h>
#include <sofia-sip/su_strlst.h>
#include <sofia-sip/htable.h>
+#include <sofia-sip/heap.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -86,19 +87,28 @@
HTABLE_DECLARE_WITH(sres_htable, ht, sres_rr_hash_entry_t, unsigned, size_t);
+typedef HEAP_TYPE sres_heap_t;
+
+HEAP_DECLARE(static inline, sres_heap_t, sres_heap_, sres_rr_hash_entry_t *);
+
struct sres_rr_hash_entry_s {
- unsigned int rr_hash_key;
- time_t rr_received;
sres_record_t *rr;
+ size_t rr_heap_index;
+ time_t rr_expires;
+ unsigned int rr_hash_key;
};
#define SRES_HENTRY_HASH(e) ((e)->rr_hash_key)
+/* ---------------------------------------------------------------------- */
+/* Heap */
+
struct sres_cache
{
su_home_t cache_home[1];
time_t cache_cleaned;
sres_htable_t cache_hash[1];
+ sres_heap_t cache_heap;
};
#define sr_refcount sr_record->r_refcount
@@ -109,7 +119,6 @@
#define sr_class sr_record->r_class
#define sr_ttl sr_record->r_ttl
#define sr_rdlen sr_record->r_rdlen
-#define sr_rdata sr_generic->g_data
/* ---------------------------------------------------------------------- */
/* Internal prototypes */
@@ -126,7 +135,6 @@
HTABLE_PROTOS_WITH(sres_htable, ht, sres_rr_hash_entry_t, unsigned, size_t);
-
/* ---------------------------------------------------------------------- */
/* Public functions */
@@ -140,7 +148,8 @@
if (cache) {
su_home_threadsafe(cache->cache_home);
- if (sres_htable_resize(cache->cache_home, cache->cache_hash, n) < 0)
+ if (sres_htable_resize(cache->cache_home, cache->cache_hash, n) < 0 ||
+ sres_heap_resize(cache->cache_home, &cache->cache_heap, 0) < 0)
su_home_unref(cache->cache_home), cache = NULL;
}
@@ -197,7 +206,7 @@
rr = (*rr_iter)->rr;
if (rr != NULL &&
- (uint32_t)(now - (*rr_iter)->rr_received) <= rr->sr_ttl &&
+ now <= (*rr_iter)->rr_expires &&
(type == sres_qtype_any || rr->sr_type == type) &&
rr->sr_name != NULL &&
strcasecmp(rr->sr_name, domain) == 0)
@@ -224,7 +233,7 @@
rr = (*rr_iter)->rr;
if (rr != NULL &&
- (uint32_t)(now - (*rr_iter)->rr_received) <= rr->sr_ttl &&
+ now <= (*rr_iter)->rr_expires &&
(type == sres_qtype_any || rr->sr_type == type) &&
rr->sr_name != NULL &&
strcasecmp(rr->sr_name, domain) == 0) {
@@ -278,13 +287,13 @@
}
/** Free a record that has not been stored. */
-void sres_cache_free_record(sres_cache_t *cache, void *rr)
+void sres_cache_free_record(sres_cache_t *cache, void *_sr)
{
- sres_record_t *sr = rr;
+ sres_record_t *sr = _sr;
if (sr) {
assert(sr->sr_refcount == 0);
- su_free(cache->cache_home, rr);
+ su_free(cache->cache_home, sr);
}
}
@@ -306,6 +315,12 @@
if (sres_htable_is_full(cache->cache_hash))
sres_htable_resize(cache->cache_home, cache->cache_hash, 0);
+ if (sres_heap_is_full(cache->cache_heap))
+ if (sres_heap_resize(cache->cache_home, &cache->cache_heap, 0) < 0) {
+ UNLOCK(cache);
+ return;
+ }
+
for (rr_iter = sres_htable_hash(cache->cache_hash, hash);
(rr_hash_entry = *rr_iter);
rr_iter = sres_htable_next(cache->cache_hash, rr_iter)) {
@@ -327,10 +342,12 @@
continue;
/* There was an old entry in the cache.. Zap it, replace this with it */
- rr_hash_entry->rr_received = now;
+ sres_heap_remove(cache->cache_heap, rr_hash_entry->rr_heap_index);
+ rr_hash_entry->rr_expires = now + rr->sr_ttl;
rr_hash_entry->rr = rr;
rr->sr_refcount++;
-
+ sres_heap_add(cache->cache_heap, rr_hash_entry);
+
_sres_cache_free_one(cache, or);
UNLOCK(cache);
@@ -339,16 +356,19 @@
}
rr_hash_entry = su_zalloc(cache->cache_home, sizeof(*rr_hash_entry));
+
if (rr_hash_entry) {
rr_hash_entry->rr_hash_key = hash;
- rr_hash_entry->rr_received = now;
+ rr_hash_entry->rr_expires = now + rr->sr_ttl;
rr_hash_entry->rr = rr;
rr->sr_refcount++;
+ sres_heap_add(cache->cache_heap, rr_hash_entry);
+
cache->cache_hash->ht_used++;
+
+ *rr_iter = rr_hash_entry;
}
-
- *rr_iter = rr_hash_entry;
UNLOCK(cache);
}
@@ -417,6 +437,7 @@
return result;
}
+/** Remove entries from cache. */
void sres_cache_clean(sres_cache_t *cache, time_t now)
{
size_t i;
@@ -424,27 +445,56 @@
if (now < cache->cache_cleaned + SRES_CACHE_TIMER_INTERVAL)
return;
- if (!LOCK(cache))
- return;
-
/* Clean cache from old entries */
- cache->cache_cleaned = now;
- for (i = 0; i < cache->cache_hash->ht_size; i++) {
- sres_rr_hash_entry_t *e;
+ for (;;) {
+ if (!LOCK(cache))
+ return;
+
+ cache->cache_cleaned = now;
+
+ for (i = 0; i < 100; i++) {
+ sres_rr_hash_entry_t *e = sres_heap_get(cache->cache_heap, 1);
+
+ if (e == NULL || e->rr_expires >= now) {
+ UNLOCK(cache);
+ return;
+ }
- while ((e = cache->cache_hash->ht_table[i]) != NULL) {
- if ((uint32_t)(now - e->rr_received) <= e->rr->sr_ttl)
- break;
-
+ sres_heap_remove(cache->cache_heap, 1);
sres_htable_remove(cache->cache_hash, e);
-
_sres_cache_free_one(cache, e->rr);
+ su_free(cache->cache_home, e);
}
- }
- UNLOCK(cache);
+ UNLOCK(cache);
+ }
}
HTABLE_BODIES_WITH(sres_htable, ht, sres_rr_hash_entry_t, SRES_HENTRY_HASH,
unsigned, size_t);
+
+static inline
+int sres_heap_earlier_entry(sres_rr_hash_entry_t const *a,
+ sres_rr_hash_entry_t const *b)
+{
+ return a->rr_expires < b->rr_expires;
+}
+
+static inline
+void sres_heap_set_entry(sres_rr_hash_entry_t **heap,
+ size_t index,
+ sres_rr_hash_entry_t *entry)
+{
+ entry->rr_heap_index = index;
+ heap[index] = entry;
+}
+
+HEAP_BODIES(static inline,
+ sres_heap_t,
+ sres_heap_,
+ sres_rr_hash_entry_t *,
+ sres_heap_earlier_entry,
+ sres_heap_set_entry,
+ su_realloc,
+ NULL);
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/test_sresolv.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/test_sresolv.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/sresolv/test_sresolv.c Mon Aug 20 13:37:13 2007
@@ -1152,7 +1152,7 @@
#if HAVE_SIN6
sres_query(res, test_answer_multi, ctx,
- sres_type_aaaa, "mgw02.example.com");
+ sres_type_aaaa, "mgw02.example.com");
inet_pton(AF_INET6,
"3ffe:1200:3012:c000:0a08:20ff:fe7d:e7ac",
@@ -1161,7 +1161,7 @@
sin6.sin6_family = AF_INET6;
query = sres_query_sockaddr(res, test_answer_multi, ctx,
- sres_qtype_any, (struct sockaddr *)&sin6);
+ sres_qtype_any, (struct sockaddr *)&sin6);
TEST_1(query != NULL);
#endif
@@ -1770,97 +1770,6 @@
END();
}
-
-/* Test API function argument validation */
-static
-int test_api_errors(sres_context_t *noctx)
-{
- sres_context_t ctx[1];
- sres_resolver_t *res;
- int s, fd;
- int sockets[20];
- struct sockaddr sa[1] = {{ 0 }};
- char *template = NULL;
- FILE *f;
-
- BEGIN();
-
- memset(ctx, 0, sizeof ctx);
-
- template = su_sprintf(ctx->home, ".test_sresolv_api.conf.XXXXXX");
- TEST_1(template);
-
- TEST_1(res = sres_resolver_new(NULL));
- TEST(su_home_threadsafe((su_home_t *)res), 0);
- TEST_VOID(sres_resolver_unref(res));
-
-#ifndef _WIN32
- fd = mkstemp(template); TEST_1(fd != -1);
-#else
- fd = open(template, O_WRONLY); TEST_1(fd != -1);
-#endif
-
- f = fdopen(fd, "w"); TEST_1(f);
- fprintf(f, "domain example.com\n");
- fclose(f);
-
- /* Test also LOCALDOMAIN handling */
- putenv("LOCALDOMAIN=localdomain");
-
- TEST_1(res = sres_resolver_new(template));
- TEST(su_home_threadsafe((su_home_t *)res), 0);
-
- unlink(template);
-
- s = sockets[0];
-
- TEST_P(sres_resolver_ref(NULL), NULL);
- TEST(errno, EFAULT);
- sres_resolver_unref(NULL);
-
- TEST_P(sres_resolver_set_userdata(NULL, NULL), NULL);
- TEST(errno, EFAULT);
-
- TEST_P(sres_resolver_get_userdata(NULL), NULL);
-
- TEST_P(sres_resolver_get_userdata(res), NULL);
- TEST_P(sres_resolver_set_userdata(res, sa), NULL);
- TEST_P(sres_resolver_get_userdata(res), sa);
- TEST_P(sres_resolver_set_userdata(res, NULL), sa);
- TEST_P(sres_resolver_get_userdata(res), NULL);
-
- errno = 0;
- TEST_P(sres_query(NULL, test_answer, ctx, sres_type_a, "com"), NULL);
- TEST(errno, EFAULT); errno = 0;
- TEST_P(sres_query(res, test_answer, ctx, sres_type_a, NULL), NULL);
- TEST(errno, EFAULT); errno = 0;
- TEST_P(sres_query_sockaddr(res, test_answer, ctx,
- sres_qtype_any, sa), NULL);
- TEST(errno, EAFNOSUPPORT); errno = 0;
-
- TEST_P(sres_cached_answers(NULL, sres_qtype_any, "example.com"), NULL);
- TEST(errno, EFAULT); errno = 0;
- TEST_P(sres_cached_answers(res, sres_qtype_any, NULL), NULL);
- TEST(errno, EFAULT); errno = 0;
- TEST_P(sres_cached_answers(res, sres_qtype_any, name2048), NULL);
- TEST(errno, ENAMETOOLONG); errno = 0;
- TEST_P(sres_cached_answers_sockaddr(res, sres_qtype_any, sa), NULL);
- TEST(errno, EAFNOSUPPORT); errno = 0;
-
- sres_free_answer(res, NULL);
- sres_free_answers(res, NULL);
- sres_sort_answers(res, NULL);
-
- sres_free_answer(NULL, NULL);
- sres_free_answers(NULL, NULL);
- sres_sort_answers(NULL, NULL);
-
- sres_resolver_unref(res);
-
- END();
-}
-
-
static
int test_init(sres_context_t *ctx, char const *conf_file)
{
@@ -2087,8 +1996,6 @@
}
}
- error |= test_api_errors(ctx);
-
return error;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/stun/stun_tag.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/stun/stun_tag.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/stun/stun_tag.c Mon Aug 20 13:37:13 2007
@@ -36,6 +36,7 @@
#define TAG_NAMESPACE "stun"
#include <sofia-sip/su_tag_class.h>
+#include <sofia-sip/stun_tag.h>
/**@def STUNTAG_ANY()
*
@@ -159,7 +160,7 @@
* int (stun_action_t)
*
* @par Values
- * See types for stun_action_t in stun.h
+ * See types for stun_action_t in <sofia-sip/stun.h>
*
* Corresponding tag taking reference parameter is STUNTAG_ACTION_REF()
*/
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Doxyfile.in
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Doxyfile.in (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Doxyfile.in Mon Aug 20 13:37:13 2007
@@ -8,6 +8,7 @@
TAGFILES += ../docs/msg.doxytags=../msg
TAGFILES += ../docs/sip.doxytags=../sip
+TAGFILES += ../docs/utils.doxytags=../utils
TAGFILES += ../docs/docs.doxytags=..
GENERATE_TAGFILE = ../docs/su.doxytags
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Makefile.am (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/Makefile.am Mon Aug 20 13:37:13 2007
@@ -16,23 +16,9 @@
bin_PROGRAMS = addrinfo localinfo
-if COREFOUNDATION
-OSXSOURCES = \
- su_osx_runloop.c
-OSXHEADERS = \
- sofia-sip/su_osx_runloop.h
-OSXPROGS = \
- torture_su_root_osx test_su_osx
-OSXTESTS = \
- torture_su_root_osx run_test_su_osx
-else
-OSXSOURCES =
-OSXHEADERS =
-endif
-
check_PROGRAMS = torture_su torture_su_port \
torture_su_alloc torture_su_time torture_su_tag \
- test_htable torture_rbtree \
+ test_htable torture_rbtree torture_heap \
test_memmem torture_su_bm \
torture_su_root torture_su_timer \
test_su su_proxy test_poll $(OSXPROGS)
@@ -42,7 +28,7 @@
TESTS = torture_su torture_su_port \
torture_su_alloc torture_su_time torture_su_tag \
- test_htable torture_rbtree \
+ test_htable torture_rbtree torture_heap \
test_memmem torture_su_bm \
torture_su_root torture_su_timer \
run_addrinfo run_localinfo run_test_su \
@@ -63,8 +49,8 @@
sofia-sip/su_tag_class.h sofia-sip/su_tagarg.h \
sofia-sip/su_tag_io.h sofia-sip/su_tag_inline.h \
sofia-sip/htable.h sofia-sip/htable2.h \
- sofia-sip/rbtree.h sofia-sip/su_debug.h \
- sofia-sip/su_log.h \
+ sofia-sip/rbtree.h sofia-sip/heap.h \
+ sofia-sip/su_debug.h sofia-sip/su_log.h \
sofia-sip/su_config.h sofia-sip/su_md5.h \
sofia-sip/su_uniqueid.h sofia-sip/su_bm.h \
sofia-sip/tstdef.h sofia-sip/su_os_nw.h \
@@ -122,3 +108,15 @@
# Sofia specific rules
include $(top_srcdir)/rules/sofia.am
+
+# ----------------------------------------------------------------------
+# OS X stuff
+
+if COREFOUNDATION
+OSXSOURCES = su_osx_runloop.c
+OSXHEADERS = sofia-sip/su_osx_runloop.h
+OSXPROGS = torture_su_root_osx test_su_osx
+OSXTESTS = torture_su_root_osx run_test_su_osx
+endif
+
+EXTRA_DIST += su_osx_runloop.c sofia-sip/su_osx_runloop.h
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h Mon Aug 20 13:37:13 2007
@@ -1,7 +1,7 @@
/*
* This file is part of the Sofia-SIP package
*
- * Copyright (C) 2005 Nokia Corporation.
+ * Copyright (C) 2005,2006,2007 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
*
@@ -66,15 +66,14 @@
#if SU_HAVE_WINSOCK /* Windows includes */
# include <winsock2.h>
# include <ws2tcpip.h>
-
-# if defined(IPPROTO_IPV6)
-/* IPv6 defined in ws2tcpip.h */
-# elif SU_HAVE_IN6
-# include <tpipv6.h> /* From "IPv6 Tech Preview" */
-# else
-# error Winsock with IPv6 support required
+# if SU_HAVE_IN6
+# if defined(IPPROTO_IPV6)
+/* case 1: IPv6 defined in winsock2.h/ws2tcpip.h */
+# else
+/* case 2: try to use "IPv6 Tech Preview" */
+# include <tpipv6.h>
+# endif
# endif
-
#endif
SOFIA_BEGIN_DECLS
@@ -95,6 +94,9 @@
/** Return code for an unsuccessful call */
su_failure = -1
};
+#if SYMBIAN && !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL (0)
+#endif
#elif SU_HAVE_WINSOCK
enum {
su_success = 0,
@@ -274,7 +276,9 @@
/** Control socket. */
SOFIAPUBFUN int su_ioctl(su_socket_t s, int request, ...);
-/** Checks if the @a errcode indicates that the socket call failed because
+/**Check for in-progress error codes.
+ *
+ * Checks if the @a errcode indicates that the socket call failed because
* it would have blocked.
*
* Defined as macro with POSIX sockets.
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_config.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_config.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_config.h Mon Aug 20 13:37:13 2007
@@ -36,7 +36,7 @@
*/
#ifndef SU_CONFIGURE_H
-#include "sofia-sip/su_configure.h"
+#include <sofia-sip/su_configure.h>
#endif
#if defined(__GNUC__)
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_configure.h.in
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_configure.h.in (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_configure.h.in Mon Aug 20 13:37:13 2007
@@ -1,7 +1,7 @@
/*
* This file is part of the Sofia-SIP package
*
- * Copyright (C) 2005 Nokia Corporation.
+ * Copyright (C) 2005,2006,2007 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
*
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_time.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_time.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_time.h Mon Aug 20 13:37:13 2007
@@ -73,7 +73,7 @@
*/
typedef uint64_t su_ntp_t;
-/** Represent NTP consttant */
+/** Represent NTP constant */
#define SU_NTP_C(x) SU_U64_C(x)
#define SU_TIME_CMP(t1, t2) su_time_cmp(t1, t2)
@@ -81,6 +81,13 @@
/** Seconds from 1.1.1900 to 1.1.1970. @NEW_1_12_4 */
#define SU_TIME_EPOCH 2208988800UL
+typedef uint64_t su_nanotime_t;
+
+#define SU_E9 (1000000000U)
+
+SOFIAPUBFUN su_nanotime_t su_nanotime(su_nanotime_t *return_time);
+SOFIAPUBFUN su_nanotime_t su_monotime(su_nanotime_t *return_time);
+
SOFIAPUBFUN su_time_t su_now(void);
SOFIAPUBFUN void su_time(su_time_t *tv);
SOFIAPUBFUN long su_time_cmp(su_time_t const t1, su_time_t const t2);
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_types.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_types.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_types.h Mon Aug 20 13:37:13 2007
@@ -34,7 +34,7 @@
*/
#ifndef SU_CONFIG_H
-#include "sofia-sip/su_config.h"
+#include <sofia-sip/su_config.h>
#endif
#if SU_HAVE_STDINT
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_wait.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_wait.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_wait.h Mon Aug 20 13:37:13 2007
@@ -341,6 +341,12 @@
su_timer_t *t,
su_timer_arg_t *arg);
+#ifndef SU_TIMER_QUEUE_T
+#define SU_TIMER_QUEUE_T su_timer_t *
+#endif
+
+typedef SU_TIMER_QUEUE_T su_timer_queue_t;
+
/* ---------------------------------------------------------------------- */
/* Tasks */
@@ -487,7 +493,7 @@
SOFIAPUBFUN su_root_t *su_timer_root(su_timer_t const *);
-SOFIAPUBFUN int su_timer_expire(su_timer_t ** const,
+SOFIAPUBFUN int su_timer_expire(su_timer_queue_t * const,
su_duration_t *tout,
su_time_t now);
@@ -505,7 +511,7 @@
SOFIAPUBFUN int su_task_is_running(su_task_r const);
SOFIAPUBFUN su_root_t *su_task_root(su_task_r const self);
-SOFIAPUBFUN su_timer_t **su_task_timers(su_task_r const self);
+SOFIAPUBFUN su_timer_queue_t *su_task_timers(su_task_r const self);
SOFIAPUBFUN int su_task_execute(su_task_r const task,
int (*function)(void *), void *arg,
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.c Mon Aug 20 13:37:13 2007
@@ -32,9 +32,13 @@
#include "config.h"
-#include "sofia-sip/su.h"
-#include "sofia-sip/su_log.h"
-#include "sofia-sip/su_alloc.h"
+#if HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+
+#include <sofia-sip/su.h>
+#include <sofia-sip/su_log.h>
+#include <sofia-sip/su_alloc.h>
#include <stdio.h>
#include <string.h>
@@ -53,38 +57,194 @@
int su_socket_close_on_exec = 0;
int su_socket_blocking = 0;
-/** Create an endpoint for communication. */
+#if HAVE_OPEN_C && HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#if SU_HAVE_BSDSOCK && HAVE_OPEN_C
+char su_global_ap_name[IFNAMSIZ];
+extern int su_get_local_ip_addr(su_sockaddr_t *su);
+#endif
+
+/** Create a socket endpoint for communication.
+ *
+ * @param af addressing family
+ * @param socktype socket type
+ * @param proto protocol number specific to the addressing family
+ *
+ * The newly created socket is nonblocking unless global variable
+ * su_socket_blocking is set to true.
+ *
+ * Also, the newly created socket is closed on exec() if global variable
+ * su_socket_close_on_exec is set to true. Note that a multithreaded program
+ * can fork() and exec() before the close-on-exec flag is set.
+ *
+ * @return A valid socket descriptor or INVALID_SOCKET (-1) upon an error.
+ */
su_socket_t su_socket(int af, int socktype, int proto)
{
+#if HAVE_OPEN_C
+ struct ifconf ifc;
+ int numifs = 64;
+ char *buffer;
+ struct ifreq ifr;
+ int const su_xtra = 0;
+#endif
+
su_socket_t s = socket(af, socktype, proto);
-#if SU_HAVE_BSDSOCK
+
if (s != INVALID_SOCKET) {
+#if SU_HAVE_BSDSOCK
if (su_socket_close_on_exec)
fcntl(s, F_SETFD, FD_CLOEXEC); /* Close on exec */
+#endif
if (!su_socket_blocking) /* All sockets are born blocking */
su_setblocking(s, 0);
}
+
+#if HAVE_OPEN_C
+ /* Use AP we have raised up */
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, (char const *) su_global_ap_name, IFNAMSIZ);
+
+ /* Assign socket to an already active access point (interface) */
+ ioctl(s, SIOCSIFNAME, &ifr);
+ ioctl(s, SIOCIFSTART, &ifr);
#endif
+
return s;
}
-#if SU_HAVE_BSDSOCK
+#if HAVE_OPEN_C
+#include <errno.h>
+su_sockaddr_t su_ap[1];
+int ifindex;
+void *aConnection;
+extern void *su_localinfo_ap_set(su_sockaddr_t *su, int *index);
+extern int su_localinfo_ap_deinit(void *aconn);
+#define NUMIFS 64
+
+int su_localinfo_ap_name_to_index(int ap_index)
+{
+ struct ifconf ifc;
+
+ struct ifreq *ifr, *ifr_next;
+ int error = EFAULT;
+ char *buffer, buf[NUMIFS * sizeof(struct ifreq)];
+ su_socket_t s;
+
+ s= socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ return -1;
+
+ ifc.ifc_len = NUMIFS * sizeof (struct ifreq);
+
+ memset(buf, 0, ifc.ifc_len);
+ ifc.ifc_buf = buf;
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ return error;
+ }
+
+ buffer = ifc.ifc_buf + ifc.ifc_len;
+
+ for (ifr = ifc.ifc_req;
+ (void *)ifr < (void *)buffer;
+ ifr = ifr_next) {
+ struct ifreq ifreq[1];
+ int scope, if_index, flags = 0, gni_flags = 0;
+ char *if_name;
+ su_sockaddr_t su2[1];
+
+#if SA_LEN
+ if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
+ ifr_next = (struct ifreq *)
+ (ifr->ifr_addr.sa_len + (char *)(&ifr->ifr_addr));
+ else
+#else
+ ifr_next = ifr + 1;
+#endif
+
+ if_name = ifr->ifr_name;
+
+#if defined(SIOCGIFINDEX)
+ ifreq[0] = *ifr;
+ if (ioctl(s, SIOCGIFINDEX, ifreq) < 0) {
+return -1;
+ }
+#if HAVE_IFR_INDEX
+ if_index = ifreq->ifr_index;
+#elif HAVE_IFR_IFINDEX
+ if_index = ifreq->ifr_ifindex;
+#else
+#error Unknown index field in struct ifreq
+#endif
+
+ if (ap_index == if_index)
+ {
+ strncpy(su_global_ap_name, (const char *) if_name, sizeof(su_global_ap_name));
+ error = 0;
+ };
+
+#else
+#error su_localinfo() cannot map interface name to number
+#endif
+
+ }
+
+ close(s);
+ return error;
+}
+#endif
+
+#if SU_HAVE_BSDSOCK || DOCUMENTATION_ONLY
+/** Initialize socket implementation.
+ *
+ * Before using any sofia-sip-ua functions, the application should call
+ * su_init() in order to initialize run-time environment including sockets.
+ * This function may prepare plugins if there are any.
+ *
+ * @par POSIX Implementation
+ * The su_init() initializes debugging logs and ignores the SIGPIPE signal.
+ *
+ * @par Windows Implementation
+ * The function su_init() initializes Winsock2 library on Windows.
+ *
+ * @par Symbian Implementation
+ * The function su_init() prompts user to select an access point (interface
+ * towards Internet) and uses the activated access point for the socket
+ * operations.
+ */
int su_init(void)
{
+#if HAVE_OPEN_C
+ char apname[60];
+ su_socket_t s;
+#endif
+
su_home_threadsafe(NULL);
#if HAVE_SIGPIPE
signal(SIGPIPE, SIG_IGN); /* we want to get EPIPE instead */
#endif
+#if HAVE_OPEN_C
+ /* This code takes care of enabling an access point (interface) */
+ aConnection = su_localinfo_ap_set(su_ap, &ifindex);
+ su_localinfo_ap_name_to_index(ifindex);
+#endif
+
su_log_init(su_log_default);
su_log_init(su_log_global);
return 0;
}
+/** Deinitialize socket implementation. */
void su_deinit(void)
{
+#if HAVE_OPEN_C
+ su_localinfo_ap_deinit(aConnection);
+#endif
}
/** Close an socket descriptor. */
@@ -133,7 +293,7 @@
WSACleanup();
}
-/** Close an socket descriptor. */
+/** Close a socket descriptor. */
int su_close(su_socket_t s)
{
return closesocket(s);
@@ -196,6 +356,14 @@
return -1;
return (issize_t)n;
}
+#elif HAVE_OPEN_C
+issize_t su_getmsgsize(su_socket_t s)
+{
+ int n = -1;
+ if (su_ioctl(s, E32IONREAD, &n) == -1)
+ return -1;
+ return (issize_t)n;
+}
#else
issize_t su_getmsgsize(su_socket_t s)
{
@@ -222,8 +390,9 @@
}
#endif
-#if SU_HAVE_WINSOCK
+#if SU_HAVE_WINSOCK || DOCUMENTATION_ONLY
+/** Call send() with POSIX-compatible signature */
ssize_t su_send(su_socket_t s, void *buffer, size_t length, int flags)
{
if (length > INT_MAX)
@@ -231,6 +400,7 @@
return (ssize_t)send(s, buffer, (int)length, flags);
}
+/** Call sendto() with POSIX-compatible signature */
ssize_t su_sendto(su_socket_t s, void *buffer, size_t length, int flags,
su_sockaddr_t const *to, socklen_t tolen)
{
@@ -240,6 +410,7 @@
&to->su_sa, (int) tolen);
}
+/** Call recv() with POSIX-compatible signature */
ssize_t su_recv(su_socket_t s, void *buffer, size_t length, int flags)
{
if (length > INT_MAX)
@@ -248,6 +419,7 @@
return (ssize_t)recv(s, buffer, (int)length, flags);
}
+/** Call recvfrom() with POSIX-compatible signature */
ssize_t su_recvfrom(su_socket_t s, void *buffer, size_t length, int flags,
su_sockaddr_t *from, socklen_t *fromlen)
{
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.docs
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.docs (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su.docs Mon Aug 20 13:37:13 2007
@@ -17,25 +17,25 @@
*
* The @b su module provides following interfaces for application programs:
*
- * - su_types.h - integral types
- * - su.h - @ref su_socket
- * - su_localinfo.h - get list of local IP addresses
- * - su_wait.h - @ref su_wait
- * - su_time.h - @ref su_time
- * - su_alloc.h - @ref su_alloc
- * - su_log.h - @ref su_log
- * - su_tag.h - @ref su_tag
- * - su_md5.h - @ref su_md5
- * - su_uniqueid.h - @ref su_uniqueid
+ * - <sofia-sip/su_types.h> - integral types
+ * - <sofia-sip/su_alloc.h> - @ref su_alloc memory management
+ * - <sofia-sip/su.h> - @ref su_socket
+ * - <sofia-sip/su_localinfo.h> - get list of local IP addresses
+ * - <sofia-sip/su_wait.h> - @ref su_wait
+ * - <sofia-sip/su_time.h> - @ref su_time
+ * - <sofia-sip/su_log.h> - @ref su_log
+ * - <sofia-sip/su_tag.h> - @ref su_tag
+ * - <sofia-sip/su_md5.h> - @ref su_md5
+ * - <sofia-sip/su_uniqueid.h> - @ref su_uniqueid Unique ID and random number generators
*
* The @b su library also contains some collection datatypes:
- * - htable.h - @ref su_htable
- * - rbtree.h - balanced red-black trees
- * - su_strlst.h - @ref su_strlst
- * - su_vector.h - @ref su_vector
+ * - <sofia-sip/htable.h> - @ref su_htable
+ * - <sofia-sip/rbtree.h> - balanced red-black trees
+ * - <sofia-sip/su_strlst.h> - @ref su_strlst list of strings
+ * - <sofia-sip/su_vector.h> - @ref su_vector dynamic arrays of pointers
*
* There are also some convenience macros for unit test programs:
- * - tstdef.h - macros for unit tests
+ * - sofia-sip/tstdef.h - macros for unit tests
*
* @author Pekka Pessi <Pekka.Pessi(a)nokia.com>
* @author Jari Selin <Jari.Selin(a)nokia.com>
@@ -55,7 +55,7 @@
* developed for Sofia communications software. Currently, interface to
* it consists of following parts:
*
- * - <a href=su_types_h.html>su_types</a> - basic integer types
+ * - <sofia-sip/su_types.h> - basic integer types
* - <a href=group_su_socket.html>su_socket</a> - socket functions
* - <a href=group_su_wait.html>su_wait</a> - synchronization functions
* - <a href=group_su_time.html>su_time</a> - time functions
@@ -74,9 +74,9 @@
/**@defgroup su_socket Socket Functions
*
- * @brief The <su.h> contains the portable socket functions.
+ * @brief The <sofia-sip/su.h> contains the portable socket functions.
*
- * The <su.h> contains following functions, macros, and types:
+ * The <sofia-sip/su.h> contains following functions, macros, and types:
* - su_init(): initializes sockets
* - su_deinit(): deinitializes sockets
* - su_socket(): creates a socket
@@ -84,7 +84,7 @@
* - su_ioctl(): ioctl to a socket
* - su_setreuseaddr(): set/reset reusing the addresses/ports for a socket
* - su_setblocking(): enables/disables blocking
- * - su_isblocking(): checks if the previous call failed because it
+ * - su_is_blocking(): checks if the previous call failed because it
* would have blocked
* - su_errno(): the latest socket error
* - su_perror(): prints the latest socket error message to stderr
@@ -94,6 +94,8 @@
* - su_getmsgsize(): return the number of bytes that can be recv()ed from
* a socket
* - su_getlocalip(): return an IP address belonging to the local host
+ * - su_send(), su_sendto(): type-compatible send()
+ * - su_recv(), su_recvfrom(): type-compatible recv()
* - su_vsend(): scatter-gather send
* - su_vrecv(): scatter-gather receive
* - #su_iovec_t: structure holding scatter-gather IO vector
@@ -107,1246 +109,3 @@
* <sofia-sip/htable.h>. Example code and tests for the implementation is in
* test_htable.c.
*/
-
-
-/* <a name="su_wallclock"></a>
- * <h3>Function @c su_wallclock() - get current time</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_time.h>
- *
- * void su_wallclock(su_time_t *tv);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * Fills the @a tv with the current NTP timestamp.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c tv <td>pointer to the timeval object
- * </table>
- * </blockquote>
- *
- * <a name="su_now"></a>
- * <h3>Function @c su_now() - get current time</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_time.h>
- *
- * su_time_t su_now(void);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * Return the current NTP timestamp.
- * </blockquote>
- *
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * The structure containing the current NTP timestamp.
- * </blockquote>
- *
- * <a name="su_time_print"></a>
- * <h3>Function @c su_time_print() - print an NTP timestamp</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_time.h>
- *
- * int su_time_print(char *s, int n, su_time_t const *tv);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * This function prints an NTP timestamp as a decimal number to the
- * given buffer.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c char *s <td>pointer to buffer
- * <tr><td>@c int n <td>buffer size
- * <tr><td>@c su_time_t const tv <td>pointer to the timeval object
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * The number of characters printed, excluding the final NUL.
- * </blockquote>
- *
- * <a name="su_duration"></a>
- * <h3>Function @c su_duration() - return time difference in milliseconds</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_time.h>
- *
- * su_duration_t su_duration(su_time_t t1, su_time_t t2);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * Calculates the duration in milliseconds from @a t2 to @a t1 in milliseconds. If the difference is bigger
- * than @c SU_MAX_DURATION, return @c SU_MAX_DURATION instead.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c t1 <td>after time
- * <tr><td>@c t2 <td>before time
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * The duration in milliseconds between the two times.
- * </blockquote>
- *
- * <a name="su_alloc.h"></a>
- * <h1><su_alloc.h></h1>
- *
- * This section describes memory management functions.
- *
- *
- * The
- * @c su_alloc library provides convenience functions for
- * memory management. The library defines an object @c su_home_t for
- * collecting multiple memory allocations under one handle.
- *
- * <ul>
- * - Function @c su_home_create()
- * - create an su_home_t object
- *
- * - Function @c su_home_destroy()
- * - free a home object
- *
- * - Function @c su_alloc()
- * - allocate a memory block
- *
- * - Function @c su_zalloc()
- * - allocate and zero a memory block
- *
- * - Function @c su_salloc()
- * - allocate a structure
- *
- * - Function @c su_free()
- * - free a memory block
- *
- * </ul>
- *
- *
- * The functions for implementing objects derived from @c su_home_t
- * are as follows:
- * <ul>
- * - Function @c su_home_init()
- * - initialize an @c su_home_t object
- *
- * - Function @c su_home_deinit()
- * - free memory blocks from home
- *
- * </ul>
- *
- * <a name="su_home_create"></a>
- * <h3>Function @c su_home_create() - create an su_home_t object</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * su_home_t *su_home_create(void);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function @c su_home_create() creates a home object used to
- * collect multiple memory allocations under one handle, so that they can be
- * freed by calling <dfn>su_home_destroy()</dfn>.
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * This function returns a pointer to an @c su_home_t object, or
- * @c NULL upon an error.
- * </blockquote>
- *
- * <a name="su_home_destroy"></a>
- * <h3>Function @c su_home_destroy() - free a home object</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * void su_home_destroy(su_home_t *h);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function @c su_home_destroy() frees a home object, and all
- * memory blocks associated with it.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c su_home_t *h <td>pointer to a home object
- * </table>
- * </blockquote>
- *
- * <a name="su_alloc"></a>
- * <h3>Function @c su_alloc() - allocate a memory block</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * void *su_alloc(su_home_t *h, int n);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function @c su_alloc() allocates a memory block of a given size.
- *
- *
- * If @a h is @c NULL, this function behaves exactly like
- * @c malloc().
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c su_home_t *h <td>pointer to a home object
- * <tr><td>@c int n <td>size of the memory block to be allocated
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * This function returns a pointer to the allocated memory block, or
- * @c NULL, if an error occurred.
- * </blockquote>
- *
- * <a name="su_zalloc"></a>
- * <h3>Function @c su_zalloc() - allocate and zero a memory block</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * void *su_zalloc(su_home_t *h, int n)
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function @c su_zalloc() allocates a memory block with a given
- * size and zeroes the allocated block.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c su_home_t *h <td>pointer to a home object
- * <tr><td>@c int n <td>size of the memory block to be allocated
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * This function returns a pointer to the allocated memory block, or
- * @c NULL, if an error occurred.
- * </blockquote>
- *
- * <a name="su_salloc"></a>
- * <h3>Function @c su_salloc() - allocate a structure</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * void *su_salloc(su_home_t *h, int s);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function su_salloc() allocates a structure with a given size,
- * zeros it, and initializes the size field to the given size.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c su_home_t *h <td>pointer to a home object
- * <tr><td>@c int n <td>size of the structure to be allocated
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * This function returns a pointer to the allocated memory block, or
- * @c NULL, if an error occurred.
- * </blockquote>
- *
- * <a name="su_free"></a>
- * <h3>Function @c su_free() - free a memory block</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * void su_free(su_home_t *h, void *vb);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function @c su_free() frees a single memory block.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c su_home_t *h <td>pointer to a home object
- * <tr><td>@c void *vb <td>pointer to the memory block to be freed
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * </blockquote>
- *
- * <a name="su_home_init"></a>
- * <h3>Function @c su_home_init() - initialize an @c su_home_t object</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * int su_home_init(su_home_t *h);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function @c su_home_init() initializes an object derived from
- * @c su_home_t. It checks that the @a suh_size field is valid.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c su_home_t *h <td>pointer to a home object
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * The function @c su_home_init() returns @c 0 when
- * successful, or @c -1 upon an error.
- * </blockquote>
- *
- * <h4>Note</h4>
- * <blockquote><strong>This is an internal function, and it is intended for
- * implementing the objects derived from @c su_home_t.</strong>
- * </blockquote>
- *
- * <a name="su_home_deinit"></a>
- * <h3>Function @c su_home_deinit() - free memory blocks from home </h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_alloc.h>
- *
- * void su_home_deinit(su_home_t *h);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * The function @c su_home_deinit() frees the memory blocks
- * associated with the home object.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c su_home_t *h <td>pointer to a home object
- * </table>
- * </blockquote>
- *
- * <h4>Note</h4>
- * <blockquote><strong>This is an internal function, and it is intended for
- * implementing the objects derived from @c su_home_t.</strong>
- * </blockquote>
- *
- *
- * <a name="su_wait.h"></a>
- * <h1><su_wait.h></h1>
- *
- * This section describes synchronization functionality.
- * The @c su_wait library provides portable synchronization
- * primitives needed for running communication software.
- *
- * Synchronization means that the program can stop waiting for events,
- * set callback functions for events, schedule timers, and set callback
- * functions for timers. In other words, it is an OS-independent
- * @c poll()/@c select()/@c WaitForMultipleObjects()
- * interface, spiced up with timer interface.
- *
- * The library provides three kinds of objects: root
- * objects (@c su_root_t), wait objects
- * (@c su_wait_t), and timer objects
- * (@c su_timer_t).
- *
- * <a name="wait"></a>
- * <h2>Wait Objects</h2>
- *
- *
- * Wait objects are used to signal I/O events to the process.
- * The events are as follows:
- *
- * <dl>
- * <dt>SU_WAIT_IN
- * <dd>incoming data is available
- *
- * <dt>SU_WAIT_OUT
- * <dd>data can be output
- *
- * <dt>SU_WAIT_ERR
- * <dd>an error occurred
- *
- * <dt>SU_WAIT_HUP
- * <dd>the socket connection was closed
- *
- * <dt>SU_WAIT_ACCEPT
- * <dd>a listening socket accepted a new connection attempt
- * </dl>
- *
- *
- * It is possible to combine several events with |, binary or operator.
- *
- *
- * Public API contains functions as follows:
- * <ul>
- * - su_wait_create()
- * - su_wait_destroy()
- * - su_wait()
- * - su_wait_events()
- * </ul>
- *
- *
- * In Unix, the wait object is @c struct poll. The structure contains a file
- * handle, a mask describing expected events, and a mask containing the
- * occurred events after calling @c poll(), ie. @c su_wait().
- *
- *
- * In Windows, the wait object is a @c HANDLE (a descriptor of a Windows
- * kernel entity).
- *
- *
- * <a name="su_wait_create"></a>
- * <h3>Function @c su_wait_create()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_wait_create(su_wait_t *newwait, su_socket_t socket, int events)</pre></blockquote>
- *
- * <h4>Description</h4>
- *
- * <blockquote>
- * @c Su_wait_create() creates a new wait object for a
- * @a socket with given @a events. The new wait object is
- * assigned to the @a newwait parameter.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- *
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c newwait<td>the newly created wait object
- * <tr><td>@c socket <td>socket descriptor
- * <tr><td>@c events <td>mask for events that can signal this wait object
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- *
- * <blockquote>
- * 0 if the call was successful, -1 otherwise.
- * </blockquote>
- *
- * <a name="su_wait_destroy"></a>
- * <h3>Function @c su_wait_destroy()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre> #include <su_wait.h>
- *
- * int su_wait_destroy(su_wait_t *waitobj);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>Destroy a wait object.
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- *
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c waitobj <td>pointer to wait object
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- *
- * <blockquote>
- * 0 when successful, -1 upon an error.
- * </blockquote>
- *
- * <a name="su_wait"></a>
- * <h3>Function @c su_wait()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_wait(su_wait_t waits[], unsigned n, long timeout);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Block until a event specified by wait objects or a timeout occurs.
- *
- *
- * In Unix, this is poll.
- *
- *
- * In Windows, this is WSAWaitForMultipleEvents
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c waits <td>array of wait objects
- * <tr><td>@c n <td>number of wait objects in array waits
- * <tr><td>@c timeout <td>timeout in milliseocnds
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * Index of the signaled wait object, if any, SU_WAIT_TIMEOUT if timeout
- * occurred, and -1 upon an error.
- * </blockquote>
- *
- * <a name="su_wait_events"></a>
- * <h3>Function @c su_wait_events()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_wait_events(su_wait_t *waitobj, su_socket_t s);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Return an mask describing events occurred.
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c waitobj <td>pointer to wait object
- * <tr><td>@c s <td>socket
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> Binary mask describing the events.
- * </blockquote>
- *
- * <a name="su_wait_mask"></a>
- * <h3>Function @c su_wait_mask()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_wait_mask(su_wait_t *waitobj, su_socket_t s, int events);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote>
- * Sets the mask describing events that can signal the wait object.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c waitobj <td>pointer to wait object
- * <tr><td>@c s <td>socket
- * <tr><td>@c events <td>new event mask
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * 0 when successful, -1 upon an error.
- * </blockquote>
- *
- * <a name="root"></a>
- * <h2>Root objects</h2>
- *
- *
- * Root object is a structure containing a list of wait objects,
- * associated callback functions, and arguments to these functions.
- * It can also contain a list of timers, and a magic cookie (a pointer
- * defined by root object user.)
- *
- *
- * The public API contains following functions:
- * <ul>
- * - su_root_create()
- * - su_root_destroy()
- * - su_root_magic()
- * - su_root_register()
- * - su_root_unregister()
- * - su_root_run()
- * - su_root_break()
- * - su_root_step()
- * </ul>
- *
- * These functions are intended for implementing su_root API:
- * <ul>
- * - su_root_init()
- * - su_root_deinit()
- * - su_root_query()
- * - su_root_event()
- * </ul>
- *
- * <a name="su_root_create"></a>
- * <h3>Function @c su_root_create()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * su_root_t *su_root_create(su_root_magic_t *magic);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Allocate and initialize an instance of su_root_t
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c magic <td>pointer to user data
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> A pointer to allocated su_root_t instance, NULL on error.
- * </blockquote>
- *
- *
- * <a name="su_root_destroy"></a>
- * <h3>Function @c su_root_destroy()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * void su_root_destroy(su_root_t *root);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Deinitialize and free an instance of su_root_t
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to a root structure
- * </table>
- * </blockquote>
- *
- *
- * <a name="su_root_magic"></a>
- * <h3>Function @c su_root_magic()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * su_root_magic_t *su_root_magic(su_root_t *root);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Return the user data pointer that was given input to su_root_create() or
- *
- * su_root_init().
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to a root object
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> A pointer to user data
- * </blockquote>
- *
- *
- * <a name="su_root_register"></a>
- * <h3>Function @c su_root_register()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_root_register(su_root_t *root,
- * su_wait_t *waits,
- * su_wakeup_f callback,
- * su_wakeup_arg_t arg,
- * int priority);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Register a su_wait_t object. The wait object, a callback function and
- *
- * a argument is stored to the root object. The callback function is called,
- * when the wait object is signaled.
- *
- * Please note if identical wait objects are inserted, only first one is
- * ever signalled.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to root object
- * <tr><td>@c waits <td>pointer to wait object
- * <tr><td>@c callback <td>callback function pointer
- * <tr><td>@c arg <td>argument given to callback function when it is invoked
- * <tr><td>@c priority <td>relative priority of the wait object
- * (0 is normal, 1 important, 2 realtime)
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> Index of the wait object, or -1 upon an error.
- * </blockquote>
- *
- *
- * <a name="su_root_unregister"></a>
- * <h3>Function @c su_root_unregister()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_root_unregister(su_root_t *root,
- * su_wait_t *wait,
- * su_wakeup_f callback,
- * su_wakeup_arg_t arg);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> UnRegisters a su_wait_t object. The wait object, a callback function and
- *
- * a argument are removed from the root object. The callback function is called,
- * when the wait object is signaled.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to root object
- * <tr><td>@c waits <td>pointer to wait object
- * <tr><td>@c callback <td>callback function pointer (may be NULL)
- * <tr><td>@c arg <td>argument given to callback function when it
- * is invoked (may be NULL)
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> Index of the wait object, or -1 upon an error.
- * </blockquote>
- *
- *
- * <a name="su_root_run"></a>
- * <h3>Function @c su_root_run()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * void su_root_run(su_root_t *root);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> This function waits for wait objects and the timers associated with
- * the root object. When any wait object is signaled or timer is
- * expired, it invokes the callbacks, and returns waiting.
- *
- *
- * This function returns when su_root_break() is called from a callback.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to root object
- * </table>
- * </blockquote>
- *
- *
- * <a name="su_root_break"></a>
- * <h3>Function @c su_root_break()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * void su_root_break(su_root_t *root);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> If this function is used to terminate execution of su_root_run(). It
- *
- * can be called from a callback function.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to root object
- * </table>
- * </blockquote>
- *
- *
- * <a name="su_root_step"></a>
- * <h3>Function @c su_root_step()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * su_duration_t su_root_step(su_root_t *root, su_duration_t tout);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> This function waits for wait objects and the timers associated with
- * the @a root object. When any wait object is signaled or timer is
- * expired, it invokes the callbacks, and returns.
- *
- *
- * This function returns when a callback has been invoked or @a tout
- * milliseconds is elapsed.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to root object
- * <tr><td>@c tout <td>timeout in milliseconds
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * Milliseconds to the next invocation of timer, or SU_WAIT_FOREVER if
- * there are no active timers.
- * </blockquote>
- *
- * <a name="timer"></a>
- * <h2>Timer objects</h2>
- *
- * Timers are used to schedule some task to be executed at given time or
- * after a default interval. The default interval is specified when the
- * timer is created. We call timer activation "setting the timer", and
- * deactivation "resetting the timer" (as in SDL). When the given time has
- * arrived or the default interval has elapsed, the timer expires and
- * it is ready for execution.
- *
- * These functions are available for handling timers:
- *
- * - su_timer_create()
- * - su_timer_destroy()
- * - su_timer_set()
- * - su_timer_set_at()
- * - su_timer_reset()
- * - su_timer_run()
- *
- * <a name="su_timer_create"></a>
- * <h3>Function @c su_timer_create()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * su_timer_t *su_timer_create(su_root_t *root, su_duration_t msec);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- *
- * <blockquote>
- * Allocate and initialize an instance of su_timer_t.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>the root object with which the timer will be associated
- * <tr><td>@c msec <td>the default duration of the timer
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> A pointer to allocated timer instance, NULL on error.
- * </blockquote>
- *
- *
- * <a name="su_timer_destroy"></a>
- * <h3>Function @c su_timer_destroy()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * void su_timer_destroy(su_timer_t *t);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Deinitialize and free an instance of su_timer_t.
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c t <td>pointer to the timer object
- * </table>
- * </blockquote>
- *
- *
- * <a name="su_timer_set"></a>
- * <h3>Function @c su_timer_set()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_timer_set(su_timer_t *t,
- * su_timer_f wakeup,
- * su_wakeup_arg_t arg);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Sets the given timer to expire after the default duration.
- *
- * The timer must have an default duration.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c t <td>pointer to the timer object
- * <tr><td>@c wakeup <td>pointer to the wakeup function
- * <tr><td>@c arg <td>argument given to the wakeup function
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> 0 if successful, -1 otherwise.
- * </blockquote>
- *
- *
- * <a name="su_timer_set_at"></a>
- * <h3>Function @c su_timer_set_at()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_timer_set_at(su_timer_t *t,
- * su_timer_f wakeup,
- * su_wakeup_arg_t arg,
- * su_time_t when);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Sets the timer to expire at given time.
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c t <td>pointer to the timer object
- * <tr><td>@c wakeup <td>pointer to the wakeup function
- * <tr><td>@c arg <td>argument given to the wakeup function
- * <tr><td>@c when <td>time structure defining the wakeup time
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> 0 if successful, -1 otherwise.
- * </blockquote>
- *
- *
- * <a name="su_timer_reset"></a>
- * <h3>Function @c su_timer_reset()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * int su_timer_reset(su_timer_t *t);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Resets the given timer.
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c t <td>pointer to the timer object
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> 0 if successful, -1 otherwise.
- * </blockquote>
- *
- * <a name="su_timer_run"></a>
- * <h3>Function @c su_timer_run()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- *
- * su_duration_t su_timer_run(su_timer_t ** const t0, su_duration_t tout);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Expires and executes expired timers in queue.
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c t0 <td>pointer to the timer queue
- * <tr><td>@c tout <td>timeout in milliseconds
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote>
- * The duration in milliseconds before the next timer expires, or timeout (2**31 - 1
- * ms), whichever is shorter.
- * </blockquote>
- *
- * <!--
- * Root object is used for synchronizing. There must be one root object per
- * thread. There are two alternative ways for creating a root object. If you
- * are just using su_root_t, and don't want to <a
- * href="#inherit_su_root_t">inherit from it</a>, you can use
- * @c su_create().
- * -->
- *
- * <a name="su_wait_internal.h"></a>
- * <h1><su_wait_internal.h></h1>
- *
- *
- * This section contains the internal functions, that is, functions used to
- * implement objects in @c <su_wait.h>.
- *
- * <a name="su_root_init"></a>
- * <h3>Function @c su_root_init()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- * #include <su_wait_internal.h>
- *
- * int su_root_init(su_root_t *root, su_root_magic_t *magic);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- *
- * <blockquote>
- *
- * Initialize an instance of @c su_root_t. The caller should allocate
- * the memory required for su_root_t, and set the sur_size to the size of the
- * allocated structure.
- *
- * </blockquote>
- *
- * <h4>Parameters</h4>
- *
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to a uninitialized root structure
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> 0 when call was successful, -1 otherwise.
- * </blockquote>
- *
- *
- * <h4>Note</h4>
- * <blockquote>
- * <strong>This is an internal function, and it is intended for implementing
- * the objects derived from @c su_root_t.</strong>
- * </blockquote>
- *
- *
- * <a name="su_root_deinit"></a>
- * <h3>Function @c su_root_deinit()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- * #include <su_wait_internal.h>
- *
- * void su_root_deinit(su_root_t *root);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Deinitialize an instance of su_root_t
- * </blockquote>
- *
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to a root structure
- * </table>
- * </blockquote>
- *
- * <h4>Note</h4>
- * <blockquote> <strong>This is an internal function, and it is intended for
- * implementing the objects derived from @c su_root_t.</strong>
- * </blockquote>
- *
- * <a name="su_root_query"></a>
- * <h3>Function @c su_root_query()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- * #include <su_wait_internal.h>
- *
- * unsigned su_root_query(su_root_t *root, su_wait_t *waits, unsigned n_waits);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Copies the su_wait_t objects from the root. The number of wait objects
- *
- * can be found out by calling su_root_query() with n_waits as zero.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c waits <td>pointer to array to which wait objects are copied
- * <tr><td>@c root <td>pointer to root object
- * <tr><td>@c n_waits <td>number of wait objects fitting in array waits
- * </table>
- * </blockquote>
- *
- * <h4>Return Value</h4>
- * <blockquote> Number of wait objects, or 0 upon an error.
- * </blockquote>
- *
- *
- * <h4>Note</h4>
- * <blockquote><strong>This is an internal function, and it is intended for
- * implementing the objects derived from @c su_root_t.</strong>
- * </blockquote>
- *
- *
- * <a name="su_root_event"></a>
- * <h3>Function @c su_root_event()</h3>
- *
- * <h4>Synopsis</h4>
- *
- * <blockquote><pre>
- * #include <su_wait.h>
- * #include <su_wait_internal.h>
- *
- * void su_root_event(su_root_t *root, su_wait_t *waitobj);
- * </pre></blockquote>
- *
- * <h4>Description</h4>
- * <blockquote> Invokes the callback function associated with the wait object.
- *
- *
- * If waitobj is NULL, check if a wait object associated with root is
- * signaled, and its callback is invoked.
- * </blockquote>
- *
- * <h4>Parameters</h4>
- * <blockquote>
- * <table cellpadding=3 cellspacing=0 border=1>
- * <tr><td>@c root <td>pointer to root object
- * <tr><td>@c waitobj <td>pointer to wait object, or NULL
- * </table>
- * </blockquote>
- *
- * <h4>Note</h4>
- * <blockquote><strong>This is an internal function, and it is intended for
- * implementing the objects derived from @c su_root_t.</strong>
- * </blockquote>
- *
- */
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_addrinfo.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_addrinfo.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_addrinfo.c Mon Aug 20 13:37:13 2007
@@ -47,6 +47,10 @@
#include <stdlib.h>
#include <ctype.h>
+#ifndef EAI_NODATA
+#define EAI_NODATA 7
+#endif
+
/*
* "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
*
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_base_port.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_base_port.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_base_port.c Mon Aug 20 13:37:13 2007
@@ -477,7 +477,7 @@
* Timers
*/
-su_timer_t **su_base_port_timers(su_port_t *self)
+su_timer_queue_t *su_base_port_timers(su_port_t *self)
{
return &self->sup_timers;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_default_log.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_default_log.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_default_log.c Mon Aug 20 13:37:13 2007
@@ -53,7 +53,7 @@
* The SOFIA_DEBUG environment variable is used to determine the default
* debug logging level. The normal level is 3.
*
- * @sa <su_debug.h>, su_log_global
+ * @sa <sofia-sip/su_debug.h>, su_log_global
*/
extern char const SOFIA_DEBUG[];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_global_log.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_global_log.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_global_log.c Mon Aug 20 13:37:13 2007
@@ -45,7 +45,7 @@
* The SU_DEBUG environment variable is used to determine the debug logging
* level for @b su module. The default level is 3.
*
- * @sa <su_debug.h>, su_log_global
+ * @sa <sofia-sip/su_debug.h>, su_log_global
*/
extern char const SU_DEBUG[];
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c Mon Aug 20 13:37:13 2007
@@ -28,20 +28,21 @@
* Obtain list of local addresses.
*
* @author Pekka Pessi <Pekka.Pessi(a)nokia.com>
+ * @author Martti Mela <Martti.Mela(a)nokia.com>
*
* @date Created: Wed Oct 4 14:09:29 EET 2000 ppessi
*/
#include "config.h"
-#include "sofia-sip/su.h"
-#include "sofia-sip/su_localinfo.h"
-#include "su_module_debug.h"
-
#if HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
+#include <sofia-sip/su.h>
+#include <sofia-sip/su_localinfo.h>
+#include "su_module_debug.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -409,9 +410,14 @@
return 0;
}
+#if HAVE_OPEN_C
+extern int su_get_local_ip_addr(su_sockaddr_t *su);
+#endif
+
#if USE_LOCALINFO0
#elif HAVE_IFCONF
+#if __APPLE_CC__
/** Build a list of local IPv4 addresses and append it to *rresult. */
static
int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
@@ -434,6 +440,10 @@
char *buffer;
struct ifreq *ifr, *ifr_next;
+ su_sockaddr_t *sa;
+ socklen_t salen = sizeof(*sa);
+ int scope = 0, gni_flags = 0;
+
s = su_socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1) {
SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",
@@ -441,70 +451,105 @@
return ELI_SYSTEM;
}
-#if defined(__APPLE_CC__)
- {
- su_sockaddr_t *sa;
- socklen_t salen = sizeof(*sa);
- int scope = 0, gni_flags = 0;
- li = calloc(1, sizeof(su_localinfo_t));
- sa = calloc(1, sizeof(su_sockaddr_t));
+ li = calloc(1, sizeof(su_localinfo_t));
+ sa = calloc(1, sizeof(su_sockaddr_t));
- error = getsockname(s, (struct sockaddr *) sa, &salen);
- if (error < 0 && errno == SOCKET_ERROR) {
- SU_DEBUG_1(("%s: getsockname() failed: %s\n", __func__,
- su_strerror(su_errno())));
- }
+ error = getsockname(s, (struct sockaddr *) sa, &salen);
+ if (error < 0 && errno == SOCKET_ERROR) {
+ SU_DEBUG_1(("%s: getsockname() failed: %s\n", __func__,
+ su_strerror(su_errno())));
+ }
- error = bind(s, (struct sockaddr *) sa, salen);
+ error = bind(s, (struct sockaddr *) sa, salen);
- if (error < 0) {
- SU_DEBUG_1(("%s: bind() failed: %s\n", __func__,
- su_strerror(su_errno())));
- goto err;
- }
+ if (error < 0) {
+ SU_DEBUG_1(("%s: bind() failed: %s\n", __func__,
+ su_strerror(su_errno())));
+ goto err;
+ }
- su_close(s);
+ su_close(s);
- scope = li_scope4(sa->su_sin.sin_addr.s_addr);
+ scope = li_scope4(sa->su_sin.sin_addr.s_addr);
- if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
- gni_flags = NI_NUMERICHOST;
+ if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
+ gni_flags = NI_NUMERICHOST;
- if (su_xtra) {
- /* Map IPv4 address to IPv6 address */
- memset(sa, 0, sizeof(*sa));
- sa->su_family = AF_INET6;
- ((int32_t*)&sa->su_sin6.sin6_addr)[3] = sa->su_sin.sin_addr.s_addr;
+ if (su_xtra) {
+ /* Map IPv4 address to IPv6 address */
+ memset(sa, 0, sizeof(*sa));
+ sa->su_family = AF_INET6;
+ ((int32_t*)&sa->su_sin6.sin6_addr)[3] = sa->su_sin.sin_addr.s_addr;
((int32_t*)&sa->su_sin6.sin6_addr)[2] = htonl(0xffff);
- }
+ }
- li->li_family = sa->su_family;
- li->li_scope = scope;
- li->li_index = 0;
- li->li_addrlen = su_sockaddr_size(sa);
- li->li_addr = sa;
+ li->li_family = sa->su_family;
+ li->li_scope = scope;
+ li->li_index = 0;
+ li->li_addrlen = su_sockaddr_size(sa);
+ li->li_addr = sa;
- if ((error = li_name(hints, gni_flags, sa, &canonname)) < 0)
- goto err;
+ if ((error = li_name(hints, gni_flags, sa, &canonname)) < 0)
+ goto err;
- if (canonname) {
- if (strchr(canonname, ':') ||
- strspn(canonname, "0123456789.") == strlen(canonname))
- li->li_flags |= LI_NUMERIC;
- }
- else
- li->li_flags = 0;
+ if (canonname) {
+ if (strchr(canonname, ':') ||
+ strspn(canonname, "0123456789.") == strlen(canonname))
+ li->li_flags |= LI_NUMERIC;
+ }
+ else
+ li->li_flags = 0;
+
+ li->li_canonname = canonname;
- li->li_canonname = canonname;
+ canonname = NULL;
- canonname = NULL;
+ *rresult = li;
+ return 0;
- *rresult = li;
- return 0;
- }
+err:
+ if (canonname) free(canonname);
+ if (li_first) free(li_first);
+ su_freelocalinfo(tbf);
+ su_close(s);
+
+ return error;
+}
+#else /* !__APPLE_CC__ */
+/** Build a list of local IPv4 addresses and append it to *rresult. */
+static
+int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
+{
+ su_localinfo_t *tbf = NULL, **lli = &tbf;
+ su_localinfo_t *li = NULL, *li_first = NULL;
+ su_sockaddr_t *su;
+ int error = ELI_NOADDRESS;
+ char *canonname = NULL;
+ su_socket_t s;
+
+#if SU_HAVE_IN6
+ int su_xtra = (hints->li_flags & LI_V4MAPPED) ? sizeof(*su) : 0;
+#else
+ int const su_xtra = 0;
#endif
+ struct ifconf ifc;
+ int numifs;
+ char *buffer;
+ struct ifreq *ifr, *ifr_next;
+
+#if HAVE_OPEN_C
+ su_sockaddr_t *sa;
+ socklen_t salen = sizeof(*sa);
+#endif
+
+ s = su_socket(AF_INET, SOCK_DGRAM, 0);
+ if (s == -1) {
+ SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",
+ su_strerror(su_errno())));
+ return ELI_SYSTEM;
+ }
# if HAVE_IFNUM
/* Get the list of known IP address from the kernel */
@@ -539,16 +584,25 @@
error = ELI_MEMORY;
goto err;
}
-
+
li_first = (su_localinfo_t *)buffer;
memset(li_first, 0, sizeof(su_localinfo_t) + su_xtra);
ifc.ifc_buf = buffer + sizeof(su_localinfo_t) + su_xtra;
+#if HAVE_OPEN_C
+ if (ioctl(s, SIOCGIFACTIVECONF, (char *)&ifc) < 0) {
+ SU_DEBUG_1(("su_localinfo: SIOCGIFCONF failed: %s\n",
+ su_strerror(su_errno())));
+ error = ELI_SYSTEM;
+ goto err;
+ }
+#else
if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
SU_DEBUG_1(("su_localinfo: SIOCGIFCONF failed: %s\n",
su_strerror(su_errno())));
error = ELI_SYSTEM;
goto err;
}
+#endif
buffer = ifc.ifc_buf + ifc.ifc_len;
@@ -594,6 +648,42 @@
SU_DEBUG_9(("su_localinfo: if %s with index %d\n", if_name, if_index));
+
+#if HAVE_OPEN_C
+ su_close(s);
+
+ li = calloc(1, sizeof(su_localinfo_t));
+ sa = calloc(1, sizeof(su_sockaddr_t));
+
+ if (su_get_local_ip_addr(sa) < 0)
+ goto err;
+
+ li->li_family = sa->su_family;
+ li->li_scope = LI_SCOPE_GLOBAL /* scope */;
+ li->li_index = if_index;
+ li->li_addrlen = su_sockaddr_size(sa);
+ li->li_addr = sa;
+
+ if ((error = li_name(hints, gni_flags, sa, &canonname)) < 0)
+ goto err;
+
+ if (canonname) {
+ if (strchr(canonname, ':') ||
+ strspn(canonname, "0123456789.") == strlen(canonname))
+ li->li_flags |= LI_NUMERIC;
+ }
+ else
+ li->li_flags = 0;
+
+ li->li_canonname = canonname;
+
+ canonname = NULL;
+
+ *rresult = li;
+
+ return 0;
+#endif
+
#if defined(SIOCGIFFLAGS)
ifreq[0] = *ifr;
if (ioctl(s, SIOCGIFFLAGS, ifreq) < 0) {
@@ -703,6 +793,7 @@
return error;
}
+#endif /* __APPLE_CC__ */
#else
static
int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_log.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_log.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_log.c Mon Aug 20 13:37:13 2007
@@ -246,6 +246,10 @@
} else {
log->log_level = level;
log->log_init = 2;
+
+ if (explicitly_initialized == not_initialized)
+ explicitly_initialized = getenv("SHOW_DEBUG_LEVELS");
+
if (explicitly_initialized)
su_llog(log, 0, "%s: soft set log to level %u\n",
log->log_name, log->log_level);
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_port.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_port.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_port.h Mon Aug 20 13:37:13 2007
@@ -123,7 +123,7 @@
int (*su_port_remove_prepoll)(su_port_t *port,
su_root_t *root);
- su_timer_t **(*su_port_timers)(su_port_t *port);
+ su_timer_queue_t *(*su_port_timers)(su_port_t *port);
int (*su_port_multishot)(su_port_t *port, int multishot);
@@ -443,7 +443,7 @@
su_msg_t *sup_head, **sup_tail;
/* Timer list */
- su_timer_t *sup_timers;
+ su_timer_queue_t sup_timers;
unsigned sup_running; /**< In su_root_run() loop? */
} su_base_port_t;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c Mon Aug 20 13:37:13 2007
@@ -459,8 +459,10 @@
struct su_pthread_port_execute frame = {
{ PTHREAD_MUTEX_INITIALIZER },
{ _ENeedsNormalInit, NULL },
- function, arg, 0
+ NULL, NULL, 0
};
+ frame.function = function;
+ frame.arg = arg;
#else
struct su_pthread_port_execute frame = {
{ PTHREAD_MUTEX_INITIALIZER },
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_root.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_root.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_root.c Mon Aug 20 13:37:13 2007
@@ -313,7 +313,7 @@
* @return A timer list of the task. If there are no timers, it returns
* NULL.
*/
-su_timer_t **su_task_timers(su_task_r const task)
+su_timer_queue_t *su_task_timers(su_task_r const task)
{
return task ? su_port_timers(task->sut_port) : NULL;
}
@@ -901,7 +901,7 @@
* @retval -1 otherwise.
*/
-int su_msg_reply(su_msg_r reply, su_msg_r const msg,
+int su_msg_reply(su_msg_r reply, su_msg_cr msg,
su_msg_f wakeup, isize_t size)
{
su_msg_r msg0;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c Mon Aug 20 13:37:13 2007
@@ -66,7 +66,7 @@
*
* Object-oriented tag routines for Sofia utility library.
*
- * The <su_tag.h> defines a interface to object-oriented tag list routines.
+ * The <sofia-sip/su_tag.h> defines a interface to object-oriented tag list routines.
* A tag list is a linear list (array) of tag items, tagi_t structures,
* terminated by a TAG_END() item. Each tag item has a label, tag, (@c
* t_tag) and a value (@c t_value). The tag is a pointer (tag_type_t) to a
@@ -112,7 +112,7 @@
* - TAG_NEXT() - contains a pointer to the next tag list.
*
* The tag type structures are declared as tag_typedef_t. They can be
- * defined by the macros found in <su_tag_class.h>. See nta_tag.c or
+ * defined by the macros found in <sofia-sip/su_tag_class.h>. See nta_tag.c or
* su_tag_test.c for an example.
*
*/
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time.c Mon Aug 20 13:37:13 2007
@@ -61,7 +61,7 @@
* OS-independent timing functions and types for the @b su library.
*
* The @b su library provides three different time formats with different
- * ranges and epochs in the file @b su_time.h:
+ * ranges and epochs in <sofia-sip/su_time.h>:
*
* - #su_time_t, second and microsecond as 32-bit values since 1900,
* - #su_duration_t, milliseconds between two times, and
@@ -209,6 +209,8 @@
(su_res64 * (su_t64_t)(tv).tv_sec + (su_t64_t)(tv).tv_usec)
#define SU_DUR_TO_T64(d) (1000 * (int64_t)(d))
+#define E9 (1000000000)
+
/** Get NTP timestamp.
*
* The function su_ntp_now() returns the current NTP timestamp. NTP
@@ -219,22 +221,36 @@
*/
su_ntp_t su_ntp_now(void)
{
- su_time_t t;
- uint32_t sec, usec;
-
- su_time(&t);
+ su_nanotime_t now;
- sec = t.tv_sec;
- usec = t.tv_usec;
+ su_nanotime(&now);
- /*
- * Multiply usec by 4294.967296 (ie. 2**32 / 1E6)
- *
- * Utilize fact that 4294.967296 == 4295 - 511 / 15625
- */
- usec = 4295 * usec - (511 * usec + 7812) / 15625;
+ if (sizeof(long) == sizeof(now)) {
+ return ((now / E9) << 32) | ((((now % E9) << 32) + E9/2) / E9);
+ }
+ else {
+ su_nanotime_t usec;
+ int nsec;
+ unsigned rem;
+
+ usec = now / 1000;
+ nsec = now % 1000;
+
+ /*
+ * Multiply usec by 4294.967296 (ie. 2**32 / 1E6)
+ *
+ * Utilize fact that 4294.967296 == 4295 - 511 / 15625
+ */
+ now = 4295 * usec - 511 * usec / 15625;
+ rem = (511U * usec) % 15625U;
- return ((su_ntp_t)sec << 32) + (su_ntp_t)usec;
+ /* Multiply nsec by 4.294967296 */
+ nsec = 4295 * 125 * nsec - (511 * nsec) / 125;
+ nsec -= 8 * rem; /* usec rounding */
+ nsec = (nsec + (nsec < 0 ? -62499 : +62499)) / 125000;
+
+ return now + nsec;
+ }
}
/** Get NTP seconds.
@@ -263,7 +279,6 @@
return (uint32_t) (ntp >> 32) & 0xffffffffLU;
}
-
su_ntp_t su_ntp_hilo(uint32_t hi, uint32_t lo)
{
return ((((su_ntp_t)hi) << 32)) | lo;
@@ -464,8 +479,3 @@
}
#endif /* WIN32 */
-
-
-
-
-
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time0.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time0.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_time0.c Mon Aug 20 13:37:13 2007
@@ -44,6 +44,8 @@
#include "sofia-sip/su_time.h"
#include "su_module_debug.h"
+#include <time.h>
+
#if HAVE_SYS_TIME_H
#include <sys/time.h> /* Get struct timeval */
#endif
@@ -60,6 +62,12 @@
/** Seconds from 1.1.1900 to 1.1.1970 */
#define NTP_EPOCH 2208988800UL
+#define E9 (1000000000U)
+#define E7 (10000000U)
+
+/* Hooks for testing timing and timers */
+void (*_su_time)(su_time_t *tv);
+uint64_t (*_su_nanotime)(uint64_t *);
/** Get current time.
*
@@ -83,11 +91,128 @@
GetSystemTimeAsFileTime(date.ft);
- tv->tv_usec = (unsigned long) ((date.ull->QuadPart % 10000000U) / 10);
- tv->tv_sec = (unsigned long) ((date.ull->QuadPart / 10000000U) -
+ tv->tv_usec = (unsigned long) ((date.ull->QuadPart % E7) / 10);
+ tv->tv_sec = (unsigned long) ((date.ull->QuadPart / E7) -
/* 1900-Jan-01 - 1601-Jan-01: 299 years, 72 leap years */
(299 * 365 + 72) * 24 * 60 * (uint64_t)60);
#else
#error no su_time() implementation
#endif
+
+ if (_su_time)
+ _su_time(tv);
+}
+
+/** Get current time as nanoseconds since epoch.
+ *
+ * Return the current NTP timestamp expressed as nanoseconds since epoch
+ * (January 1st 1900).
+ *
+ * @param return_time optional pointer to current time to return
+ *
+ * @return Nanoseconds since epoch
+ */
+su_nanotime_t su_nanotime(su_nanotime_t *return_time)
+{
+ su_nanotime_t now;
+
+ if (!return_time)
+ return_time = &now;
+
+#if HAVE_CLOCK_GETTIME
+ {
+ struct timespec tv;
+
+ if (clock_gettime(CLOCK_REALTIME, &tv) == 0) {
+ now = ((su_nanotime_t)tv.tv_sec + NTP_EPOCH) * E9 + tv.tv_nsec;
+ *return_time = now;
+ if (_su_nanotime)
+ return _su_nanotime(return_time);
+ return now;
+ }
+ }
+#endif
+
+#if HAVE_FILETIME
+ {
+ union {
+ FILETIME ft[1];
+ ULARGE_INTEGER ull[1];
+ } date;
+
+ GetSystemTimeAsFileTime(date.ft);
+
+ now = 100 *
+ (date.ull->QuadPart -
+ /* 1900-Jan-01 - 1601-Jan-01: 299 years, 72 leap years */
+ ((su_nanotime_t)(299 * 365 + 72) * 24 * 60 * 60) * E7);
+ }
+#elif HAVE_GETTIMEOFDAY
+ {
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ now = ((su_nanotime_t)tv.tv_sec + NTP_EPOCH) * E9 + tv.tv_usec * 1000;
+ }
+#else
+ now = ((su_nanotime_t)time() + NTP_EPOCH) * E9;
+#endif
+
+ *return_time = now;
+
+ if (_su_nanotime)
+ return _su_nanotime(return_time);
+
+ return now;
+}
+
+/** Get current time as nanoseconds.
+ *
+ * Return the current time expressed as nanoseconds. The time returned is
+ * monotonic and never goes back - if the underlying system supports such a
+ * clock.
+ *
+ * @param return_time optional pointer to return the current time
+ *
+ * @return Current time as nanoseconds
+ */
+su_nanotime_t su_monotime(su_nanotime_t *return_time)
+{
+#if HAVE_CLOCK_GETTIME
+ {
+ struct timespec tv;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &tv) == 0) {
+ su_nanotime_t now = (su_nanotime_t)tv.tv_sec * E9 + tv.tv_nsec;
+ if (return_time)
+ *return_time = now;
+ return now;
+ }
+ }
+#endif
+
+#if HAVE_NANOUPTIME
+ {
+ struct timespec tv;
+
+ nanouptime(&tv);
+ now = (su_nanotime_t)tv.tv_sec * E9 + tv.tv_nsec;
+ if (return_time)
+ *return_time = now;
+ return now;
+ }
+#elif HAVE_MICROUPTIME
+ {
+ struct timeval tv;
+
+ microuptime(&tv);
+ now = (su_nanotime_t)tv.tv_sec * E9 + tv.tv_usec * 1000;
+ if (return_time)
+ *return_time = now;
+ return now;
+ }
+#else
+ return su_nanotime(return_time);
+#endif
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c Mon Aug 20 13:37:13 2007
@@ -32,6 +32,7 @@
#include "config.h"
+#include "su_port.h"
#include "sofia-sip/su.h"
#include "sofia-sip/su_wait.h"
#include "sofia-sip/su_alloc.h"
@@ -182,8 +183,8 @@
RBTREE_PROTOS(su_inline, timers, su_timer_t);
-su_inline int timers_append(su_timer_t **, su_timer_t *);
-su_inline void timers_remove(su_timer_t **, su_timer_t *);
+su_inline int timers_append(su_timer_queue_t *, su_timer_t *);
+su_inline void timers_remove(su_timer_queue_t *, su_timer_t *);
su_inline su_timer_t *timers_succ(su_timer_t const *);
su_inline su_timer_t *timers_prec(su_timer_t const *);
su_inline su_timer_t *timers_first(su_timer_t const *);
@@ -199,7 +200,7 @@
* @retval 0 when successful (always)
*/
su_inline int
-su_timer_set0(su_timer_t **timers,
+su_timer_set0(su_timer_queue_t *timers,
su_timer_t *t,
su_timer_f wakeup,
su_wakeup_arg_t *arg,
@@ -221,7 +222,7 @@
* @retval 0 when successful (always)
*/
su_inline int
-su_timer_reset0(su_timer_t **timers,
+su_timer_reset0(su_timer_queue_t *timers,
su_timer_t *t)
{
if (SU_TIMER_IS_SET(t))
@@ -242,11 +243,11 @@
* @retval NULL upon an error
*/
static
-su_timer_t **su_timer_tree(su_timer_t const *t,
- int use_sut_duration,
- char const *caller)
+su_timer_queue_t *su_timer_tree(su_timer_t const *t,
+ int use_sut_duration,
+ char const *caller)
{
- su_timer_t **timers;
+ su_timer_queue_t *timers;
if (t == NULL) {
SU_DEBUG_1(("%s(%p): %s\n", caller, (void *)t,
@@ -286,11 +287,10 @@
assert(msec >= 0);
- if (su_task_cmp(task, su_task_null))
- retval = su_zalloc(NULL, sizeof(*retval));
- else
- retval = NULL;
+ if (!su_task_cmp(task, su_task_null))
+ return NULL;
+ retval = su_zalloc(NULL, sizeof(*retval));
if (retval) {
su_task_copy(retval->sut_task, task);
retval->sut_duration = msec;
@@ -308,7 +308,7 @@
void su_timer_destroy(su_timer_t *t)
{
if (t) {
- su_timer_t **timers = su_task_timers(t->sut_task);
+ su_timer_queue_t *timers = su_task_timers(t->sut_task);
if (timers)
su_timer_reset0(timers, t);
su_task_deinit(t->sut_task);
@@ -332,7 +332,7 @@
su_timer_arg_t *arg,
su_duration_t interval)
{
- su_timer_t **timers = su_timer_tree(t, 0, "su_timer_set_interval");
+ su_timer_queue_t *timers = su_timer_tree(t, 0, "su_timer_set_interval");
if (t == NULL)
return -1;
@@ -356,7 +356,7 @@
su_timer_f wakeup,
su_timer_arg_t *arg)
{
- su_timer_t **timers = su_timer_tree(t, 1, "su_timer_set");
+ su_timer_queue_t *timers = su_timer_tree(t, 1, "su_timer_set");
if (timers == NULL)
return -1;
@@ -380,7 +380,7 @@
su_wakeup_arg_t *arg,
su_time_t when)
{
- su_timer_t **timers = su_timer_tree(t, 0, "su_timer_set_at");
+ su_timer_queue_t *timers = su_timer_tree(t, 0, "su_timer_set_at");
if (timers == NULL)
return -1;
@@ -410,7 +410,7 @@
su_timer_f wakeup,
su_timer_arg_t *arg)
{
- su_timer_t **timers = su_timer_tree(t, 1, "su_timer_run");
+ su_timer_queue_t *timers = su_timer_tree(t, 1, "su_timer_run");
su_time_t now;
if (timers == NULL)
@@ -443,7 +443,7 @@
su_timer_f wakeup,
su_timer_arg_t *arg)
{
- su_timer_t **timers = su_timer_tree(t, 1, "su_timer_set_for_ever");
+ su_timer_queue_t *timers = su_timer_tree(t, 1, "su_timer_set_for_ever");
su_time_t now;
if (timers == NULL)
@@ -466,7 +466,7 @@
*/
int su_timer_reset(su_timer_t *t)
{
- su_timer_t **timers = su_timer_tree(t, 0, "su_timer_reset");
+ su_timer_queue_t *timers = su_timer_tree(t, 0, "su_timer_reset");
if (timers == NULL)
return -1;
@@ -487,7 +487,7 @@
* @return
* The number of expired timers.
*/
-int su_timer_expire(su_timer_t ** const timers,
+int su_timer_expire(su_timer_queue_t * const timers,
su_duration_t *timeout,
su_time_t now)
{
@@ -571,7 +571,7 @@
*
* @return Number of timers reset.
*/
-int su_timer_reset_all(su_timer_t **timers, su_task_r task)
+int su_timer_reset_all(su_timer_queue_t *timers, su_task_r task)
{
su_timer_t *t, *t_next;
int n = 0;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/tag_dll.awk
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/tag_dll.awk (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/tag_dll.awk Mon Aug 20 13:37:13 2007
@@ -92,7 +92,7 @@
"#include \"config.h\"\n\n"\
"#include <sofia-sip/su_tag_class.h>\n"\
"\n"\
- "#ifdef _WIN32\n"\
+ "#if defined _WIN32 || defined HAVE_OPEN_C\n"\
"#define EXPORT __declspec(dllexport)\n"\
"#else\n"\
"#define EXPORT\n"\
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/test_poll.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/test_poll.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/test_poll.c Mon Aug 20 13:37:13 2007
@@ -24,7 +24,7 @@
/**@ingroup su_root_ex
* @file test_poll.c
- * Example code for su_wait.h.
+ * Example code for <sofia-sip/su_wait.h>.
*
* This file illustrates how the asynchronous connect can be used with @b su.
*
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_tag.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_tag.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_tag.c Mon Aug 20 13:37:13 2007
@@ -275,8 +275,16 @@
/** Test tl_list, tl_llist and tl_dup */
static int test_dup(void)
{
- tagi_t const rest[] = {{ TAG_A("Foo") }, { TAG_NULL() }};
tagi_t *lst, *dup;
+#if HAVE_OPEN_C
+ tagi_t rest[2];
+ rest[0].t_tag = tag_a;
+ rest[0].t_value = tag_str_v("Foo");
+ rest[1].t_tag = (tag_type_t)0;
+ rest[0].t_value = (tag_value_t)0;
+#else
+ tagi_t const rest[] = {{ TAG_A("Foo") }, { TAG_NULL() }};
+#endif
BEGIN();
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_time.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_time.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_time.c Mon Aug 20 13:37:13 2007
@@ -50,62 +50,37 @@
char const *name = "torture_su_time.c";
+int expensive_tests = 0;
+
static int test1(int flags);
static int test2(int flags);
static int test3(int flags);
-void usage(int exitcode)
-{
- fprintf(stderr,
- "usage: %s [-v] [-a]\n",
- name);
- exit(exitcode);
-}
-
-char *lastpart(char *path)
-{
- if (strchr(path, '/'))
- return strrchr(path, '/') + 1;
- else
- return path;
-}
+su_time_t tv0;
-int main(int argc, char *argv[])
+void su_time0(su_time_t *tv)
{
- int flags = 0;
- int retval = 0;
- int i;
-
- name = lastpart(argv[0]); /* Set our name */
-
- for (i = 1; argv[i]; i++) {
- if (strcmp(argv[i], "-v") == 0)
- flags |= tst_verbatim;
- else if (strcmp(argv[i], "-a") == 0)
- flags |= tst_abort;
- else
- usage(1);
- }
-
- retval |= test1(flags); fflush(stdout);
- retval |= test2(flags); fflush(stdout);
- retval |= test3(flags); fflush(stdout);
-
- return retval;
+ *tv = tv0;
}
-su_time_t tv0;
+uint64_t nanotime;
-void su_time(su_time_t *tv)
+uint64_t su_nanotime0(uint64_t *retval)
{
- *tv = tv0;
+ if (nanotime)
+ return *retval = nanotime;
+ else
+ return *retval = (uint64_t)tv0.tv_sec * 1000000000U + tv0.tv_usec * 1000U;
}
+#define E9 (1000000000U)
+
int test1(int flags)
{
uint32_t ntp_hi, ntp_lo, ntp_mw;
su_time_t now;
su_ntp_t ntp, ntp0, ntp1;
+ uint64_t increment = 3019;
BEGIN();
@@ -136,8 +111,20 @@
TEST64(su_ntp_hi(ntp), ntp_hi);
TEST64(su_ntp_lo(ntp), 0);
TEST64(su_ntp_mw(ntp), (ntp_hi & 0xffff) << 16);
+
TEST(su_ntp_fraq(tv0), su_ntp_mw(ntp));
+ if (expensive_tests)
+ increment = 1;
+
+ for (nanotime = 1; nanotime <= 2 * E9; nanotime += increment) {
+ ntp = su_ntp_now();
+ ntp0 = ((nanotime / E9) << 32) | ((((nanotime % E9) << 32) + E9/2) / E9);
+ TEST(ntp, ntp0);
+ }
+
+ nanotime = 0;
+
END();
}
@@ -157,6 +144,7 @@
BEGIN();
+ nanotime = 0;
tv0.tv_sec = 268435455;
tv0.tv_usec = 98765;
@@ -165,10 +153,10 @@
su_guid_generate(g1);
seq1 = ((g1->s.clock_seq_hi_and_reserved & 0x3f) << 8) + g1->s.clock_seq_low;
- TEST(g1->s.time_low, htonl(tl & 0xffffFFFFU));
- TEST(g1->s.time_mid, htons((tl >> 32) & 0xffffU));
- TEST(g1->s.time_high_and_version, htons(((tl >> 48) & 0xfffU) | 0x1000));
TEST(g1->s.clock_seq_hi_and_reserved & 0xc0, 0x80);
+ TEST(g1->s.time_high_and_version, htons(((tl >> 48) & 0xfffU) | 0x1000));
+ TEST(ntohs(g1->s.time_mid), (tl >> 32) & 0xffffU);
+ //TEST(ntohl(g1->s.time_low), tl & 0xffffFFFFU);
TEST(i = su_guid_sprintf(buf, sizeof(buf), g1), su_guid_strlen);
TEST_SIZE(strlen(buf), i);
@@ -219,3 +207,56 @@
END();
}
+
+void su_time0(su_time_t *tv);
+uint64_t su_nanotime0(uint64_t *);
+
+extern void (*_su_time)(su_time_t *tv);
+extern uint64_t (*_su_nanotime)(uint64_t *);
+
+void usage(int exitcode)
+{
+ fprintf(stderr,
+ "usage: %s [-v] [-a]\n",
+ name);
+ exit(exitcode);
+}
+
+char *lastpart(char *path)
+{
+ if (strchr(path, '/'))
+ return strrchr(path, '/') + 1;
+ else
+ return path;
+}
+
+int main(int argc, char *argv[])
+{
+ int flags = 0;
+ int retval = 0;
+ int i;
+
+ name = lastpart(argv[0]); /* Set our name */
+
+ for (i = 1; argv[i]; i++) {
+ if (strcmp(argv[i], "-v") == 0)
+ flags |= tst_verbatim;
+ else if (strcmp(argv[i], "-x") == 0)
+ expensive_tests = 1;
+ else if (strcmp(argv[i], "-a") == 0)
+ flags |= tst_abort;
+ else
+ usage(1);
+ }
+
+ if (getenv("EXPENSIVE_CHECKS"))
+ expensive_tests = 1;
+
+ _su_time = su_time0, _su_nanotime = su_nanotime0;
+
+ retval |= test1(flags); fflush(stdout);
+ retval |= test2(flags); fflush(stdout);
+ retval |= test3(flags); fflush(stdout);
+
+ return retval;
+}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_timer.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_timer.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/su/torture_su_timer.c Mon Aug 20 13:37:13 2007
@@ -147,8 +147,8 @@
char *argv0 = argv[0];
char *s;
int use_t1 = 0;
- su_time_t now, started;
- intptr_t i, N = 500;
+ su_time_t now, started, inserted;
+ unsigned i, N = 500;
struct timing timing[1] = {{ 0 }};
struct tester tester[1] = {{ 0 }};
@@ -240,22 +240,34 @@
timers = calloc(N, sizeof *timers);
if (!timers) { perror("calloc"); exit(1); }
- now = started = su_now();
-
for (i = 0; i < N; i++) {
t = su_timer_create(su_root_task(root), 1000);
if (!t) { perror("su_timer_create"); exit(1); }
- if (++now.tv_usec == 0) ++now.tv_sec;
- su_timer_set_at(t, increment, (void *)i, now);
timers[i] = t;
}
- tester->sentinel = (void*)(i - 1);
+ now = started = su_now();
+
+ for (i = 0; i < N; i++) {
+ if (++now.tv_usec == 0) ++now.tv_sec;
+ su_timer_set_at(timers[i], increment, (void *)(intptr_t)i, now);
+ }
+
+ tester->sentinel = (void*)(intptr_t)(i - 1);
+
+ inserted = su_now();
su_root_run(root);
- printf("Processing %u timers took %f millisec (%f expected)\n",
- (unsigned)i, su_time_diff(su_now(), started) * 1000, (double)i / 1000);
+ now = su_now();
+
+ printf("Inserting %u timers took %f millisec\n",
+ i, su_time_diff(inserted, started) * 1000);
+
+ printf("Processing %u/%u timers took %f millisec (%f expected)\n",
+ tester->times, i,
+ su_time_diff(now, started) * 1000,
+ (double)i / 1000);
for (i = 0; i < N; i++) {
su_timer_destroy(timers[i]);
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/test_tport.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/test_tport.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/test_tport.c Mon Aug 20 13:37:13 2007
@@ -1385,6 +1385,10 @@
usage(1);
}
+#if HAVE_OPEN_C
+ tstflags |= tst_verbatim;
+#endif
+
/* Use log */
if (flags & tst_verbatim)
tport_log->log_default = 9;
@@ -1411,6 +1415,10 @@
su_deinit();
+#if HAVE_OPEN_C
+ sleep(10);
+#endif
+
return retval;
}
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport.c Mon Aug 20 13:37:13 2007
@@ -3746,6 +3746,11 @@
hints->ai_socktype = self->tp_addrinfo->ai_socktype;
hints->ai_protocol = self->tp_addrinfo->ai_protocol;
+#if HAVE_OPEN_C
+ if (host_is_ip_address(tpn->tpn_host))
+ hints->ai_flags |= AI_NUMERICHOST;
+#endif
+
if (tpn->tpn_host[0] == '[') {
/* Remove [] around IPv6 address */
char *end;
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h Mon Aug 20 13:37:13 2007
@@ -61,7 +61,7 @@
#include <sofia-sip/su_debug.h>
-#if !defined(MSG_NOSIGNAL) || defined(__CYGWIN__)
+#if !defined(MSG_NOSIGNAL) || defined(__CYGWIN__) || defined(SYMBIAN)
#undef MSG_NOSIGNAL
#define MSG_NOSIGNAL (0)
#endif
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c Mon Aug 20 13:37:13 2007
@@ -77,7 +77,7 @@
* The TPORT_DEBUG environment variable is used to determine the debug logging
* level for @b tport module. The default level is 3.
*
- * @sa <su_debug.h>, tport_log, SOFIA_DEBUG
+ * @sa <sofia-sip/su_debug.h>, tport_log, SOFIA_DEBUG
*/
#ifdef DOXYGEN
extern char const TPORT_DEBUG[]; /* dummy declaration for Doxygen */
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_tls.c Mon Aug 20 13:37:13 2007
@@ -50,7 +50,7 @@
/* ---------------------------------------------------------------------- */
/* TLS */
-#include <tport_tls.h>
+#include "tport_tls.h"
static int tport_tls_init_primary(tport_primary_t *,
tp_name_t tpn[1],
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/build_sources.cmd
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/build_sources.cmd (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/build_sources.cmd Mon Aug 20 13:37:13 2007
@@ -110,6 +110,8 @@
%CHECK%
%TAG_AWK% NO_DLL=1 %P%/tport/tport_tag.c < NUL
%CHECK%
+%TAG_AWK% NO_DLL=1 %P%/su/su_tag.c < NUL
+%CHECK%
%TAG_AWK% NO_DLL=1 %P%/url/url_tag.c < NUL
%CHECK%
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/config.h.in
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/config.h.in (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/config.h.in Mon Aug 20 13:37:13 2007
@@ -441,4 +441,4 @@
/* #undef size_t */
/* Define to 1 if compiling on Open C environment */
-/* #undef HAVE_OPEN_C */
\ No newline at end of file
+#define HAVE_OPEN_C 1
\ No newline at end of file
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/bld.inf
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/bld.inf (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/bld.inf Mon Aug 20 13:37:13 2007
@@ -1,40 +1,143 @@
-/*
-* ==============================================================================
-* Name : bld.inf
-* Part of : Camcorder
-* Description : Camcorder application build information
-* Version :
-*
-* Copyright (c) 2003-2006 Nokia Corporation.
-* This material, including documentation and any related
-* computer programs, is protected by copyright controlled by
-* Nokia Corporation. All rights are reserved. Copying,
-* including reproducing, storing, adapting or translating, any
-* or all of this material requires the prior written consent of
-* Nokia Corporation. This material also contains confidential
-* information which may not be disclosed to others without the
-* prior written consent of Nokia Corporation.
-* ==============================================================================
-*/
-
-PRJ_PLATFORMS
-DEFAULT
-
-PRJ_EXPORTS
-
-
-PRJ_MMPFILES
-
-libsofia-sip-ua.mmp
-
-torture_su_root.mmp
-torture_su_port.mmp
-torture_su_tag.mmp
-torture_su_alloc.mmp
-torture_url.mmp
-test_msg.mmp
-torture_sip.mmp
-
-PRJ_TESTMMPFILES
-
+//
+// bld.inf for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+../../libsofia-sip-ua/bnf/sofia-sip/bnf.h \epoc32\include\osextensions\sofia-sip\bnf.h
+../../libsofia-sip-ua/bnf/sofia-sip/hostdomain.h \epoc32\include\osextensions\sofia-sip\hostdomain.h
+../../libsofia-sip-ua/features/sofia-sip/sofia_features.h \epoc32\include\osextensions\sofia-sip\sofia_features.h
+../../libsofia-sip-ua/http/sofia-sip/http.h \epoc32\include\osextensions\sofia-sip\http.h
+../../libsofia-sip-ua/http/sofia-sip/http_hclasses.h \epoc32\include\osextensions\sofia-sip\http_hclasses.h
+../../libsofia-sip-ua/http/sofia-sip/http_header.h \epoc32\include\osextensions\sofia-sip\http_header.h
+../../libsofia-sip-ua/http/sofia-sip/http_parser.h \epoc32\include\osextensions\sofia-sip\http_parser.h
+../../libsofia-sip-ua/http/sofia-sip/http_protos.h \epoc32\include\osextensions\sofia-sip\http_protos.h
+../../libsofia-sip-ua/http/sofia-sip/http_status.h \epoc32\include\osextensions\sofia-sip\http_status.h
+../../libsofia-sip-ua/http/sofia-sip/http_tag.h \epoc32\include\osextensions\sofia-sip\http_tag.h
+../../libsofia-sip-ua/http/sofia-sip/http_tag_class.h \epoc32\include\osextensions\sofia-sip\http_tag_class.h
+../../libsofia-sip-ua/ipt/sofia-sip/base64.h \epoc32\include\osextensions\sofia-sip\base64.h
+../../libsofia-sip-ua/ipt/sofia-sip/rc4.h \epoc32\include\osextensions\sofia-sip\rc4.h
+../../libsofia-sip-ua/ipt/sofia-sip/token64.h \epoc32\include\osextensions\sofia-sip\token64.h
+../../libsofia-sip-ua/ipt/sofia-sip/uniqueid.h \epoc32\include\osextensions\sofia-sip\uniqueid.h
+../../libsofia-sip-ua/ipt/sofia-sip/utf8.h \epoc32\include\osextensions\sofia-sip\utf8.h
+../../libsofia-sip-ua/iptsec/sofia-sip/auth_client.h \epoc32\include\osextensions\sofia-sip\auth_client.h
+../../libsofia-sip-ua/iptsec/sofia-sip/auth_client_plugin.h \epoc32\include\osextensions\sofia-sip\auth_client_plugin.h
+../../libsofia-sip-ua/iptsec/sofia-sip/auth_common.h \epoc32\include\osextensions\sofia-sip\auth_common.h
+../../libsofia-sip-ua/iptsec/sofia-sip/auth_digest.h \epoc32\include\osextensions\sofia-sip\auth_digest.h
+../../libsofia-sip-ua/iptsec/sofia-sip/auth_module.h \epoc32\include\osextensions\sofia-sip\auth_module.h
+../../libsofia-sip-ua/iptsec/sofia-sip/auth_ntlm.h \epoc32\include\osextensions\sofia-sip\auth_ntlm.h
+../../libsofia-sip-ua/iptsec/sofia-sip/auth_plugin.h \epoc32\include\osextensions\sofia-sip\auth_plugin.h
+../../libsofia-sip-ua/msg/sofia-sip/msg.h \epoc32\include\osextensions\sofia-sip\msg.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_addr.h \epoc32\include\osextensions\sofia-sip\msg_addr.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_buffer.h \epoc32\include\osextensions\sofia-sip\msg_buffer.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_date.h \epoc32\include\osextensions\sofia-sip\msg_date.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_header.h \epoc32\include\osextensions\sofia-sip\msg_header.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_mclass.h \epoc32\include\osextensions\sofia-sip\msg_mclass.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_mclass_hash.h \epoc32\include\osextensions\sofia-sip\msg_mclass_hash.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_mime.h \epoc32\include\osextensions\sofia-sip\msg_mime.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_mime_protos.h \epoc32\include\osextensions\sofia-sip\msg_mime_protos.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_parser.h \epoc32\include\osextensions\sofia-sip\msg_parser.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_protos.h \epoc32\include\osextensions\sofia-sip\msg_protos.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_tag_class.h \epoc32\include\osextensions\sofia-sip\msg_tag_class.h
+../../libsofia-sip-ua/msg/sofia-sip/msg_types.h \epoc32\include\osextensions\sofia-sip\msg_types.h
+../../libsofia-sip-ua/nea/sofia-sip/nea.h \epoc32\include\osextensions\sofia-sip\nea.h
+../../libsofia-sip-ua/nea/sofia-sip/nea_tag.h \epoc32\include\osextensions\sofia-sip\nea_tag.h
+../../libsofia-sip-ua/nta/sofia-sip/nta.h \epoc32\include\osextensions\sofia-sip\nta.h
+../../libsofia-sip-ua/nta/sofia-sip/nta_stateless.h \epoc32\include\osextensions\sofia-sip\nta_stateless.h
+../../libsofia-sip-ua/nta/sofia-sip/nta_tag.h \epoc32\include\osextensions\sofia-sip\nta_tag.h
+../../libsofia-sip-ua/nta/sofia-sip/nta_tport.h \epoc32\include\osextensions\sofia-sip\nta_tport.h
+../../libsofia-sip-ua/nta/sofia-sip/sl_utils.h \epoc32\include\osextensions\sofia-sip\sl_utils.h
+../../libsofia-sip-ua/nth/sofia-sip/nth.h \epoc32\include\osextensions\sofia-sip\nth.h
+../../libsofia-sip-ua/nth/sofia-sip/nth_tag.h \epoc32\include\osextensions\sofia-sip\nth_tag.h
+../../libsofia-sip-ua/nua/sofia-sip/nua.h \epoc32\include\osextensions\sofia-sip\nua.h
+../../libsofia-sip-ua/nua/sofia-sip/nua_tag.h \epoc32\include\osextensions\sofia-sip\nua_tag.h
+../../libsofia-sip-ua/sdp/sofia-sip/sdp.h \epoc32\include\osextensions\sofia-sip\sdp.h
+../../libsofia-sip-ua/sdp/sofia-sip/sdp_tag.h \epoc32\include\osextensions\sofia-sip\sdp_tag.h
+../../libsofia-sip-ua/sip/sofia-sip/sip.h \epoc32\include\osextensions\sofia-sip\sip.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_extra.h \epoc32\include\osextensions\sofia-sip\sip_extra.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_hclasses.h \epoc32\include\osextensions\sofia-sip\sip_hclasses.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_header.h \epoc32\include\osextensions\sofia-sip\sip_header.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_parser.h \epoc32\include\osextensions\sofia-sip\sip_parser.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_protos.h \epoc32\include\osextensions\sofia-sip\sip_protos.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_status.h \epoc32\include\osextensions\sofia-sip\sip_status.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_tag.h \epoc32\include\osextensions\sofia-sip\sip_tag.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_tag_class.h \epoc32\include\osextensions\sofia-sip\sip_tag_class.h
+../../libsofia-sip-ua/sip/sofia-sip/sip_util.h \epoc32\include\osextensions\sofia-sip\sip_util.h
+../../libsofia-sip-ua/soa/sofia-sip/soa.h \epoc32\include\osextensions\sofia-sip\soa.h
+../../libsofia-sip-ua/soa/sofia-sip/soa_add.h \epoc32\include\osextensions\sofia-sip\soa_add.h
+../../libsofia-sip-ua/soa/sofia-sip/soa_session.h \epoc32\include\osextensions\sofia-sip\soa_session.h
+../../libsofia-sip-ua/soa/sofia-sip/soa_tag.h \epoc32\include\osextensions\sofia-sip\soa_tag.h
+../../libsofia-sip-ua/sresolv/sofia-sip/sresolv.h \epoc32\include\osextensions\sofia-sip\sresolv.h
+../../libsofia-sip-ua/sresolv/sofia-resolv/sres.h \epoc32\include\osextensions\sofia-resolv/sres.h
+../../libsofia-sip-ua/sresolv/sofia-resolv/sres_async.h \epoc32\include\osextensions\sofia-resolv/sres_async.h
+../../libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h \epoc32\include\osextensions\sofia-resolv/sres_cache.h
+../../libsofia-sip-ua/sresolv/sofia-resolv/sres_config.h \epoc32\include\osextensions\sofia-resolv/sres_config.h
+../../libsofia-sip-ua/sresolv/sofia-resolv/sres_record.h \epoc32\include\osextensions\sofia-resolv/sres_record.h
+../../libsofia-sip-ua/stun/sofia-sip/stun.h \epoc32\include\osextensions\sofia-sip\stun.h
+../../libsofia-sip-ua/stun/sofia-sip/stun_common.h \epoc32\include\osextensions\sofia-sip\stun_common.h
+../../libsofia-sip-ua/stun/sofia-sip/stun_tag.h \epoc32\include\osextensions\sofia-sip\stun_tag.h
+../../libsofia-sip-ua/su/sofia-sip/heap.h \epoc32\include\osextensions\sofia-sip\heap.h
+../../libsofia-sip-ua/su/sofia-sip/htable.h \epoc32\include\osextensions\sofia-sip\htable.h
+../../libsofia-sip-ua/su/sofia-sip/htable2.h \epoc32\include\osextensions\sofia-sip\htable2.h
+../../libsofia-sip-ua/su/sofia-sip/rbtree.h \epoc32\include\osextensions\sofia-sip\rbtree.h
+../../libsofia-sip-ua/su/sofia-sip/string0.h \epoc32\include\osextensions\sofia-sip\string0.h
+../../libsofia-sip-ua/su/sofia-sip/su.h \epoc32\include\osextensions\sofia-sip\su.h
+../../libsofia-sip-ua/su/sofia-sip/su_addrinfo.h \epoc32\include\osextensions\sofia-sip\su_addrinfo.h
+../../libsofia-sip-ua/su/sofia-sip/su_alloc.h \epoc32\include\osextensions\sofia-sip\su_alloc.h
+../../libsofia-sip-ua/su/sofia-sip/su_alloc_stat.h \epoc32\include\osextensions\sofia-sip\su_alloc_stat.h
+../../libsofia-sip-ua/su/sofia-sip/su_bm.h \epoc32\include\osextensions\sofia-sip\su_bm.h
+../../libsofia-sip-ua/su/sofia-sip/su_config.h \epoc32\include\osextensions\sofia-sip\su_config.h
+../../libsofia-sip-ua/su/sofia-sip/su_debug.h \epoc32\include\osextensions\sofia-sip\su_debug.h
+../../libsofia-sip-ua/su/sofia-sip/su_errno.h \epoc32\include\osextensions\sofia-sip\su_errno.h
+../../libsofia-sip-ua/su/sofia-sip/su_localinfo.h \epoc32\include\osextensions\sofia-sip\su_localinfo.h
+../../libsofia-sip-ua/su/sofia-sip/su_log.h \epoc32\include\osextensions\sofia-sip\su_log.h
+../../libsofia-sip-ua/su/sofia-sip/su_md5.h \epoc32\include\osextensions\sofia-sip\su_md5.h
+../../libsofia-sip-ua/su/sofia-sip/su_os_nw.h \epoc32\include\osextensions\sofia-sip\su_os_nw.h
+../../libsofia-sip-ua/su/sofia-sip/su_strlst.h \epoc32\include\osextensions\sofia-sip\su_strlst.h
+../../libsofia-sip-ua/su/sofia-sip/su_tag.h \epoc32\include\osextensions\sofia-sip\su_tag.h
+../../libsofia-sip-ua/su/sofia-sip/su_tag_class.h \epoc32\include\osextensions\sofia-sip\su_tag_class.h
+../../libsofia-sip-ua/su/sofia-sip/su_tag_inline.h \epoc32\include\osextensions\sofia-sip\su_tag_inline.h
+../../libsofia-sip-ua/su/sofia-sip/su_tag_io.h \epoc32\include\osextensions\sofia-sip\su_tag_io.h
+../../libsofia-sip-ua/su/sofia-sip/su_tagarg.h \epoc32\include\osextensions\sofia-sip\su_tagarg.h
+../../libsofia-sip-ua/su/sofia-sip/su_time.h \epoc32\include\osextensions\sofia-sip\su_time.h
+../../libsofia-sip-ua/su/sofia-sip/su_types.h \epoc32\include\osextensions\sofia-sip\su_types.h
+../../libsofia-sip-ua/su/sofia-sip/su_uniqueid.h \epoc32\include\osextensions\sofia-sip\su_uniqueid.h
+../../libsofia-sip-ua/su/sofia-sip/su_vector.h \epoc32\include\osextensions\sofia-sip\su_vector.h
+../../libsofia-sip-ua/su/sofia-sip/su_wait.h \epoc32\include\osextensions\sofia-sip\su_wait.h
+../../libsofia-sip-ua/su/sofia-sip/tstdef.h \epoc32\include\osextensions\sofia-sip\tstdef.h
+../../libsofia-sip-ua/tport/sofia-sip/tport.h \epoc32\include\osextensions\sofia-sip\tport.h
+../../libsofia-sip-ua/tport/sofia-sip/tport_plugins.h \epoc32\include\osextensions\sofia-sip\tport_plugins.h
+../../libsofia-sip-ua/tport/sofia-sip/tport_tag.h \epoc32\include\osextensions\sofia-sip\tport_tag.h
+../../libsofia-sip-ua/url/sofia-sip/url.h \epoc32\include\osextensions\sofia-sip\url.h
+../../libsofia-sip-ua/url/sofia-sip/url_tag.h \epoc32\include\osextensions\sofia-sip\url_tag.h
+../../libsofia-sip-ua/url/sofia-sip/url_tag_class.h \epoc32\include\osextensions\sofia-sip\url_tag_class.h
+../../libsofia-sip-ua-glib/su-glib/sofia-sip/su_glib.h \epoc32\include\osextensions\sofia-sip\su_glib.h
+../../libsofia-sip-ua-glib/su-glib/sofia-sip/su_source.h \epoc32\include\osextensions\sofia-sip\su_source.h
+../sofia-sip/su_configure.h \epoc32\include\osextensions\sofia-sip\su_configure.h
+
+PRJ_MMPFILES
+
+libsofia-sip-ua.mmp
+libsofia-sip-ua-glib.mmp
+
+//torture_su_root.mmp
+//torture_su_port.mmp
+//torture_su_tag.mmp
+//torture_su_alloc.mmp
+//torture_url.mmp
+//test_msg.mmp
+//torture_sip.mmp
+//test_http.mmp
+//test_soa.mmp
+test_tport.mmp
+test_nua.mmp
+//test_nta.mmp
+su_source_test.mmp
+
// End of File
\ No newline at end of file
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/libsofia-sip-ua.mmp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/libsofia-sip-ua.mmp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/libsofia-sip-ua.mmp Mon Aug 20 13:37:13 2007
@@ -1,12 +1,19 @@
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
+
// General properties
-TARGET libsofia-sip-ua.lib
-TARGETTYPE lib
-CAPABILITY ALL -TCB
+TARGET libsofia-sip-ua.dll
+TARGETTYPE dll
+CAPABILITY All -Tcb //NetworkServices
UID 0x1000008D 0xA000017E
VENDORID 0
OPTION CW -dialect c99 -inline on -warn nounusedarg,nounusedvar
+//CAPABILITY NetworkServices NetworkControl CommDD UserEnvironment
-//EPOCHEAPSIZE 4 4194304 // min. 4KB ja max 4MB
+//EPOCHEAPSIZE 4 4194304
// Allow global writeable static data
EPOCALLOWDLLDATA
@@ -17,6 +24,8 @@
SOURCEPATH ..\..\libsofia-sip-ua\su
+SOURCE su_open_c_localinfo.cpp
+
SOURCE su.c
SOURCE su_errno.c
SOURCE su_addrinfo.c
@@ -268,35 +277,20 @@
USERINCLUDE ..\..\libsofia-sip-ua\nea
USERINCLUDE ..\..\libsofia-sip-ua\nua
-SYSTEMINCLUDE ..
-SYSTEMINCLUDE ..\..\libsofia-sip-ua/features
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\su
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\bnf
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\ipt
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\iptsec
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\url
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\msg
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\sresolv
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\stun
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\soa
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\sdp
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\http
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\tport
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\sip
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\nta
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\nth
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\nea
-SYSTEMINCLUDE ..\..\libsofia-sip-ua\nua
-
-SYSTEMINCLUDE \Epoc32\include
-SYSTEMINCLUDE \Epoc32\include\osextensions\stdapis
-SYSTEMINCLUDE \epoc32\include\libc
-SYSTEMINCLUDE \epoc32\include\osextensions\stdapis\openssl
+SYSTEMINCLUDE \epoc32\include
+SYSTEMINCLUDE \epoc32\include\stdapis
+SYSTEMINCLUDE \epoc32\include\stdapis\openssl
+SYSTEMINCLUDE \epoc32\include\osextensions
// Library dependencies
+
+LIBRARY commdb.lib
+STATICLIBRARY libcrt0.lib
LIBRARY libc.lib
LIBRARY libm.lib
LIBRARY libpthread.lib
LIBRARY libcrypto.lib
LIBRARY libssl.lib
-LIBRARY euser.lib
\ No newline at end of file
+LIBRARY euser.lib
+LIBRARY insock.lib
+LIBRARY esock.lib
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg.mmp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg.mmp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg.mmp Mon Aug 20 13:37:13 2007
@@ -1,4 +1,8 @@
-// sofiatest component properties
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
// General properties
TARGET test_msg.exe
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg_reg.rss
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg_reg.rss (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/test_msg_reg.rss Mon Aug 20 13:37:13 2007
@@ -1,3 +1,9 @@
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
+
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip.mmp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip.mmp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip.mmp Mon Aug 20 13:37:13 2007
@@ -1,4 +1,8 @@
-// sofiatest component properties
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
// General properties
TARGET torture_sip.exe
@@ -16,7 +20,7 @@
#endif
END //RESOURCE
-//EPOCHEAPSIZE 4 4194304 // min. 4KB ja max 4MB
+EPOCHEAPSIZE 4 4194304 // min. 4KB ja max 4MB
// Allow global writeable static data
EPOCALLOWDLLDATA
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip_reg.rss
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip_reg.rss (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_sip_reg.rss Mon Aug 20 13:37:13 2007
@@ -1,3 +1,9 @@
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
+
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc.mmp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc.mmp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc.mmp Mon Aug 20 13:37:13 2007
@@ -1,4 +1,8 @@
-// sofiatest component properties
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
// General properties
TARGET torture_su_alloc.exe
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc_reg.rss
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc_reg.rss (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_alloc_reg.rss Mon Aug 20 13:37:13 2007
@@ -1,3 +1,9 @@
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
+
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root.mmp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root.mmp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root.mmp Mon Aug 20 13:37:13 2007
@@ -1,4 +1,8 @@
-// sofiatest component properties
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
// General properties
TARGET torture_su_root.exe
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root_reg.rss
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root_reg.rss (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_root_reg.rss Mon Aug 20 13:37:13 2007
@@ -1,3 +1,9 @@
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
+
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag.mmp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag.mmp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag.mmp Mon Aug 20 13:37:13 2007
@@ -1,4 +1,8 @@
-// sofiatest component properties
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
// General properties
TARGET torture_su_tag.exe
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag_reg.rss
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag_reg.rss (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_su_tag_reg.rss Mon Aug 20 13:37:13 2007
@@ -1,3 +1,9 @@
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
+
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url.mmp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url.mmp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url.mmp Mon Aug 20 13:37:13 2007
@@ -1,4 +1,8 @@
-// sofiatest component properties
+// part of Symbian build files for sofia-sip package
+//
+// Copyright (C) 2005,2006,2007 Nokia Corporation
+// Contact: Pekka Pessi <pekka.pessi(a)nokia.com>
+// Licensed under LGPL. See file COPYING.
// General properties
TARGET torture_url.exe
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url_reg.rss
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url_reg.rss (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/open_c/group/torture_url_reg.rss Mon Aug 20 13:37:13 2007
@@ -1,3 +1,5 @@
+// sofiatest component properties
+
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/utils/Doxyfile.in
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/utils/Doxyfile.in (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/utils/Doxyfile.in Mon Aug 20 13:37:13 2007
@@ -7,23 +7,25 @@
# Licensed under LGPL. See file COPYING.
#
-PROJECT_NAME = "sofia-sip"
+PROJECT_NAME = "sofia-sip-utils"
PROJECT_NUMBER = @VERSION@
-INPUT = @srcdir@
+INPUT = @srcdir@/utils.docs
+INPUT += @srcdir@
INPUT += @top_srcdir@/libsofia-sip-ua/su/localinfo.c
INPUT += @top_srcdir@/libsofia-sip-ua/su/addrinfo.c
INPUT += @top_srcdir@/libsofia-sip-ua/stun/stunc.c
OUTPUT_DIRECTORY = ../man
+HTML_OUTPUT = ../libsofia-sip-ua/docs/html/utils
+GENERATE_TAGFILE = ../libsofia-sip-ua/docs/utils.doxytags
+
@INCLUDE_PATH = . @srcdir@
@INCLUDE = ../libsofia-sip-ua/docs/Doxyfile.aliases
-# @INCLUDE = ../libsofia-sip-ua/docs/Doxyfile.rfc
-# Only @RFC3263 is used now
-ALIASES += RFC3263="<a href=\"http://www.faqs.org/rfcs/rfc3263.html\">RFC 3263</a>"
+@INCLUDE = ../libsofia-sip-ua/docs/Doxyfile.rfc
FILE_PATTERNS = *.h *.c
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/utils/Makefile.am
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/utils/Makefile.am (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/utils/Makefile.am Mon Aug 20 13:37:13 2007
@@ -44,3 +44,7 @@
bin_PROGRAMS = sip-options sip-date sip-dig
LDADD = ../libsofia-sip-ua/libsofia-sip-ua.la $(GLIB_LIBS)
+
+# ----------------------------------------------------------------------
+# Dist and install
+EXTRA_DIST = utils.docs
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/utils/sip-options.c
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/utils/sip-options.c (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/utils/sip-options.c Mon Aug 20 13:37:13 2007
@@ -25,7 +25,7 @@
/**@page sip-options Query SIP OPTIONS
*
* @section synopsis Synopsis
- * <tt>sip-options [--bind=url] [--from=url] [-a|--all] to </tt>
+ * <tt>sip-options [OPTIONS] target-uri </tt>
*
* @section description Description
* The @em sip-options utility sends a SIP OPTIONS request (or any other SIP
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/win32/README.txt
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/win32/README.txt (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/win32/README.txt Mon Aug 20 13:37:13 2007
@@ -2,21 +2,51 @@
win32/README.txt / Sofia-SIP for win32
======================================
-The win32 subdirectory contains the build environment for Win32 environment
-using MSVC. In order to compile the code with Windows 2000 SDK you have to
-install so called "IPv6 Technology Preview for Windows 2000". The preview
-contains updated IPv6 API in <tpipv6.h> and <wspiapi.h> header files.
+The win32 subdirectory contains the build environment for Win32
+environment using MSVC.
-http://msdn.microsoft.com/downloads/sdks/platform/tpipv6.asp
+Currently, the provided workspace/solution files will create both
+shared and static libraries for libsofia-sip-ua, and a few test
+programs. The test programs can be run with the script check.cmd.
+
+Preparing the build tree
+------------------------
+
+The script autogen.cmd should be used to prepare source tree before
+compiling Sofia SIP. Note that it uses AWK, so an AWK interpreter
+is needed. You can for example use gawk (3.1.5 or newer) or mawk (tested
+with 1.3.3) implementations. Precompiled binaries are available
+for instance at:
+
+ - http://gnuwin32.sourceforge.net/packages/mawk.htm
+ - http://ftp.uni-kl.de/pub/windows/cygwin/release/gawk/
+ - plus many sites, a web search for "win32 awk" will
+ provide you many more links
+
+Notes pthread support
+---------------------
There is a pthread implementation for Visual C on Win32 included.
Source code and documentation for the pthread library can also be
downloaded from http://sources.redhat.com/pthreads-win32/.
-The script autogen.cmd should be used to prepare source tree before
-compiling Sofia SIP. Note that it uses the gawk utility - see
-http://unxutils.sourceforge.net.
+MS-VC6 specific notes
+---------------------
+
+The MSVC6 workspace file is "SofiaSIP.dsw".
+
+With Visual Studio 6, and Windows 2000 or older Platform SDK, you
+need to have so called "IPv6 Technology Preview for Windows 2000"
+installed, in order to compile Sofia-SIP. This is required even
+if IPv6 support is disabled (the socket APIs of older Platfrom SDKs
+are insufficient).
+
+You can download the preview SDK from:
+http://msdn.microsoft.com/downloads/sdks/platform/tpipv6.asp
+
+With newer Platform SDKs, the IPv6 Preview SDK is not needed.
+
+MSVC2005 specific notes
+------------------------
-Currently, the SofiaSIP.dsw workspace creates a shared library for
-sofia-sip-ua and a few test programs. The tests programs can be run
-with the script check.cmd.
+The MSVC2005 solution file is "SofiaSIP.sln".
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.dsp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.dsp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.dsp Mon Aug 20 13:37:13 2007
@@ -97,6 +97,10 @@
# End Source File
# Begin Source File
+SOURCE="..\..\libsofia-sip-ua\su\string0.c"
+# End Source File
+# Begin Source File
+
SOURCE="..\..\libsofia-sip-ua\su\su.c"
# End Source File
# Begin Source File
@@ -229,10 +233,6 @@
# End Source File
# Begin Source File
-SOURCE="..\..\libsofia-sip-ua\ipt\string0.c"
-# End Source File
-# Begin Source File
-
SOURCE="..\..\libsofia-sip-ua\ipt\token64.c"
# End Source File
# End Group
@@ -861,6 +861,10 @@
# End Source File
# Begin Source File
+SOURCE="..\..\libsofia-sip-ua\su\sofia-sip\string0.h"
+# End Source File
+# Begin Source File
+
SOURCE="..\..\libsofia-sip-ua\su\sofia-sip\su.h"
# End Source File
# Begin Source File
@@ -997,10 +1001,6 @@
# End Source File
# Begin Source File
-SOURCE="..\..\libsofia-sip-ua\ipt\sofia-sip\string0.h"
-# End Source File
-# Begin Source File
-
SOURCE="..\..\libsofia-sip-ua\ipt\sofia-sip\token64.h"
# End Source File
# End Group
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.vcproj
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.vcproj (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua-static/libsofia_sip_ua_static.vcproj Mon Aug 20 13:37:13 2007
@@ -229,6 +229,28 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\..\libsofia-sip-ua\su\string0.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="..\..\libsofia-sip-ua\su\su.c"
>
<FileConfiguration
@@ -865,28 +887,6 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\libsofia-sip-ua\ipt\string0.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
RelativePath="..\..\libsofia-sip-ua\ipt\token64.c"
>
<FileConfiguration
@@ -3825,6 +3825,10 @@
>
</File>
<File
+ RelativePath="..\..\libsofia-sip-ua\su\sofia-sip\string0.h"
+ >
+ </File>
+ <File
RelativePath="..\..\libsofia-sip-ua\su\sofia-sip\su.h"
>
</File>
@@ -3961,10 +3965,6 @@
>
</File>
<File
- RelativePath="..\..\libsofia-sip-ua\ipt\sofia-sip\string0.h"
- >
- </File>
- <File
RelativePath="..\..\libsofia-sip-ua\ipt\sofia-sip\token64.h"
>
</File>
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.dsp
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.dsp (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.dsp Mon Aug 20 13:37:13 2007
@@ -109,6 +109,10 @@
# End Source File
# Begin Source File
+SOURCE="..\..\libsofia-sip-ua\su\string0.c"
+# End Source File
+# Begin Source File
+
SOURCE="..\..\libsofia-sip-ua\su\su.c"
# End Source File
# Begin Source File
@@ -241,10 +245,6 @@
# End Source File
# Begin Source File
-SOURCE="..\..\libsofia-sip-ua\ipt\string0.c"
-# End Source File
-# Begin Source File
-
SOURCE="..\..\libsofia-sip-ua\ipt\token64.c"
# End Source File
# End Group
@@ -1009,10 +1009,6 @@
# End Source File
# Begin Source File
-SOURCE="..\..\libsofia-sip-ua\ipt\sofia-sip\string0.h"
-# End Source File
-# Begin Source File
-
SOURCE="..\..\libsofia-sip-ua\ipt\sofia-sip\token64.h"
# End Source File
# End Group
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.vcproj
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.vcproj (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/win32/libsofia-sip-ua/libsofia_sip_ua.vcproj Mon Aug 20 13:37:13 2007
@@ -272,6 +272,10 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\..\libsofia-sip-ua\su\string0.c"
+ >
+ </File>
+ <File
RelativePath="..\..\libsofia-sip-ua\su\su.c"
>
<FileConfiguration
@@ -908,28 +912,6 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\libsofia-sip-ua\ipt\string0.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
RelativePath="..\..\libsofia-sip-ua\ipt\token64.c"
>
<FileConfiguration
@@ -3868,6 +3850,10 @@
>
</File>
<File
+ RelativePath="..\..\libsofia-sip-ua\su\sofia-sip\string0.h"
+ >
+ </File>
+ <File
RelativePath="..\..\libsofia-sip-ua\su\sofia-sip\su.h"
>
</File>
@@ -4004,10 +3990,6 @@
>
</File>
<File
- RelativePath="..\..\libsofia-sip-ua\ipt\sofia-sip\string0.h"
- >
- </File>
- <File
RelativePath="..\..\libsofia-sip-ua\ipt\sofia-sip\token64.h"
>
</File>
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/win32/sofia-sip/su_configure.h
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/win32/sofia-sip/su_configure.h (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/win32/sofia-sip/su_configure.h Mon Aug 20 13:37:13 2007
@@ -45,6 +45,9 @@
#define SU_HAVE_BSDSOCK 0
#define SU_HAVE_STDINT (0)
#define SU_HAVE_NT 0
+
+/* note: on Windows 2000 and older (WINVER<=500), IPv6-tech-preview
+ * is needed for IPv4 support as well, so SU_HAVE_IN6 must be set */
#define SU_HAVE_IN6 1
#define SU_HAVE_PTHREADS (1)
Modified: freeswitch/branches/greenlizard/libs/sofia-sip/win32/utils/stunc/stunc.vcproj
==============================================================================
--- freeswitch/branches/greenlizard/libs/sofia-sip/win32/utils/stunc/stunc.vcproj (original)
+++ freeswitch/branches/greenlizard/libs/sofia-sip/win32/utils/stunc/stunc.vcproj Mon Aug 20 13:37:13 2007
@@ -48,7 +48,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..,..\..,..\..\..\libsofia-sip-ua\su,..\..\..\libsofia-sip-ua\features,..\..\..\libsofia-sip-ua\tport,..\..\..\libsofia-sip-ua\iptsec,..\..\..\libsofia-sip-ua\ipt,..\..\..\libsofia-sip-ua\url,..\..\..\libsofia-sip-ua\nta,..\..\..\libsofia-sip-ua\msg,..\..\..\libsofia-sip-ua\sip"
+ AdditionalIncludeDirectories="..;..\..;"..\..\..\libsofia-sip-ua\su";"..\..\..\libsofia-sip-ua\features";"..\..\..\libsofia-sip-ua\tport";"..\..\..\libsofia-sip-ua\iptsec";"..\..\..\libsofia-sip-ua\ipt";"..\..\..\libsofia-sip-ua\url";"..\..\..\libsofia-sip-ua\nta";"..\..\..\libsofia-sip-ua\msg";"..\..\..\libsofia-sip-ua\sip";"..\..\..\libsofia-sip-ua\stun""
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
Modified: freeswitch/branches/greenlizard/libs/win32/util.vbs
==============================================================================
--- freeswitch/branches/greenlizard/libs/win32/util.vbs (original)
+++ freeswitch/branches/greenlizard/libs/win32/util.vbs Mon Aug 20 13:37:13 2007
@@ -199,6 +199,30 @@
showpath = f.path & "\"
End Function
+
+Function FindVersionStringInConfigure(strConfigFile, strVersionString)
+
+Set objRegEx = CreateObject("VBScript.RegExp")
+objRegEx.Pattern = "[^#]AC_SUBST\(" & strVersionString & ".*\[([^\[]*)\]"
+
+Set objFSO = CreateObject("Scripting.FileSystemObject")
+Set objFile = objFSO.OpenTextFile(strConfigFile, 1)
+strSearchString = objFile.ReadAll
+objFile.Close
+
+Set colMatches = objRegEx.Execute(strSearchString)
+
+strResult = ""
+If colMatches.Count > 0 Then
+ For Each strMatch in colMatches
+ strResult = objRegEx.Replace(strMatch.Value, "$1")
+ Next
+End If
+
+ FindVersionStringInConfigure = strResult
+
+End Function
+
Sub FindReplaceInFile(FileName, sFind, sReplace)
Const OpenAsASCII = 0 ' Opens the file as ASCII (TristateFalse)
Const OpenAsUnicode = -1 ' Opens the file as Unicode (TristateTrue)
@@ -219,30 +243,43 @@
Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
Dim oExec
+
+ strVerMajor = FindVersionStringInConfigure(VersionDir & "configure.in", "SWITCH_VERSION_MAJOR")
+ strVerMinor = FindVersionStringInConfigure(VersionDir & "configure.in", "SWITCH_VERSION_MINOR")
+ strVerMicro = FindVersionStringInConfigure(VersionDir & "configure.in", "SWITCH_VERSION_MICRO")
+ strVerRev = FindVersionStringInConfigure(VersionDir & "configure.in", "SWITCH_VERSION_REVISION")
+
If Right(tmpFolder, 1) <> "\" Then tmpFolder = tmpFolder & "\" End If
If Not FSO.FileExists(tmpFolder & "svnversion.exe") Then
Wget ToolsBase & "svnversion.exe", tmpFolder
End If
Dim sLastFile
- Const OverwriteIfExist = -1
- Const ForReading = 1
- VersionCmd="svnversion " & quote & VersionDir & "." & quote & " -n"
- Set MyFile = fso.CreateTextFile(tmpFolder & "tmpVersion.Bat", True)
- MyFile.WriteLine("@" & "cd " & quote & tmpFolder & quote )
- MyFile.WriteLine("@" & VersionCmd)
- MyFile.Close
- Set oExec = WshShell.Exec("cmd /C " & quote & tmpFolder & "tmpVersion.Bat" & quote)
- Do
- strFromProc = OExec.StdOut.ReadLine()
- VERSION=strFromProc
- Loop While Not OExec.StdOut.atEndOfStream
- sLastVersion = ""
- Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII)
- If Not sLastFile.atEndOfStream Then
- sLastVersion = sLastFile.ReadLine()
- End If
- sLastFile.Close
+ Const OverwriteIfExist = -1
+ Const ForReading = 1
+
+ if strVerRev = "" Then
+ VersionCmd="svnversion " & quote & VersionDir & "." & quote & " -n"
+ Set MyFile = fso.CreateTextFile(tmpFolder & "tmpVersion.Bat", True)
+ MyFile.WriteLine("@" & "cd " & quote & tmpFolder & quote )
+ MyFile.WriteLine("@" & VersionCmd)
+ MyFile.Close
+ Set oExec = WshShell.Exec("cmd /C " & quote & tmpFolder & "tmpVersion.Bat" & quote)
+ Do
+ strFromProc = OExec.StdOut.ReadLine()
+ VERSION=strFromProc
+ Loop While Not OExec.StdOut.atEndOfStream
+ sLastVersion = ""
+ Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII)
+ If Not sLastFile.atEndOfStream Then
+ sLastVersion = sLastFile.ReadLine()
+ End If
+ sLastFile.Close
+ End If
+ if strVerRev <> "" Then
+ VERSION = strVerRev
+ End If
+
If VERSION = "" Then
VERSION = "UNKNOWN"
End If
@@ -253,7 +290,11 @@
MyFile.Close
FSO.CopyFile includebase, includedest, true
- FindReplaceInFile includedest, "@SVN_VERSION@", VERSION
+ FindReplaceInFile includedest, "@SWITCH_VERSION_REVISION@", VERSION
+ FindReplaceInFile includedest, "@SWITCH_VERSION_MAJOR@", strVerMajor
+ FindReplaceInFile includedest, "@SWITCH_VERSION_MINOR@", strVerMinor
+ FindReplaceInFile includedest, "@SWITCH_VERSION_MICRO@", strVerMicro
+
End If
End Sub
Modified: freeswitch/branches/greenlizard/scripts/socket/socket2me/socket2me.c
==============================================================================
--- freeswitch/branches/greenlizard/scripts/socket/socket2me/socket2me.c (original)
+++ freeswitch/branches/greenlizard/scripts/socket/socket2me/socket2me.c Mon Aug 20 13:37:13 2007
@@ -131,42 +131,86 @@
}
-static int cheezy_get_var(char *data, char *name, char *buf, size_t buflen)
+static void set_vars(char *data)
{
- char *p;
+ char *start, *end, *p=malloc(strlen(data)+1);
+ char name[8192],value[8192];
- if ((p = strstr(data, name))) {
- char *v, *e;
+ if(!p) {
+ perror("malloc");
+ exit(1);
+ }
+
+ memcpy(p,data,strlen(data)+1);
+ start=p;
+
+
+ while(start != 0 && *start != '\0') {
+ if(end = strchr(start,'\r')) {
+ *end = '\0';
+ if(*(end + 1) == '\n') {
+ end+=2;
+ } else {
+ end++;
+ }
+ } else {
+ return;
+ }
+
+ sscanf(start,"%s: %s",name,value);
+ setenv(name,value,1);
+ start = end;
+ }
+ free(p);
+}
- if ((v = strchr(p, ':'))) {
- v++;
- while(v && *v == ' ') {
- v++;
- }
- if (v) {
- if (!(e = strchr(v, '\r'))) {
- e = strchr(v, '\n');
- }
- }
-
- if (v && e) {
- int cplen;
- int len = e - v;
- if (len > buflen - 1) {
- cplen = buflen -1;
- } else {
- cplen = len;
- }
- strncpy(buf, v, cplen);
- *(buf+cplen) = '\0';
- return 1;
- }
+static int cheezy_get_var(char *data, char *name, char *buf, size_t buflen)
+{
+ char *p=data;
+
+ /* the old way didnt make sure that variable values were used for the name hunt
+ * and didnt ensure that only a full match of the variable name was used
+ */
+
+ do {
+ if(!strncmp(p,name,strlen(name)) && *(p+strlen(name))==':') break;
+ } while((p = (strstr(p,"\n")+1))!=(char *)1);
+
+
+ if (p != (char *)1 && *p!='\0') {
+ char *v, *e;
+
+ if ((v = strchr(p, ':'))) {
+ v++;
+ while(v && *v == ' ') {
+ v++;
+ }
+ if (v) {
+ if (!(e = strchr(v, '\r'))) {
+ e = strchr(v, '\n');
+ }
+ }
- }
+ if (v && e) {
+ int cplen;
+ int len = e - v;
+
+ if (len > buflen - 1) {
+ cplen = buflen -1;
+ } else {
+ cplen = len;
}
- return 0;
+
+ strncpy(buf, v, cplen);
+ *(buf+cplen) = '\0';
+ return 1;
+ }
+
+ }
+ }
+ return 0;
}
void client_run(int client_socket, char *local_ip, int local_port, char *remote_ip, int remote_port)
@@ -227,6 +271,12 @@
send_fax = TRUE;
}
}
+
+ if (cheezy_get_var(infobuf, "variable_fax_preexec", tmp, sizeof(tmp))) {
+ set_vars(infobuf);
+ system(tmp);
+ }
+
#if SOCKET2ME_DEBUG
printf("SEND: [%s]\n", sendbuf);
#endif
@@ -382,6 +432,10 @@
t30_terminate(&fax.t30_state);
fax_release(&fax);
+ if (cheezy_get_var(infobuf, "variable_fax_postexec", tmp, sizeof(tmp))) {
+ set_vars(infobuf);
+ system(tmp);
+ }
printf("Done\n");
snprintf(sendbuf, sizeof(sendbuf), "hangup\n\n");
send(client_socket, sendbuf, strlen(sendbuf), 0);
Modified: freeswitch/branches/greenlizard/src/include/switch_module_interfaces.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_module_interfaces.h (original)
+++ freeswitch/branches/greenlizard/src/include/switch_module_interfaces.h Mon Aug 20 13:37:13 2007
@@ -365,6 +365,7 @@
/*! The Rate */
uint32_t rate;
uint32_t speed;
+ uint32_t samples;
char voice[80];
char engine[80];
/*! the handle's memory pool */
Modified: freeswitch/branches/greenlizard/src/include/switch_types.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_types.h (original)
+++ freeswitch/branches/greenlizard/src/include/switch_types.h Mon Aug 20 13:37:13 2007
@@ -117,6 +117,8 @@
#define SWITCH_LOCAL_VIDEO_IP_VARIABLE "local_video_ip"
#define SWITCH_LOCAL_VIDEO_PORT_VARIABLE "local_video_port"
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE "hangup_after_bridge"
+#define SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE "exec_after_bridge_app"
+#define SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE "exec_after_bridge_arg"
#define SWITCH_MAX_FORWARDS_VARIABLE "max_forwards"
#define SWITCH_SPEECH_KEY "speech"
#define SWITCH_UUID_BRIDGE "uuid_bridge"
@@ -576,6 +578,7 @@
CF_UNICAST = (1 << 21) - Channel has a unicast connection
CF_VIDEO = (1 << 22) - Channel has video
CF_EVENT_LOCK = (1 << 23) - Don't parse events
+CF_RESET = (1 << 24) - Tell extension parser to reset
</pre>
*/
@@ -603,7 +606,8 @@
CF_BROADCAST = (1 << 20),
CF_UNICAST = (1 << 21),
CF_VIDEO = (1 << 22),
- CF_EVENT_LOCK = (1 << 23)
+ CF_EVENT_LOCK = (1 << 23),
+ CF_RESET = (1 << 24)
} switch_channel_flag_t;
Modified: freeswitch/branches/greenlizard/src/include/switch_utils.h
==============================================================================
--- freeswitch/branches/greenlizard/src/include/switch_utils.h (original)
+++ freeswitch/branches/greenlizard/src/include/switch_utils.h Mon Aug 20 13:37:13 2007
@@ -182,7 +182,7 @@
char *p;
for (p = s; p && *p; p++) {
uint8_t x = (uint8_t) *p;
- if (x < 32 || x > 127) {
+ if ((x < 32 || x > 127) && x != '\n' && x != '\r') {
*p = ' ';
}
}
Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c (original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_commands/mod_commands.c Mon Aug 20 13:37:13 2007
@@ -264,7 +264,7 @@
#define TONE_DETECT_SYNTAX "<uuid> <key> <tone_spec> [<flags> <timeout> <app> <args>]"
SWITCH_STANDARD_API(tone_detect_session_function)
{
- char *argv[6] = { 0 };
+ char *argv[7] = { 0 };
int argc;
char *mydata = NULL;
time_t to = 0;
@@ -1059,7 +1059,8 @@
}
snprintf(id, sizeof(id), "%d", holder->rows);
- switch_xml_set_attr_d(row, "row_id", id);
+
+ switch_xml_set_attr(switch_xml_set_flag(row, SWITCH_XML_DUP), strdup("row_id"), strdup(id));
for(x = 0; x < argc; x++) {
char *name = columnNames[x];
@@ -1229,7 +1230,8 @@
char count[50];
char *xmlstr;
snprintf(count, sizeof(count), "%d", holder.count);
- switch_xml_set_attr_d(holder.xml, "row_count", count);
+
+ switch_xml_set_attr(switch_xml_set_flag(holder.xml, SWITCH_XML_DUP), strdup("row_count"), strdup(count));
xmlstr = switch_xml_toxml(holder.xml);
if (xmlstr) {
@@ -1279,6 +1281,53 @@
return SWITCH_STATUS_SUCCESS;
}
+#define SETVAR_SYNTAX "<uuid> <var> <value>"
+SWITCH_STANDARD_API(uuid_setvar_function)
+{
+ switch_core_session_t *psession = NULL;
+ char *mycmd = NULL, *argv[3] = { 0 };
+ int argc = 0;
+
+ if (session) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (!switch_strlen_zero(cmd) && (mycmd = strdup(cmd))) {
+ argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+ if (argc == 3) {
+ char *uuid = argv[0];
+ char *var_name = argv[1];
+ char *var_value = argv[2];
+
+ if ((psession = switch_core_session_locate(uuid))) {
+ switch_channel_t *channel;
+ channel = switch_core_session_get_channel(psession);
+
+ assert(channel != NULL);
+
+ if (switch_strlen_zero(var_name)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No variable name specified.\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SET [%s]=[%s]\n", var_name, var_value ? var_value : "UNDEF");
+ switch_channel_set_variable(channel, var_name, var_value);
+ }
+
+ switch_core_session_rwunlock(psession);
+
+ } else {
+ stream->write_function(stream, "No Such Channel!\n");
+ }
+ goto done;
+ }
+ }
+
+ stream->write_function(stream, "USAGE: %s\n", SETVAR_SYNTAX);
+
+done:
+ switch_safe_free(mycmd);
+ return SWITCH_STATUS_SUCCESS;
+}
+
SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
{
switch_api_interface_t *commands_api_interface;
@@ -1296,6 +1345,7 @@
SWITCH_ADD_API(commands_api_interface, "show", "Show", show_function, SHOW_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "status", "status", status_function, "");
SWITCH_ADD_API(commands_api_interface, "uuid_bridge", "uuid_bridge", uuid_bridge_function, "");
+ SWITCH_ADD_API(commands_api_interface, "uuid_setvar", "uuid_setvar", uuid_setvar_function, SETVAR_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "session_displace", "session displace", session_displace_function, "<uuid> [start|stop] <path> [<limit>] [mux]");
SWITCH_ADD_API(commands_api_interface, "session_record", "session record", session_record_function, SESS_REC_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "broadcast", "broadcast", uuid_broadcast_function, BROADCAST_SYNTAX);
Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_conference/mod_conference.c Mon Aug 20 13:37:13 2007
@@ -4047,7 +4047,7 @@
rl++;
/* if this is not an outbound call, deal with conference pins */
- if (!switch_channel_test_flag(channel, CF_OUTBOUND) && conference->pin) {
+ if (!switch_channel_test_flag(channel, CF_OUTBOUND) && conference->pin && *(conference->pin)) {
char pin_buf[80] = "";
int pin_retries = 3; /* XXX - this should be configurable - i'm too lazy to do it right now... */
int pin_valid = 0;
@@ -4451,7 +4451,10 @@
switch_xml_t xml_kvp;
assert(conference != NULL);
- assert(xml_controls != NULL);
+
+ if (!xml_controls) {
+ return status;
+ }
/* parse the controls tree for caller control digit strings */
for (xml_kvp = switch_xml_child(xml_controls, "control"); xml_kvp; xml_kvp = xml_kvp->next) {
Modified: freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c (original)
+++ freeswitch/branches/greenlizard/src/mod/applications/mod_dptools/mod_dptools.c Mon Aug 20 13:37:13 2007
@@ -724,7 +724,9 @@
SWITCH_STANDARD_APP(system_session_function)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Executing command: %s\n",data);
- system(data);
+ if(!system(data)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Failed to execute command: %s\n",data);
+ }
}
SWITCH_STANDARD_APP(tone_detect_session_function)
@@ -953,25 +955,54 @@
switch_status_t status;
uint32_t limit = 0;
char *path;
- char *p;
switch_input_args_t args = { 0 };
-
+ switch_file_handle_t fh = { 0 };
+ int argc;
+ char *mydata, *argv[4] = { 0 };
+ char *l = NULL;
+
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
+
+ if (data && (mydata = switch_core_session_strdup(session, data))) {
+ argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No file specified.\n");
+ return;
+ }
+
+ path = argv[0];
+ l = argv[1];
- path = switch_core_session_strdup(session, data);
- if ((p = strchr(path, '+'))) {
- char *q = p - 1;
- while(q && *q == ' ') {
- *q = '\0';
- q--;
+ if (l) {
+ if (*l == '+') {
+ l++;
+ if (l) {
+ limit = atoi(l);
+ if (limit < 0) {
+ limit = 0;
+ }
+ }
+ }
+ }
+
+
+ if (argv[2]) {
+ fh.thresh = atoi(argv[2]);
+ if (fh.thresh < 0) {
+ fh.thresh = 0;
+ }
+ }
+
+ if (argv[3]) {
+ fh.silence_hits = atoi(argv[3]);
+ if (fh.silence_hits < 0) {
+ fh.silence_hits = 0;
}
- *p++ = '\0';
- limit = atoi(p);
}
args.input_callback = on_dtmf;
- status = switch_ivr_record_file(session, NULL, path, &args, limit);
+ status = switch_ivr_record_file(session, &fh, path, &args, limit);
if (!switch_channel_ready(channel) || (status != SWITCH_STATUS_SUCCESS && !SWITCH_STATUS_IS_BREAK(status))) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
@@ -1163,7 +1194,7 @@
SWITCH_ADD_APP(app_interface, "playback", "Playback File", "Playback a file to the channel", playback_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "stop_record_session", "Stop Record Session", STOP_SESS_REC_DESC, stop_record_session_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "record_session", "Record Session", SESS_REC_DESC, record_session_function, "<path>", SAF_NONE);
- SWITCH_ADD_APP(app_interface, "record", "Record File", "Record a file from the channels input", record_function, "<path> [+time_limit_ms]", SAF_NONE);
+ SWITCH_ADD_APP(app_interface, "record", "Record File", "Record a file from the channels input", record_function, "<path> [<time_limit_secs>] [<silence_thresh>] [<silence_hits>]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "stop_displace_session", "Stop Displace File", "Stop Displacing to a file", stop_displace_session_function, "<path>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "displace_session", "Displace File", DISPLACE_DESC, displace_session_function, "<path> [+time_limit_ms] [mux]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "speak", "Speak text", SPEAK_DESC, speak_function, "<engine>|<voice>|<text>", SAF_NONE);
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile Mon Aug 20 13:37:13 2007
@@ -1,33 +1,29 @@
# define these targets in your makefile if you wish
# local_all local_depend local_clean depend_install local_install local_distclean local_extraclean:
-# and define these variables to impact your build
-
-# TO GET THIS TO COMPILE
-# hack ../../../../build/modmake.rules and remove the
-# -Werror from the ALL_CFLAGS variable.
-
# TODO
-# - re-enable the -Werror flag after openmrcp compilation warnings are fixed
# - needs to compile/link against the _freeswitch_ sofia libs (see FIXME)
-# - Should this download and build openmrcp? What's the plan? (see FIXME)
-# - somehow consolidate libs and includes into less files
-# FIXME!!!
-OPENMRCP_DIR=/usr/src/openmrcp_trunk
+OPENMRCP_DIR=../../../../libs/openmrcp
OPENMRCP_INCLUDE=-I$(OPENMRCP_DIR)/mrcpcore/client/include/ -I$(OPENMRCP_DIR)/platform/openmrcpclient/include/ -I$(OPENMRCP_DIR)/mediaframe/include/ -I$(OPENMRCP_DIR)/mrcpcore/engine/include/ -I$(OPENMRCP_DIR)/mrcpcore/include/ -I$(OPENMRCP_DIR)/mrcpcore/parser/include/ -I$(OPENMRCP_DIR)/mrcpcore/server/include/ -I$(OPENMRCP_DIR)/mrcpcore/media/include/ -I$(OPENMRCP_DIR)/mrcpcore/util/include -I$(OPENMRCP_DIR)/mrcpcore/resource/include/
-OPENMRCP_LIBS=$(OPENMRCP_DIR)/platform/openmrcpclient/.libs/libopenmrcpclient.a $(OPENMRCP_DIR)/platform/openmrcpserver/.libs/libopenmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/client/.libs/libmrcpclient.a $(OPENMRCP_DIR)/mediaframe/.libs/libmediaframe.a $(OPENMRCP_DIR)/mrcpcore/engine/.libs/libmrcpengine.a $(OPENMRCP_DIR)/mrcpcore/parser/.libs/libmrcpparser.a $(OPENMRCP_DIR)/mrcpcore/server/.libs/libmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/media/.libs/libmrcpmedia.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/resource/.libs/libmrcpresource.a $(OPENMRCP_DIR)/module/plugin/demo/.libs/libdemoplugin.a $(OPENMRCP_DIR)/module/mrcpv2agent/.libs/libmrcpv2agent.a $(OPENMRCP_DIR)/module/mrcpmediaframe/.libs/libmrcpmediaframe.a $(OPENMRCP_DIR)/module/mrcpsofiasip/.libs/libmrcpsofiasip.a $(OPENMRCP_DIR)/mrcpcore/.libs/libmrcpcore.a
+OPENMRCP_LIBS=$(OPENMRCP_DIR)/platform/openmrcpclient/.libs/libopenmrcpclient.a $(OPENMRCP_DIR)/platform/openmrcpserver/.libs/libopenmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/client/.libs/libmrcpclient.a $(OPENMRCP_DIR)/mediaframe/.libs/libmediaframe.a $(OPENMRCP_DIR)/mrcpcore/engine/.libs/libmrcpengine.a $(OPENMRCP_DIR)/mrcpcore/parser/.libs/libmrcpparser.a $(OPENMRCP_DIR)/mrcpcore/server/.libs/libmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/media/.libs/libmrcpmedia.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/resource/.libs/libmrcpresource.a $(OPENMRCP_DIR)/module/plugin/demo/.libs/libdemoplugin.a $(OPENMRCP_DIR)/module/mrcpv2agent/.libs/libmrcpv2agent.a $(OPENMRCP_DIR)/module/mrcpmediaframe/.libs/libmrcpmediaframe.a $(OPENMRCP_DIR)/module/mrcpsofiasip/.libs/libmrcpsofiasip.a $(OPENMRCP_DIR)/mrcpcore/.libs/libmrcpcore.a
MRCP_APR_INCLUDES = -I../../../../libs/apr/include
MRCP_APU_INCLUDES = -I../../../../libs/apr-util/include
-MRCP_SOFIA_INCLUDES = -I/usr/local/include/sofia-sip-1.12 # FIXME!!
LOCAL_CFLAGS= -Wno-unused
-LOCAL_CFLAGS+= -Wno-comment -Wno-sign-compare $(OPENMRCP_INCLUDE) $(MRCP_APR_INCLUDES) $(MRCP_APU_INCLUDES) $(MRCP_SOFIA_INCLUDES)
+LOCAL_CFLAGS+= -Wno-comment -Wno-sign-compare $(OPENMRCP_INCLUDE) $(MRCP_APR_INCLUDES) $(MRCP_APU_INCLUDES)
+
+LOCAL_LIBADD=$(OPENMRCP_LIBS)
+
+LOCAL_INSERT_LDFLAGS=if test $$osarch = "Darwin" ; then echo "-framework CoreFoundation -framework SystemConfiguration -lssl -lcrypto" ; fi ;
-LOCAL_LDFLAGS=$(OPENMRCP_LIBS)
-VERBOSE=TRUE
include ../../../../build/modmake.rules
+$(OPENMRCP_DIR)/Makefile:
+ cd $(OPENMRCP_DIR) && ./bootstrap && ./configure --with-apr=../apr --with-apr-util=../apr-util --with-sofia-sip=../sofia-sip
+
+$(OPENMRCP_LIBS): $(OPENMRCP_DIR)/Makefile
+ cd $(OPENMRCP_DIR) && make
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Mon Aug 20 13:37:13 2007
@@ -24,6 +24,7 @@
* Contributor(s):
*
* Traun Leyden <tleyden(a)branchcut.com>
+ * Arsen Chaloyan <achaloyan(a)yahoo.com>
*
* Module which acts as an MRCP client to an MRCP speech recognition
* server. In other words it bridges freeswitch to an external speech
@@ -36,10 +37,6 @@
* TODO
* =======
*
- * - MAJOR DESIGN ISSUE!! It is way too expensive to be calling malloc on every audio frame,
- * this needs to send the packet directly. OpenMrcp will need a way to disable their own
- * timer so that the fs timer is the only one driving the media.
- *
* - There are two memory pools in use. One in asr_session which is managed
* by this module, and one in the switch_asr_handle_t, which is managed by freeswitch.
* These need to be consolidated into one. (basically throw away the one in asr_session)
@@ -50,9 +47,6 @@
* - openmrcp_flush_tts, openmrcp_text_param_tts, openmrcp_numeric_param_tts,
* openmrcp_float_param_tts need to have functionality added
*
- * - fix audio problem with TTS, convert from using queue to using a switch_buffer
- * (in progress)
- *
* - use a regex for extracting xml from raw result received from mrcp recognition
* server
*
@@ -68,21 +62,7 @@
#include "mrcp_recognizer.h"
#include "mrcp_synthesizer.h"
#include "mrcp_generic_header.h"
-#include "rtp_session.h"
-#include "mrcp_client.h"
-#include "mrcp_client_context.h"
-#include "mrcp_client_defs.h"
-#include "mrcp_client_session.h"
-#include "mrcp_client_resource.h"
-#include "mrcp_client_signaling_agent.h"
-#include "mrcp_media_agent.h"
-#include "mrcp_resource.h"
-#include "mrcp_consumer_task.h"
-#include <apr_general.h>
-#include <apr_file_io.h>
-#include <apr_thread_proc.h>
-#include <apr_thread_cond.h>
-#include <apr_strings.h>
+#include "mrcp_resource_set.h"
#include <switch.h>
@@ -95,546 +75,183 @@
SWITCH_MODULE_DEFINITION(mod_openmrcp, mod_openmrcp_load,
mod_openmrcp_shutdown, NULL);
-static struct {
- char *asr_client_ip;
- char *asr_server_ip;
- uint32_t asr_proto_version;
- uint32_t asr_client_port;
- uint32_t asr_server_port;
- char *tts_client_ip;
- char *tts_server_ip;
- uint32_t tts_proto_version;
- uint32_t tts_client_port;
- uint32_t tts_server_port;
- uint32_t rtp_port_min;
- uint32_t rtp_port_max;
-} globals;
-
-
-typedef enum {
- OPENMRCP_EVENT_NONE,
- OPENMRCP_EVENT_SESSION_INITIATE,
- OPENMRCP_EVENT_SESSION_TERMINATE,
- OPENMRCP_EVENT_CHANNEL_CREATE,
- OPENMRCP_EVENT_CHANNEL_DESTROY,
- OPENMRCP_EVENT_CHANNEL_MODIFY
-} openmrcp_event_t;
-
-static const char *openmrcp_event_names[] = {
- "NONE",
- "SESSION_INITIATE",
- "SESSION_TERMINATE",
- "CHANNEL_CREATE",
- "CHANNEL_DESTROY",
- "CHANNEL_MODIFY",
-};
+typedef struct {
+ char *name;
+ openmrcp_client_options_t *mrcp_options;
+ mrcp_client_t *mrcp_client;
+ mrcp_client_context_t *mrcp_context;
+} openmrcp_profile_t;
-typedef struct asr_session_t asr_session_t;
-struct asr_session_t {
+typedef struct {
+ openmrcp_profile_t *profile;
mrcp_session_t *client_session;
- mrcp_client_channel_t *channel;
- switch_queue_t *audio_queue;
- switch_queue_t *event_queue;
+ mrcp_client_channel_t *control_channel;
+ mrcp_audio_channel_t *audio_channel;
mrcp_message_t *mrcp_message_last_rcvd;
- audio_source_t *source;
apr_pool_t *pool;
- uint32_t flags;
+ switch_speech_flag_t flags;
switch_mutex_t *flag_mutex;
-};
-
-typedef struct tts_session_t tts_session_t;
-struct tts_session_t {
- mrcp_session_t *client_session;
- mrcp_client_channel_t *channel;
- switch_queue_t *audio_queue; // TO BE REMOVED
- switch_queue_t *event_queue;
- switch_mutex_t *audio_lock;
- switch_buffer_t *audio_buffer;
- audio_sink_t *sink;
- apr_pool_t *pool;
- switch_speech_flag_t flags;
- switch_mutex_t *flag_mutex;
-};
-
-static apr_status_t openmrcp_recognizer_read_frame(audio_source_t *source, media_frame_t *frame);
-static apr_status_t openmrcp_tts_write_frame(audio_sink_t *sink, media_frame_t *frame);
-
-static const audio_source_method_set_t audio_source_method_set = {
- NULL,
- NULL,
- NULL,
- openmrcp_recognizer_read_frame
-};
-
-static const audio_sink_method_set_t audio_sink_method_set = {
- NULL,
- NULL,
- NULL,
- openmrcp_tts_write_frame
-};
+ switch_thread_cond_t *wait_object;
+} openmrcp_session_t;
typedef enum {
- FLAG_HAS_TEXT = (1 << 0),
- FLAG_BARGE = (1 << 1),
- FLAG_READY = (1 << 2),
- FLAG_SPEAK_COMPLETE = (1 << 3)
+ FLAG_HAS_TEXT = (1 << 0),
+ FLAG_BARGE = (1 << 1),
+ FLAG_READY = (1 << 2),
+ FLAG_SPEAK_COMPLETE = (1 << 3),
+ FLAG_FEED_STARTED = (1 << 4)
} mrcp_flag_t;
typedef struct {
- mrcp_client_t *asr_client;
- mrcp_client_context_t *asr_client_context;
- mrcp_client_t *tts_client;
- mrcp_client_context_t *tts_client_context;
+ switch_memory_pool_t *pool;
+ switch_hash_t *profile_hash;
+
+ openmrcp_profile_t *asr_profile;
+ openmrcp_profile_t *tts_profile;
} openmrcp_module_t;
static openmrcp_module_t openmrcp_module;
-static asr_session_t* asr_session_create()
+
+static openmrcp_session_t* openmrcp_session_create(openmrcp_profile_t *profile)
{
- asr_session_t *asr_session;
+ openmrcp_session_t *openmrcp_session;
apr_pool_t *session_pool;
- if(apr_pool_create(&session_pool,NULL) != APR_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create session_pool\n");
+ if(!profile) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no profile specified\n");
return NULL;
}
- asr_session = apr_palloc(session_pool,sizeof(asr_session_t));
- asr_session->pool = session_pool;
- asr_session->client_session = NULL;
- asr_session->channel = NULL;
- asr_session->audio_queue = NULL;
- asr_session->event_queue = NULL;
-
-
- /* create an event queue */
- if (switch_queue_create(&asr_session->event_queue, 1000, asr_session->pool)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "event queue creation failed\n");
- }
-
- return asr_session;
-}
-
-
-static tts_session_t* tts_session_create()
-{
- tts_session_t *tts_session;
- apr_pool_t *session_pool;
-
if(apr_pool_create(&session_pool,NULL) != APR_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create session_pool\n");
return NULL;
}
- tts_session = apr_palloc(session_pool,sizeof(tts_session_t));
- tts_session->pool = session_pool;
- tts_session->client_session = NULL;
- tts_session->channel = NULL;
- tts_session->audio_queue = NULL;
- tts_session->event_queue = NULL;
-
- /* create an event queue */
- if (switch_queue_create(&tts_session->event_queue, 1000, tts_session->pool)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "event queue creation failed\n");
+ openmrcp_session = apr_palloc(session_pool,sizeof(openmrcp_session_t));
+ openmrcp_session->pool = session_pool;
+ openmrcp_session->profile = profile;
+ openmrcp_session->client_session = NULL;
+ openmrcp_session->control_channel = NULL;
+ openmrcp_session->audio_channel = NULL;
+ openmrcp_session->mrcp_message_last_rcvd = NULL;
+
+ switch_mutex_init(&openmrcp_session->flag_mutex, SWITCH_MUTEX_NESTED, openmrcp_session->pool);
+
+ if (switch_thread_cond_create(&openmrcp_session->wait_object, openmrcp_session->pool)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "wait object creation failed\n");
+ }
+
+ openmrcp_session->client_session = mrcp_client_context_session_create(openmrcp_session->profile->mrcp_context,openmrcp_session);
+ if (!openmrcp_session->client_session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "session creation FAILED\n");
+ apr_pool_destroy(session_pool);
+ return NULL;
}
- return tts_session;
+ return openmrcp_session;
}
-
-static mrcp_status_t asr_session_destroy(asr_session_t *asr_session)
+static void openmrcp_session_destroy(openmrcp_session_t *openmrcp_session)
{
- if(!asr_session) {
- return MRCP_STATUS_FAILURE;
- }
-
- if(asr_session->pool) {
- apr_pool_destroy(asr_session->pool);
- asr_session->pool = NULL;
+ if(openmrcp_session && openmrcp_session->pool) {
+ mrcp_client_context_session_destroy(openmrcp_session->profile->mrcp_context,openmrcp_session->client_session);
+ apr_pool_destroy(openmrcp_session->pool);
}
- return MRCP_STATUS_SUCCESS;
}
-
-static mrcp_status_t tts_session_destroy(tts_session_t *tts_session)
+static mrcp_status_t openmrcp_on_session_initiate(mrcp_client_context_t *context, mrcp_session_t *session)
{
- if(!tts_session) {
- return MRCP_STATUS_FAILURE;
- }
-
- switch_buffer_destroy(&tts_session->audio_buffer);
-
- if(tts_session->pool) {
- apr_pool_destroy(tts_session->pool);
- tts_session->pool = NULL;
- }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_session_initiate called\n");
return MRCP_STATUS_SUCCESS;
}
-
-static mrcp_status_t wait_for_event(switch_queue_t *event_queue, openmrcp_event_t openmrcp_event, size_t timeout)
-{
-
- openmrcp_event_t *popped_event = NULL;
- size_t sleep_ms = 100;
-
- if(event_queue) {
- if (switch_queue_trypop(event_queue, (void *) &popped_event)) {
- // most likely this failed because queue is empty. sleep for timeout seconds and try again?
- if (timeout > 0) {
- if (timeout < sleep_ms) {
- switch_sleep(timeout * 1000); // ms->us
- timeout = 0;
- }
- else {
- switch_sleep(sleep_ms * 1000); // ms->us
- timeout -= sleep_ms;
- }
-
- // call recursively
- // TODO: This is going to end up in a lot of recursion and
- // maybe blow the stack .. rethink this approach
- return wait_for_event(event_queue, openmrcp_event, timeout);
-
- }
- else {
- // nothing in queue, no timeout left, return failure
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "nothing in queue, no timeout left, return failure\n");
- return MRCP_STATUS_FAILURE;
- }
-
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "popped event\n");
- // check if popped event matches the event we are looking for
- if (*popped_event == openmrcp_event) {
- // just what we were waiting for!
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "just what we were waiting for! rturn success\n");
- return MRCP_STATUS_SUCCESS;
- }
- else {
- // nothing popped, but maybe there's other things in queue, or something will arrive
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "popped unexpected\n");
- if (!popped_event) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "popped NULL!!\n");
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "popped: %d\n", *popped_event);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "popped name: %s\n", openmrcp_event_names[*popped_event]);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "popped [%s] but was expecting [%s], but maybe there's other things in queue, or something will arrive\n", openmrcp_event_names[*popped_event], openmrcp_event_names[openmrcp_event]);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "calling recursively\n");
- return wait_for_event(event_queue, openmrcp_event, timeout);
- }
-
- }
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "event queue is null\n");
- return MRCP_STATUS_FAILURE;
- }
-
-}
-
-
-static mrcp_status_t asr_session_signal_event(asr_session_t *asr_session, openmrcp_event_t openmrcp_event)
-{
- mrcp_status_t status = MRCP_STATUS_SUCCESS;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got event: %s\n", openmrcp_event_names[openmrcp_event]);
-
-
- // allocate memory for event
- openmrcp_event_t *event2queue = (openmrcp_event_t *) switch_core_alloc(asr_session->pool, sizeof(openmrcp_event_t));
- *event2queue = openmrcp_event;
-
- // add it to queue
- if (switch_queue_trypush(asr_session->event_queue, (void *) event2queue)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "could not push event to queue\n");
- status = SWITCH_STATUS_GENERR;
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "pushed event to queue: %s\n", openmrcp_event_names[*event2queue]);
- }
-
- return status;
-}
-
-
-static mrcp_status_t asr_on_session_initiate(mrcp_client_context_t *context, mrcp_session_t *session)
+static mrcp_status_t openmrcp_on_session_terminate(mrcp_client_context_t *context, mrcp_session_t *session)
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "asr_on_session_initiate called\n");
- asr_session_t *asr_session = mrcp_client_context_session_object_get(session);
- if(!asr_session) {
+ openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_session_terminate called\n");
+ if(!openmrcp_session) {
return MRCP_STATUS_FAILURE;
}
- return asr_session_signal_event(asr_session,OPENMRCP_EVENT_SESSION_INITIATE);
-}
-
-static mrcp_status_t asr_on_session_terminate(mrcp_client_context_t *context, mrcp_session_t *session)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "asr_on_session_terminate called\n");
- asr_session_t *asr_session = mrcp_client_context_session_object_get(session);
- if(!asr_session) {
- return MRCP_STATUS_FAILURE;
- }
- return asr_session_signal_event(asr_session,OPENMRCP_EVENT_SESSION_TERMINATE);
+ openmrcp_session_destroy(openmrcp_session);
+ return MRCP_STATUS_SUCCESS;
}
-static mrcp_status_t asr_on_channel_add(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *channel)
+static mrcp_status_t openmrcp_on_channel_add(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *control_channel, mrcp_audio_channel_t *audio_channel)
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "asr_on_channel_add called\n");
- asr_session_t *asr_session = mrcp_client_context_session_object_get(session);
- if(!asr_session) {
+ openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_channel_add called\n");
+ if(!openmrcp_session) {
return MRCP_STATUS_FAILURE;
}
- return asr_session_signal_event(asr_session,OPENMRCP_EVENT_CHANNEL_CREATE);
+ switch_mutex_lock(openmrcp_session->flag_mutex);
+ openmrcp_session->control_channel = control_channel;
+ openmrcp_session->audio_channel = audio_channel;
+ switch_thread_cond_signal(openmrcp_session->wait_object);
+ switch_mutex_unlock(openmrcp_session->flag_mutex);
+ return MRCP_STATUS_SUCCESS;
}
-static mrcp_status_t asr_on_channel_remove(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *channel)
+static mrcp_status_t openmrcp_on_channel_remove(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *control_channel)
{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "asr_on_channel_remove called\n");
- asr_session_t *asr_session = mrcp_client_context_session_object_get(session);
- if(!asr_session) {
- return MRCP_STATUS_FAILURE;
- }
- return asr_session_signal_event(asr_session,OPENMRCP_EVENT_CHANNEL_DESTROY);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "on_channel_remove called\n");
+ return MRCP_STATUS_SUCCESS;
}
/** this is called by the mrcp core whenever an mrcp message is received from
the other side. */
-static mrcp_status_t asr_on_channel_modify(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_message_t *mrcp_message)
+static mrcp_status_t openmrcp_on_channel_modify(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_message_t *mrcp_message)
{
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "asr_on_channel_modify called\n");
- asr_session_t *asr_session = mrcp_client_context_session_object_get(session);
- if(!asr_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!asr_session\n");
+ openmrcp_session_t *openmrcp_session = mrcp_client_context_session_object_get(session);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "on_channel_modify called\n");
+ if (!openmrcp_session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!openmrcp_session\n");
return MRCP_STATUS_FAILURE;
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mrcp msg body: %s\n", mrcp_message->body);
-
- if (!strcmp(mrcp_message->start_line.method_name,"RECOGNITION-COMPLETE")) {
- asr_session->mrcp_message_last_rcvd = mrcp_message;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_HAS_TEXT\n");
- switch_set_flag_locked(asr_session, FLAG_HAS_TEXT);
- }
- else if (!strcmp(mrcp_message->start_line.method_name,"START-OF-SPEECH")) {
- asr_session->mrcp_message_last_rcvd = mrcp_message;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_BARGE\n");
- switch_set_flag_locked(asr_session, FLAG_BARGE);
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring method: %s\n", mrcp_message->start_line.method_name);
- }
-
- return asr_session_signal_event(asr_session,OPENMRCP_EVENT_CHANNEL_MODIFY);
-}
-
-
-
-static mrcp_status_t tts_session_signal_event(tts_session_t *tts_session, openmrcp_event_t openmrcp_event)
-{
- mrcp_status_t status = MRCP_STATUS_SUCCESS;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got event: %s\n", openmrcp_event_names[openmrcp_event]);
-
- // allocate memory for event
- openmrcp_event_t *event2queue = (openmrcp_event_t *) switch_core_alloc(tts_session->pool, sizeof(openmrcp_event_t));
- *event2queue = openmrcp_event;
-
- // add it to queue
- if (switch_queue_trypush(tts_session->event_queue, (void *) event2queue)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "could not push event to queue\n");
- status = SWITCH_STATUS_GENERR;
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "pushed event to queue: %s\n", openmrcp_event_names[*event2queue]);
- }
-
- return status;
-}
-
-static mrcp_status_t tts_on_session_initiate(mrcp_client_context_t *context, mrcp_session_t *session)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tts_on_session_initiate called\n");
- tts_session_t *tts_session = mrcp_client_context_session_object_get(session);
- if(!tts_session) {
- return MRCP_STATUS_FAILURE;
- }
- return tts_session_signal_event(tts_session,OPENMRCP_EVENT_SESSION_INITIATE);
-}
-
-static mrcp_status_t tts_on_session_terminate(mrcp_client_context_t *context, mrcp_session_t *session)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tts_on_session_terminate called\n");
- tts_session_t *tts_session = mrcp_client_context_session_object_get(session);
- if(!tts_session) {
- return MRCP_STATUS_FAILURE;
- }
- return tts_session_signal_event(tts_session,OPENMRCP_EVENT_SESSION_TERMINATE);
-}
-
-static mrcp_status_t tts_on_channel_add(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *channel)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tts_on_channel_add called\n");
- tts_session_t *tts_session = mrcp_client_context_session_object_get(session);
- if(!tts_session) {
+ if (!mrcp_message) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!mrcp_message\n");
return MRCP_STATUS_FAILURE;
}
- return tts_session_signal_event(tts_session,OPENMRCP_EVENT_CHANNEL_CREATE);
-}
-static mrcp_status_t tts_on_channel_remove(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_client_channel_t *channel)
-{
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "tts_on_channel_remove called\n");
- tts_session_t *tts_session = mrcp_client_context_session_object_get(session);
- if(!tts_session) {
- return MRCP_STATUS_FAILURE;
+ if (mrcp_message->start_line.message_type != MRCP_MESSAGE_TYPE_EVENT) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ignoring mrcp response\n");
+ return MRCP_STATUS_SUCCESS;
}
- return tts_session_signal_event(tts_session,OPENMRCP_EVENT_CHANNEL_DESTROY);
-}
-/** this is called by the mrcp core whenever an mrcp message is received from
- the other side. */
-static mrcp_status_t tts_on_channel_modify(mrcp_client_context_t *context, mrcp_session_t *session, mrcp_message_t *mrcp_message)
-{
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "tts_on_channel_modify called\n");
- tts_session_t *tts_session = mrcp_client_context_session_object_get(session);
- if(!tts_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!tts_session\n");
- return MRCP_STATUS_FAILURE;
- }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mrcp msg body: %s\n", mrcp_message->body);
- if (mrcp_message->start_line.method_name) {
- if (!strcmp(mrcp_message->start_line.method_name,"SPEAK-COMPLETE")) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setting FLAG_SPEAK_COMPLETE\n");
- switch_set_flag_locked(tts_session, FLAG_SPEAK_COMPLETE);
+ if (mrcp_message->channel_id.resource_id == MRCP_RESOURCE_RECOGNIZER) {
+ if (mrcp_message->start_line.method_id == RECOGNIZER_RECOGNITION_COMPLETE) {
+ openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_HAS_TEXT\n");
+ switch_set_flag_locked(openmrcp_session, FLAG_HAS_TEXT);
+ }
+ else if (mrcp_message->start_line.method_id == RECOGNIZER_START_OF_INPUT) {
+ openmrcp_session->mrcp_message_last_rcvd = mrcp_message;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting FLAG_BARGE\n");
+ switch_set_flag_locked(openmrcp_session, FLAG_BARGE);
}
else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring method: %s\n", mrcp_message->start_line.method_name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
}
}
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mrcp msg body: %s\n", mrcp_message->body);
-
-
-
- return tts_session_signal_event(tts_session,OPENMRCP_EVENT_CHANNEL_MODIFY);
-}
-
-
-
-static apr_status_t set_default_asr_options(openmrcp_client_options_t *options)
-{
- mrcp_logger.priority = MRCP_PRIO_INFO;
- options->proto_version = globals.asr_proto_version;
- options->client_ip = globals.asr_client_ip;
- options->server_ip = globals.asr_server_ip;
- options->client_port = globals.asr_client_port;
- options->server_port = globals.asr_server_port;
- options->rtp_port_min = globals.rtp_port_min;
- options->rtp_port_max = globals.rtp_port_max;
- return APR_SUCCESS;
-}
-
-
-static apr_status_t set_default_tts_options(openmrcp_client_options_t *options)
-{
- mrcp_logger.priority = MRCP_PRIO_INFO;
- options->proto_version = globals.tts_proto_version;
- options->client_ip = globals.tts_client_ip;
- options->server_ip = globals.tts_server_ip;
- options->client_port = globals.tts_client_port;
- options->server_port = globals.tts_server_port;
- options->rtp_port_min = globals.rtp_port_min;
- options->rtp_port_max = globals.rtp_port_max;
- return APR_SUCCESS;
-}
-
-
-/**
- * Called back by openmrcp client thread every time it receives audio
- * from the TTS server we are connected to. Puts audio in a queueu
- * and it will be pulled out from read_tts
- */
-static apr_status_t openmrcp_tts_write_frame(audio_sink_t *sink, media_frame_t *frame)
-{
- tts_session_t *tts_session = sink->object;
- media_frame_t *media_frame;
- switch_byte_t *buffer;
- size_t len;
-
- len = frame->codec_frame.size;
-
- /* create new media frame */
- media_frame = (media_frame_t *) switch_core_alloc(tts_session->pool, sizeof(media_frame_t));
- if (!media_frame) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "media_frame creation failed\n");
- return SWITCH_STATUS_MEMERR;
- }
-
- /**
- * since *frame might get freed by caller (true or false?), allocate a
- * new buffer and copy *data into it.
- **/
- buffer = (switch_byte_t *) switch_core_alloc(tts_session->pool, sizeof(switch_byte_t)*len);
- if (!buffer) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate buffer\n");
- return SWITCH_STATUS_MEMERR;
- }
- buffer = memcpy(buffer, frame->codec_frame.buffer, len);
- media_frame->codec_frame.buffer = buffer;
- media_frame->codec_frame.size = len;
- media_frame->type = MEDIA_FRAME_TYPE_AUDIO;
-
-
- /* push audio to queue */
- if (switch_queue_trypush(tts_session->audio_queue, (void *) media_frame)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "could not push audio to queue\n");
- return MRCP_STATUS_FAILURE;
- }
-
- return MRCP_STATUS_SUCCESS;
-
-}
-
-
-/**
- * Called back by openmcp client thread every time its ready for more audio to send
- * the recognition server we are connected to. Reads data that was put into a
- * shared fifo queue upon receiving audio frames from asr_feed()
- */
-static apr_status_t openmrcp_recognizer_read_frame(audio_source_t *source, media_frame_t *frame)
-{
- asr_session_t *asr_session = source->object;
- frame->type = MEDIA_FRAME_TYPE_NONE;
- apr_status_t result;
- media_frame_t *queue_frame = NULL;
-
- /* pop next media frame data from incoming queue into frame */
- if(asr_session->audio_queue) {
- if (switch_queue_trypop(asr_session->audio_queue, (void *) &queue_frame)) {
- // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "could not pop from queue\n");
- result = MRCP_STATUS_FAILURE;
+ else if(mrcp_message->channel_id.resource_id == MRCP_RESOURCE_SYNTHESIZER) {
+ if (mrcp_message->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setting FLAG_SPEAK_COMPLETE\n");
+ switch_set_flag_locked(openmrcp_session, FLAG_SPEAK_COMPLETE);
}
else {
- frame->codec_frame.size = queue_frame->codec_frame.size;
- frame->codec_frame.buffer = queue_frame->codec_frame.buffer;
- frame->type = MEDIA_FRAME_TYPE_AUDIO;
- result = APR_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring event: %s\n", mrcp_message->start_line.method_name);
}
}
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no audio queue\n");
- result = MRCP_STATUS_FAILURE;
- }
-
- return result;
+
+ return MRCP_STATUS_SUCCESS;
}
/** Read in the grammar and construct an MRCP Recognize message that has
The grammar attached as the payload */
-static mrcp_status_t openmrcp_recog_start(mrcp_client_context_t *context, asr_session_t *asr_session, char *path)
+static mrcp_status_t openmrcp_recog_start(mrcp_client_context_t *context, openmrcp_session_t *asr_session, char *path)
{
-
mrcp_generic_header_t *generic_header;
apr_status_t rv;
apr_file_t *fp;
@@ -643,7 +260,7 @@
char *buf1;
apr_size_t bytes2read = 0;
- mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context, asr_session->client_session, asr_session->channel, RECOGNIZER_RECOGNIZE);
+ mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context, asr_session->client_session, asr_session->control_channel, RECOGNIZER_RECOGNIZE);
if(!mrcp_message) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not create mrcp msg\n");
@@ -658,8 +275,8 @@
}
rv = apr_file_info_get(&finfo, APR_FINFO_NORM, fp);
- buf1 = apr_palloc(mp, finfo.size);
- bytes2read = finfo.size;
+ buf1 = apr_palloc(mp, (apr_size_t)finfo.size);
+ bytes2read = (apr_size_t)finfo.size;
rv = apr_file_read(fp, buf1, &bytes2read);
generic_header = mrcp_generic_header_prepare(mrcp_message);
if(!generic_header) {
@@ -672,7 +289,6 @@
/* send the MRCP RECOGNIZE message to MRCP server */
return mrcp_client_context_channel_modify(context, asr_session->client_session, mrcp_message);
-
}
@@ -686,25 +302,11 @@
*/
static switch_status_t openmrcp_asr_open(switch_asr_handle_t *ah, char *codec, int rate, char *dest, switch_asr_flag_t *flags)
{
- mrcp_client_context_t *asr_client_context = openmrcp_module.asr_client_context ;
- asr_session_t *asr_session;
- audio_source_t *source;
+ openmrcp_session_t *asr_session;
+ mrcp_client_channel_t *asr_channel;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "asr_open called, codec: %s, rate: %d\n", codec, rate);
- /*!
- NOTE: According to the current FS media bugs design, the media bug can only feed audio
- data in SLIN (L16) format. So we dont need to worry about other codecs.
-
- NOTE: forcing MRCP to use 20 as the CODEC_FRAME_TIME_BASE effectively ensures
- that it matches with 16-bit audio at 8kz with 320 byte frames. in testing, leaving
- CODEC_FRAME_TIME_BASE at 10 and using pop (instead of trypop) in
- openmrcp_recognizer_read_frame() actually produces clean audio, however it causes
- other problems as the full channel/session cleanup never completes in openmrcp, most
- likely due to a thread being blocked on a pop call from audio queue. but with trypop
- (to avoid the cleanup problem), it only produces clean audio when CODEC_FRAME_TIME_BASE
- is set to 20.
- */
if (strcmp(codec,"L16")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sorry, only L16 codec supported\n");
return SWITCH_STATUS_GENERR;
@@ -714,49 +316,35 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sorry, only 8kz supported\n");
return SWITCH_STATUS_GENERR;
}
- if (CODEC_FRAME_TIME_BASE != 20) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "You must recompile openmrcp with #define CODEC_FRAME_TIME_BASE 20\n");
- return SWITCH_STATUS_GENERR;
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CODEC_FRAME_TIME_BASE: %d\n", CODEC_FRAME_TIME_BASE);
- }
-
/* create session */
- asr_session = asr_session_create();
+ asr_session = openmrcp_session_create(openmrcp_module.asr_profile);
if (!asr_session) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_session creation FAILED\n");
return SWITCH_STATUS_GENERR;
}
- asr_session->client_session = mrcp_client_context_session_create(asr_client_context,asr_session);
- if (!asr_session->client_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_session creation FAILED\n");
- return SWITCH_STATUS_GENERR;
+
+ /* create recognizer channel, also starts outgoing rtp media */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Create Recognizer Channel\n");
+ asr_channel = mrcp_client_recognizer_channel_create(asr_session->profile->mrcp_context, asr_session->client_session, NULL);
+ if (!asr_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create recognizer channel\n");
+ return SWITCH_STATUS_FALSE;
}
- /* create audio source */
- source = mrcp_palloc(asr_session->pool,sizeof(audio_source_t));
- source->method_set = &audio_source_method_set;
- source->object = asr_session;
- asr_session->source = source;
-
- /**
- * create a new fifo queue. incoming audio received from freeswitch
- * will be put into this queue, and it will be later pulled out by
- * the openmrcp client thread.
- */
- if (switch_queue_create(&asr_session->audio_queue, 10000, asr_session->pool)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "audio queue creation failed\n");
- return SWITCH_STATUS_MEMERR;
+ switch_mutex_lock(asr_session->flag_mutex);
+ mrcp_client_context_channel_add(asr_session->profile->mrcp_context, asr_session->client_session, asr_channel, NULL);
+ if(switch_thread_cond_timedwait(asr_session->wait_object,asr_session->flag_mutex,5000*1000) != APR_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No response from client stack\n");
+ }
+ switch_mutex_unlock(asr_session->flag_mutex);
+ if(!asr_session->control_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No recognizer channel available\n");
+ return SWITCH_STATUS_FALSE;
}
-
- asr_session->flags = *flags;
- switch_mutex_init(&asr_session->flag_mutex, SWITCH_MUTEX_NESTED, asr_session->pool);
+ asr_session->flags = *flags;
ah->private_info = asr_session;
-
return SWITCH_STATUS_SUCCESS;
-
}
/* function to load a grammar to the asr interface */
@@ -768,87 +356,41 @@
TODO: - how does DEFINE-GRAMMAR fit into the picture here? (if at all)
*/
- asr_session_t *asr_session = (asr_session_t *) ah->private_info;
- mrcp_client_context_t *asr_client_context = openmrcp_module.asr_client_context;
- audio_source_t *source = asr_session->source;
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+ mrcp_client_context_t *context = asr_session->profile->mrcp_context;
- /* create recognizer channel, also starts outgoing rtp media */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Loading grammar\n");
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Create Recognizer Channel\n");
- asr_session->channel = mrcp_client_recognizer_channel_create(asr_client_context, asr_session->client_session, source);
-
- if (!asr_session->channel) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create recognizer channel\n");
- return SWITCH_STATUS_FALSE;
- }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Start Recognizer\n");
+ openmrcp_recog_start(context, asr_session, path);
- /* wait for recognizer channel creation */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "WAITING FOR CHAN CREATE\n");
- if(wait_for_event(asr_session->event_queue, OPENMRCP_EVENT_CHANNEL_CREATE, OPENMRCP_WAIT_TIMEOUT) == MRCP_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got channel creation event\n");
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "WAITING FOR NONE\n");
- if (wait_for_event(asr_session->event_queue,OPENMRCP_EVENT_NONE,200) == MRCP_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "GOT NONE EVENT\n");
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "NEVER GOT NONE EVENT\n");
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Start Recognizer\n");
- openmrcp_recog_start(asr_client_context, asr_session, path);
-
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "never got channel creation event\n");
- }
-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Finished loading grammar\n");
return SWITCH_STATUS_SUCCESS;
}
-
/*! function to feed audio to the ASR*/
static switch_status_t openmrcp_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags)
{
-
- asr_session_t *asr_session = (asr_session_t *) ah->private_info;
- media_frame_t *media_frame;
- switch_byte_t *buffer;
-
- /* create new media frame */
- media_frame = (media_frame_t *) switch_core_alloc(asr_session->pool, sizeof(media_frame_t));
- if (!media_frame) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "media_frame creation failed\n");
- return SWITCH_STATUS_MEMERR;
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+ media_frame_t media_frame;
+ audio_sink_t *audio_sink = mrcp_client_audio_sink_get(asr_session->audio_channel);
+
+ media_frame.type = MEDIA_FRAME_TYPE_AUDIO;
+ /* sampling rate and frame size should be retrieved from audio sink */
+ media_frame.codec_frame.size = 160;
+ media_frame.codec_frame.buffer = data;
+ while(len >= media_frame.codec_frame.size) {
+ if (!audio_sink) {
+ return SWITCH_STATUS_GENERR;
+ }
+ audio_sink->method_set->write_frame(audio_sink,&media_frame);
+
+ len -= (unsigned int)media_frame.codec_frame.size;
+ media_frame.codec_frame.buffer = (char*)media_frame.codec_frame.buffer + media_frame.codec_frame.size;
}
-
- /**
- * since *data buffer might get freed by caller (true or false?), allocate a
- * new buffer and copy *data into it.
- *
- * MAJOR DESIGN ISSUE!! It is way too expensive to be calling malloc on every audio frame,
- * this needs to send the packet directly. OpenMrcp will need a way to disable their own
- * timer so that the fs timer is the only one driving the media.
- **/
- buffer = (switch_byte_t *) switch_core_alloc(asr_session->pool, sizeof(switch_byte_t)*len);
- if (!buffer) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate buffer\n");
- return SWITCH_STATUS_MEMERR;
+ if(len > 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "None frame alligned data len [%d]\n",len);
}
- buffer = memcpy(buffer, data, len);
-
- media_frame->codec_frame.buffer = buffer;
- media_frame->codec_frame.size = len;
- media_frame->type = MEDIA_FRAME_TYPE_AUDIO;
-
- /* push audio to queue */
- if (switch_queue_trypush(asr_session->audio_queue, (void *) media_frame)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "could not push audio to queue\n");
- return SWITCH_STATUS_GENERR;
- }
-
return SWITCH_STATUS_SUCCESS;
}
@@ -884,42 +426,18 @@
*/
static switch_status_t openmrcp_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
{
- asr_session_t *asr_session = (asr_session_t *) ah->private_info;
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
+ mrcp_client_context_t *context = asr_session->profile->mrcp_context;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_close()\n");
- mrcp_client_context_t *context = openmrcp_module.asr_client_context;
-
// TODO!! should we do a switch_pool_clear(switch_memory_pool_t *p) on the pool held
// by asr_session?
- // destroy channel
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Going to DESTROY CHANNEL\n");
- mrcp_client_context_channel_destroy(context, asr_session->client_session, asr_session->channel);
- if (wait_for_event(asr_session->event_queue,OPENMRCP_EVENT_CHANNEL_DESTROY,10000) == MRCP_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "OPENMRCP_EVENT_CHANNEL_DESTROY received\n");
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "timed out waiting for OPENMRCP_EVENT_CHANNEL_DESTROY\n");
- }
-
// terminate client session
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Going to TERMINATE SESSION\n");
mrcp_client_context_session_terminate(context, asr_session->client_session);
- if (wait_for_event(asr_session->event_queue,OPENMRCP_EVENT_SESSION_TERMINATE,10000) == MRCP_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "OPENMRCP_EVENT_SESSION_TERMINATE recevied\n");
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "timed out waiting for OPENMRCP_EVENT_SESSION_TERMINATE\n");
- }
- // destroy client session (NOTE: this sends a BYE to the other side)
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Going to DESTROY SESSION\n");
- mrcp_client_context_session_destroy(context, asr_session->client_session);
-
- // destroys the asr_session struct
- asr_session_destroy(asr_session);
-
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
return SWITCH_STATUS_SUCCESS;
@@ -934,7 +452,7 @@
*/
static switch_status_t openmrcp_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
{
- asr_session_t *asr_session = (asr_session_t *) ah->private_info;
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
switch_status_t rv = (switch_test_flag(asr_session, FLAG_HAS_TEXT) || switch_test_flag(asr_session, FLAG_BARGE)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
@@ -944,9 +462,9 @@
/*! This will be called after asr_check_results returns SUCCESS */
static switch_status_t openmrcp_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags)
{
- asr_session_t *asr_session = (asr_session_t *) ah->private_info;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_get_results called\n");
+ openmrcp_session_t *asr_session = (openmrcp_session_t *) ah->private_info;
switch_status_t ret = SWITCH_STATUS_SUCCESS;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "openmrcp_asr_get_results called\n");
if (switch_test_flag(asr_session, FLAG_BARGE)) {
switch_clear_flag_locked(asr_session, FLAG_BARGE);
@@ -989,10 +507,11 @@
}
-static mrcp_status_t synth_speak(mrcp_client_context_t *context, tts_session_t *tts_session, char *text)
+static mrcp_status_t synth_speak(mrcp_client_context_t *context, openmrcp_session_t *tts_session, char *text)
{
+ mrcp_generic_header_t *generic_header;
+ mrcp_message_t *mrcp_message;
- //buffer = (switch_byte_t *) switch_core_alloc(asr_session->pool, sizeof(switch_byte_t)*len);
char *text2speak;
const char xml_head[] =
"<?xml version=\"1.0\"?>\r\n"
@@ -1010,8 +529,7 @@
strcat(text2speak, text);
strcat(text2speak, xml_tail);
- mrcp_generic_header_t *generic_header;
- mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->channel,SYNTHESIZER_SPEAK);
+ mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->control_channel,SYNTHESIZER_SPEAK);
if(!mrcp_message) {
return MRCP_STATUS_FAILURE;
}
@@ -1028,9 +546,9 @@
return mrcp_client_context_channel_modify(context,tts_session->client_session,mrcp_message);
}
-static mrcp_status_t synth_stop(mrcp_client_context_t *context, tts_session_t *tts_session)
+static mrcp_status_t synth_stop(mrcp_client_context_t *context, openmrcp_session_t *tts_session)
{
- mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->channel,SYNTHESIZER_STOP);
+ mrcp_message_t *mrcp_message = mrcp_client_context_message_get(context,tts_session->client_session,tts_session->control_channel,SYNTHESIZER_STOP);
if(!mrcp_message) {
return MRCP_STATUS_FAILURE;
}
@@ -1041,107 +559,63 @@
static switch_status_t openmrcp_tts_open(switch_speech_handle_t *sh, char *voice_name, int rate, switch_speech_flag_t *flags)
{
-
- tts_session_t *tts_session;
- audio_sink_t *sink;
- mrcp_client_context_t *tts_client_context = openmrcp_module.tts_client_context ;
+ openmrcp_session_t *tts_session;
+ mrcp_client_channel_t *tts_channel;
/* create session */
- tts_session = tts_session_create();
+ tts_session = openmrcp_session_create(openmrcp_module.tts_profile);
if (!tts_session) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "tts_session creation FAILED\n");
return SWITCH_STATUS_GENERR;
}
- tts_session->client_session = mrcp_client_context_session_create(tts_client_context,tts_session);
- if (!tts_session->client_session) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "tts_session creation FAILED\n");
- return SWITCH_STATUS_GENERR;
- }
-
- /* create audio sink */
- sink = mrcp_palloc(tts_session->pool,sizeof(audio_sink_t));
- sink->method_set = &audio_sink_method_set;
- sink->object = tts_session;
- tts_session->sink = sink;
-
-
- /**
- * create a new fifo queue.
- */
- if (switch_queue_create(&tts_session->audio_queue, 10000, tts_session->pool)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "audio queue creation failed\n");
- return SWITCH_STATUS_MEMERR;
+ /* create synthesizer channel */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Create Synthesizer Channel\n");
+ tts_channel = mrcp_client_synthesizer_channel_create(tts_session->profile->mrcp_context, tts_session->client_session, NULL);
+ if (!tts_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create synthesizer channel\n");
+ return SWITCH_STATUS_FALSE;
}
-
- /* create mutex that will be used to lock audio buffer */
- switch_mutex_init(&tts_session->audio_lock, SWITCH_MUTEX_NESTED, sh->memory_pool);
-
- /* create audio buffer */
- if (switch_buffer_create_dynamic(&tts_session->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Creation Failed!\n");
- return SWITCH_STATUS_MEMERR;
+ switch_mutex_lock(tts_session->flag_mutex);
+ mrcp_client_context_channel_add(tts_session->profile->mrcp_context, tts_session->client_session, tts_channel, NULL);
+ if(switch_thread_cond_timedwait(tts_session->wait_object,tts_session->flag_mutex,5000*1000) != APR_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No response from client stack\n");
+ }
+ switch_mutex_unlock(tts_session->flag_mutex);
+ if(!tts_session->control_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No synthesizer channel available\n");
+ return SWITCH_STATUS_FALSE;
}
-
tts_session->flags = *flags;
- switch_mutex_init(&tts_session->flag_mutex, SWITCH_MUTEX_NESTED, tts_session->pool);
-
sh->private_info = tts_session;
-
return SWITCH_STATUS_SUCCESS;
-
}
static switch_status_t openmrcp_tts_close(switch_speech_handle_t *sh, switch_speech_flag_t *flags)
{
- tts_session_t *tts_session = (tts_session_t *) sh->private_info;
- mrcp_client_context_t *tts_client_context = openmrcp_module.tts_client_context ;
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "synth_stop\n");
- synth_stop(tts_client_context,tts_session); // TODO
- wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_CHANNEL_MODIFY,5000);
-
-
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
+ mrcp_client_context_t *context = tts_session->profile->mrcp_context;
/* terminate tts session */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Terminate tts_session\n");
- mrcp_client_context_session_terminate(tts_client_context,tts_session->client_session);
- /* wait for tts session termination */
- wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_SESSION_TERMINATE,10000);
-
- /* destroy demo session */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "destroy tts_session\n");
- mrcp_client_context_session_destroy(tts_client_context,tts_session->client_session);
- tts_session_destroy(tts_session);
-
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "terminate tts_session\n");
+ mrcp_client_context_session_terminate(context,tts_session->client_session);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t openmrcp_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags)
{
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
+ mrcp_client_context_t *context = tts_session->profile->mrcp_context;
- tts_session_t *tts_session = (tts_session_t *) sh->private_info;
- mrcp_client_context_t *tts_client_context = openmrcp_module.tts_client_context ;
- audio_sink_t *sink = tts_session->sink;
-
- /* create synthesizer channel */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Create Synthesizer Channel\n");
- tts_session->channel = mrcp_client_synthesizer_channel_create(tts_client_context,tts_session->client_session,sink);
- /* wait for synthesizer channel creation */
- if(wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_CHANNEL_CREATE,5000) == MRCP_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got channel create event\n");
- wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_NONE,1000); // XXX: what are we waiting for??
- /* speak */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Going to speak\n");
- synth_speak(tts_client_context,tts_session, text);
-
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Never got channel create event.\n");
- return SWITCH_STATUS_FALSE;
+ if(!tts_session->control_channel) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no synthesizer channel too feed tts\n");
+ return SWITCH_STATUS_FALSE;
}
-
+
+ synth_speak(context, tts_session, text);
+
+ switch_clear_flag(tts_session,FLAG_FEED_STARTED);
return SWITCH_STATUS_SUCCESS;
}
@@ -1153,70 +627,52 @@
*/
static switch_status_t openmrcp_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
{
- media_frame_t *queue_frame = NULL;
- tts_session_t *tts_session = (tts_session_t *) sh->private_info;
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
size_t return_len=0;
- size_t amt2copy=0;
- size_t desired = *datalen;
- switch_byte_t *audiodata = (switch_byte_t *) data;
-
- while(return_len < desired) {
-
- if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
- // tell fs we are done
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
- return SWITCH_STATUS_BREAK;
- }
-
- if (switch_queue_pop(tts_session->audio_queue, (void *) &queue_frame)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "could not pop from queue\n");
- if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
- // tell fs we are done
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
- return SWITCH_STATUS_BREAK;
- }
- break;
- }
- else {
- if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
- // tell fs we are done
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
- return SWITCH_STATUS_BREAK;
- }
-
- if (queue_frame->codec_frame.size >= desired) {
- amt2copy = desired;
- }
- else {
- // limit the amt we copy to audiodata to be LTE datalen
- // if the queue frame has _more_, just ignore it (TODO: fix this!)
- amt2copy = queue_frame->codec_frame.size;
- }
- memcpy(audiodata, queue_frame->codec_frame.buffer, amt2copy);
- return_len += amt2copy;
- *datalen = return_len;
- audiodata += amt2copy; // move pointer forward
- *rate = 8000;
- }
+ media_frame_t media_frame;
+ audio_source_t *audio_source;
+ if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
+ /* tell fs we are done */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
+ return SWITCH_STATUS_BREAK;
}
- // double check we actually read something
- if (*datalen == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no data read from buffer\n");
- return SWITCH_STATUS_FALSE;
+ audio_source = mrcp_client_audio_source_get(tts_session->audio_channel);
+ if(!audio_source) {
+ return SWITCH_STATUS_BREAK;
}
- else if (*datalen < desired) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "return_len: (%d) < desired: (%d)\n", return_len, desired);
+
+ if (!switch_test_flag(tts_session, FLAG_FEED_STARTED)) {
+ switch_set_flag(tts_session, FLAG_FEED_STARTED);
+ if(audio_source->method_set->open) {
+ audio_source->method_set->open(audio_source);
+ }
}
+ /* sampling rate and frame size should be retrieved from audio source */
+ *rate = 8000;
+ media_frame.codec_frame.size = 160;
+ while(return_len < *datalen) {
+ media_frame.codec_frame.buffer = (char*)data + return_len;
+ audio_source->method_set->read_frame(audio_source,&media_frame);
+ if(media_frame.type != MEDIA_FRAME_TYPE_AUDIO) {
+ memset(media_frame.codec_frame.buffer,0,media_frame.codec_frame.size);
+ }
+ return_len += media_frame.codec_frame.size;
+ }
+ *datalen = return_len;
return SWITCH_STATUS_SUCCESS;
}
static void openmrcp_flush_tts(switch_speech_handle_t *sh)
{
+ openmrcp_session_t *tts_session = (openmrcp_session_t *) sh->private_info;
+ mrcp_client_context_t *context = tts_session->profile->mrcp_context;
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "flush_tts called\n");
+ synth_stop(context,tts_session); // TODO
}
static void openmrcp_text_param_tts(switch_speech_handle_t *sh, char *param, char *val)
@@ -1257,7 +713,6 @@
/*.speech_text_param_tts*/ openmrcp_text_param_tts,
/*.speech_numeric_param_tts*/ openmrcp_numeric_param_tts,
/*.speech_float_param_tts*/ openmrcp_float_param_tts,
-
};
static switch_loadable_module_interface_t openmrcp_module_interface = {
@@ -1277,157 +732,185 @@
};
-static switch_status_t do_config(void)
+static switch_status_t do_config()
{
char *cf = "mod_openmrcp.conf";
- switch_xml_t cfg, xml, settings, param;
+ const char *asr_profile_name = NULL;
+ const char *tts_profile_name = NULL;
+ switch_xml_t cfg, xml, settings, profiles, xprofile, param;
+ openmrcp_profile_t *mrcp_profile;
+ openmrcp_client_options_t *mrcp_options;
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;
}
- memset(&globals,0,sizeof(globals));
-
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");
+ const char *var = switch_xml_attr_soft(param, "name");
+ const char *val = switch_xml_attr_soft(param, "value");
+
+ if (!strcasecmp(var, "asr_default_profile")) {
+ asr_profile_name = val;
+ } else if (!strcasecmp(var, "tts_default_profile")) {
+ tts_profile_name = val;
+ }
+ }
+ }
+ else {
+ goto error;
+ }
+ if ((profiles = switch_xml_child(cfg, "profiles"))) {
+ for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
+ const char *profile_name = switch_xml_attr_soft(xprofile, "name");
+ mrcp_profile = switch_core_alloc(openmrcp_module.pool,sizeof(openmrcp_profile_t));
+ mrcp_profile->mrcp_client = NULL;
+ mrcp_profile->mrcp_context = NULL;
+ mrcp_profile->name = "noname";
+ if(profile_name) {
+ mrcp_profile->name = switch_core_strdup(openmrcp_module.pool,profile_name);
+ }
- if (!strcasecmp(var, "asr_client_ip")) {
- globals.asr_client_ip = val;
- } else if (!strcasecmp(var, "asr_server_ip")) {
- globals.asr_server_ip = val;
- } else if (!strcasecmp(var, "asr_proto_version")) {
- globals.asr_proto_version =(uint32_t) atoi(val);
- } else if (!strcasecmp(var, "asr_client_port")) {
- globals.asr_client_port = (uint32_t) atoi(val);
- } else if (!strcasecmp(var, "asr_server_port")) {
- globals.asr_server_port = (uint32_t) atoi(val);
- } else if (!strcasecmp(var, "tts_client_ip")) {
- globals.tts_client_ip = val;
- } else if (!strcasecmp(var, "tts_server_ip")) {
- globals.tts_server_ip = val;
- } else if (!strcasecmp(var, "tts_proto_version")) {
- globals.tts_proto_version =(uint32_t) atoi(val);
- } else if (!strcasecmp(var, "tts_client_port")) {
- globals.tts_client_port = (uint32_t) atoi(val);
- } else if (!strcasecmp(var, "tts_server_port")) {
- globals.tts_server_port = (uint32_t) atoi(val);
- } else if (!strcasecmp(var, "rtp_port_min")) {
- globals.rtp_port_min = (uint32_t) atoi(val);
- } else if (!strcasecmp(var, "rtp_port_max")) {
- globals.rtp_port_max = (uint32_t) atoi(val);
+ mrcp_options = openmrcp_client_options_create(openmrcp_module.pool);
+ for (param = switch_xml_child(xprofile, "param"); param; param = param->next) {
+ const char *var = switch_xml_attr_soft(param, "name");
+ const char *val = switch_xml_attr_soft(param, "value");
+
+ if (!strcasecmp(var, "proto_version")) {
+ mrcp_options->proto_version =(mrcp_version_t) atoi(val);
+ }
+ else if (!strcasecmp(var, "client_ip")) {
+ mrcp_options->client_ip = switch_core_strdup(openmrcp_module.pool,val);
+ } else if (!strcasecmp(var, "server_ip")) {
+ mrcp_options->server_ip = switch_core_strdup(openmrcp_module.pool,val);
+ } else if (!strcasecmp(var, "client_port")) {
+ mrcp_options->client_port = (apr_port_t) atoi(val);
+ } else if (!strcasecmp(var, "server_port")) {
+ mrcp_options->server_port = (apr_port_t) atoi(val);
+ } else if (!strcasecmp(var, "rtp_port_min")) {
+ mrcp_options->rtp_port_min = (apr_port_t) atoi(val);
+ } else if (!strcasecmp(var, "rtp_port_max")) {
+ mrcp_options->rtp_port_max = (apr_port_t) atoi(val);
+ }
}
+ mrcp_profile->mrcp_options = mrcp_options;
+ /* add profile */
+ if (!switch_core_hash_find(openmrcp_module.profile_hash, mrcp_profile->name)) {
+ switch_core_hash_insert(openmrcp_module.profile_hash, mrcp_profile->name, mrcp_profile);
+
+ /* try to set default asr profile */
+ if (!openmrcp_module.asr_profile) {
+ if (asr_profile_name) {
+ if (!strcasecmp(mrcp_profile->name,asr_profile_name)) {
+ openmrcp_module.asr_profile = mrcp_profile;
+ }
+ }
+ else {
+ openmrcp_module.asr_profile = mrcp_profile;
+ }
+ }
+ /* try to set default tts profile */
+ if (!openmrcp_module.tts_profile) {
+ if (tts_profile_name) {
+ if (!strcasecmp(mrcp_profile->name,tts_profile_name)) {
+ openmrcp_module.tts_profile = mrcp_profile;
+ }
+ }
+ else {
+ openmrcp_module.tts_profile = mrcp_profile;
+ }
+ }
+ }
}
}
+ else {
+ goto error;
+ }
switch_xml_free(xml);
-
return SWITCH_STATUS_SUCCESS;
-}
+ error:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load module configuration\n");
+ switch_xml_free(xml);
+ return SWITCH_STATUS_TERM;
-static switch_status_t mrcp_init()
+}
+
+static switch_status_t openmrcp_profile_run(openmrcp_profile_t *profile)
{
+ mrcp_client_event_handler_t *mrcp_event_handler;
+ mrcp_client_t *mrcp_client;
+ mrcp_client_context_t *mrcp_context;
+
/*!
- Perform one-time initialization of asr client library
+ Perform one-time initialization of mrcp client library
*/
-
- mrcp_mem_pool_t *pool;
- mrcp_client_event_handler_t *asr_event_handler;
- mrcp_client_t *asr_client;
- mrcp_client_context_t *asr_client_context;
- openmrcp_client_options_t *asr_options;
-
- pool = mrcp_global_pool_get();
- asr_options = mrcp_palloc(pool,sizeof(openmrcp_client_options_t));
- asr_event_handler = mrcp_palloc(pool,sizeof(mrcp_client_event_handler_t));
- set_default_asr_options(asr_options);
-
- asr_event_handler->on_session_initiate = asr_on_session_initiate;
- asr_event_handler->on_session_terminate = asr_on_session_terminate;
- asr_event_handler->on_channel_add = asr_on_channel_add;
- asr_event_handler->on_channel_remove = asr_on_channel_remove;
- asr_event_handler->on_channel_modify = asr_on_channel_modify;
-
- // create asr client context, which to must be passed to client engine
- asr_client_context = mrcp_client_context_create(&openmrcp_module,asr_event_handler);
- if(!asr_client_context) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_client_context creation failed\n");
+ mrcp_event_handler = switch_core_alloc(openmrcp_module.pool,sizeof(mrcp_client_event_handler_t));
+ mrcp_event_handler->on_session_initiate = openmrcp_on_session_initiate;
+ mrcp_event_handler->on_session_terminate = openmrcp_on_session_terminate;
+ mrcp_event_handler->on_channel_add = openmrcp_on_channel_add;
+ mrcp_event_handler->on_channel_remove = openmrcp_on_channel_remove;
+ mrcp_event_handler->on_channel_modify = openmrcp_on_channel_modify;
+
+ // create client context, which must be passed to client engine
+ mrcp_context = mrcp_client_context_create(&openmrcp_module,mrcp_event_handler);
+ if(!mrcp_context) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mrcp_client_context creation failed\n");
return SWITCH_STATUS_GENERR;
}
- openmrcp_module.asr_client_context = asr_client_context;
+ profile->mrcp_context = mrcp_context;
// this basically starts a thread that pulls events from the event queue
// and handles them
- asr_client = openmrcp_client_start(asr_options,asr_client_context);
- if(!asr_client) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "openasr_client_start FAILED\n");
- mrcp_client_context_destroy(asr_client_context);
+ mrcp_client = openmrcp_client_start(profile->mrcp_options,mrcp_context);
+ if(!mrcp_client) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "openmrcp_client_start FAILED\n");
+ mrcp_client_context_destroy(mrcp_context);
return SWITCH_STATUS_GENERR;
}
+ profile->mrcp_client = mrcp_client;
+ return SWITCH_STATUS_SUCCESS;
+}
- openmrcp_module.asr_client = asr_client;
+static switch_status_t openmrcp_init()
+{
+ openmrcp_module.pool = mrcp_global_pool_get();
+ openmrcp_module.asr_profile = NULL;
+ openmrcp_module.tts_profile = NULL;
- /*!
- Perform one-time initialization of tts client library
- */
-
- mrcp_client_event_handler_t *tts_event_handler;
- mrcp_client_t *tts_client;
- mrcp_client_context_t *tts_client_context;
- openmrcp_client_options_t *tts_options;
-
- pool = mrcp_global_pool_get();
- tts_options = mrcp_palloc(pool,sizeof(openmrcp_client_options_t));
- tts_event_handler = mrcp_palloc(pool,sizeof(mrcp_client_event_handler_t));
- set_default_tts_options(tts_options);
-
- tts_event_handler->on_session_initiate = tts_on_session_initiate;
- tts_event_handler->on_session_terminate = tts_on_session_terminate;
- tts_event_handler->on_channel_add = tts_on_channel_add;
- tts_event_handler->on_channel_remove = tts_on_channel_remove;
- tts_event_handler->on_channel_modify = tts_on_channel_modify;
-
- // create tts client context, which to must be passed to client engine
- tts_client_context = mrcp_client_context_create(&openmrcp_module,tts_event_handler);
- if(!tts_client_context) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "tts_client_context creation failed\n");
- return SWITCH_STATUS_GENERR;
- }
- openmrcp_module.tts_client_context = tts_client_context;
+ switch_core_hash_init(&openmrcp_module.profile_hash,openmrcp_module.pool);
- // this basically starts a thread that pulls events from the event queue
- // and handles them
- tts_client = openmrcp_client_start(tts_options,tts_client_context);
- if(!tts_client) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "opentts_client_start FAILED\n");
- mrcp_client_context_destroy(tts_client_context);
- return SWITCH_STATUS_GENERR;
+ /* read config */
+ if (do_config() != SWITCH_STATUS_SUCCESS) {
+ return SWITCH_STATUS_FALSE;
}
- openmrcp_module.tts_client = tts_client;
-
-
+ /* run default asr/tts profiles */
+ if(openmrcp_module.asr_profile) {
+ openmrcp_profile_run(openmrcp_module.asr_profile);
+ }
+ if(openmrcp_module.tts_profile && openmrcp_module.tts_profile != openmrcp_module.asr_profile) {
+ openmrcp_profile_run(openmrcp_module.tts_profile);
+ }
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load)
{
-
/* connect my internal structure to the blank pointer passed to me */
*module_interface = &openmrcp_module_interface;
- /* read config */
- do_config();
+ mrcp_global_init();
/* initialize openmrcp */
- mrcp_global_init();
- mrcp_init();
+ if (openmrcp_init() != SWITCH_STATUS_SUCCESS) {
+ return SWITCH_STATUS_FALSE;
+ }
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
Modified: freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/Makefile
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/Makefile (original)
+++ freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/Makefile Mon Aug 20 13:37:13 2007
@@ -1,2 +1,2 @@
BASE=../../../..
-include /usr/src/freeswitch.trunk/build/modmake.rules
+include $(BASE)/build/modmake.rules
Modified: freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/mod_h26x.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/mod_h26x.c (original)
+++ freeswitch/branches/greenlizard/src/mod/codecs/mod_h26x/mod_h26x.c Mon Aug 20 13:37:13 2007
@@ -117,13 +117,33 @@
/*.next = */&h264_90000_implementation
};
+static switch_codec_implementation_t h261_90000_implementation = {
+ /*.codec_type */ SWITCH_CODEC_TYPE_VIDEO,
+ /*.ianacode */ 31,
+ /*.iananame */ "H261",
+ /*.fmtp */ NULL,
+ /*.samples_per_second = */ 90000,
+ /*.bits_per_second = */ 0,
+ /*.microseconds_per_frame = */ 0,
+ /*.samples_per_frame = */ 0,
+ /*.bytes_per_frame = */ 0,
+ /*.encoded_bytes_per_frame = */ 0,
+ /*.number_of_channels = */ 1,
+ /*.pref_frames_per_packet = */ 1,
+ /*.max_frames_per_packet = */ 1,
+ /*.init = */ switch_h26x_init,
+ /*.encode = */ switch_h26x_encode,
+ /*.decode = */ switch_h26x_decode,
+ /*.destroy = */ switch_h26x_destroy,
+ /*.next = */&h263_90000_implementation
+};
SWITCH_MODULE_LOAD_FUNCTION(mod_h26x_load)
{
switch_codec_interface_t *codec_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
- SWITCH_ADD_CODEC(codec_interface, "h26x video (passthru)", &h263_90000_implementation);
+ SWITCH_ADD_CODEC(codec_interface, "h26x video (passthru)", &h261_90000_implementation);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_iax/mod_iax.c Mon Aug 20 13:37:13 2007
@@ -278,8 +278,8 @@
char pref_str[256] = "(";
for (x = 0; x < len; x++) {
- strncat(pref_str, ast2str(prefs[x]), sizeof(pref_str));
- strncat(pref_str, x == len - 1 ? ")" : ",", sizeof(pref_str));
+ strncat(pref_str, ast2str(prefs[x]), sizeof(pref_str)-1);
+ strncat(pref_str, x == len - 1 ? ")" : ",", sizeof(pref_str)-1);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Codec Prefs Detected: %s\n", pref_str);
@@ -763,8 +763,18 @@
assert(tech_pvt != NULL);
switch (msg->message_id) {
+ case SWITCH_MESSAGE_INDICATE_REJECT:
+ {
+ if (tech_pvt->iax_session) {
+ iax_reject(tech_pvt->iax_session, msg->string_arg ? msg->string_arg : "Call Rejected");
+ switch_set_flag(tech_pvt, TFLAG_HANGUP);
+ }
+ }
+ break;
case SWITCH_MESSAGE_INDICATE_ANSWER:
- channel_answer_channel(session);
+ {
+ channel_answer_channel(session);
+ }
break;
default:
break;
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_portaudio/mod_portaudio.c Mon Aug 20 13:37:13 2007
@@ -6,7 +6,7 @@
*
* 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
+ * the License. You may obtain a copy of the License `
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
@@ -270,7 +270,9 @@
unsigned int pos = 0;
switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
}
- WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.timer);
+ if (globals.ring_stream) {
+ WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.timer);
+ }
}
}
switch_clear_flag_locked((&globals), GFLAG_RING);
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia.c Mon Aug 20 13:37:13 2007
@@ -1771,7 +1771,7 @@
is_auth++;
}
- if (!(session = switch_core_session_request(sofia_endpoint_interface, NULL))) {
+ if (!sofia_endpoint_interface || !(session = switch_core_session_request(sofia_endpoint_interface, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
return;
@@ -1785,7 +1785,7 @@
}
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
- if (!switch_strlen_zero(key)) {
+ if (*key != '\0') {
tech_pvt->key = switch_core_session_strdup(session, key);
}
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_glue.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_glue.c Mon Aug 20 13:37:13 2007
@@ -582,10 +582,10 @@
}
nua_invite(tech_pvt->nh,
- TAG_IF(!switch_strlen_zero(rpid), SIPTAG_HEADER_STR(rpid)),
- TAG_IF(!switch_strlen_zero(alert_info), SIPTAG_HEADER_STR(alert_info)),
+ TAG_IF(*rpid != '\0', SIPTAG_HEADER_STR(rpid)),
+ TAG_IF(*alert_info != '\0', SIPTAG_HEADER_STR(alert_info)),
TAG_IF(!switch_strlen_zero(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
- TAG_IF(!switch_strlen_zero(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)),
+ TAG_IF(*max_forwards != '\0', SIPTAG_MAX_FORWARDS_STR(max_forwards)),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE),
SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END());
@@ -600,7 +600,6 @@
void sofia_glue_do_xfer_invite(switch_core_session_t *session)
{
- char rpid[1024];
private_object_t *tech_pvt;
switch_channel_t *channel = NULL;
switch_caller_profile_t *caller_profile;
@@ -630,7 +629,6 @@
nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private);
nua_invite(tech_pvt->nh2,
- TAG_IF(rpid, SIPTAG_HEADER_STR(rpid)),
SIPTAG_CONTACT_STR(tech_pvt->profile->url),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), TAG_END());
@@ -1090,9 +1088,9 @@
continue;
}
- if (!strcasecmp(a->a_name, "sendonly")) {
+ if ((!strcasecmp(a->a_name, "sendonly")) || (!strcasecmp(a->a_name, "inactive"))) {
sendonly = 1;
- } else if (!strcasecmp(a->a_name, "sendrecv")) {
+ } else if (!strcasecmp(a->a_name, "sendrecv")) {
sendonly = 0;
} else if (!strcasecmp(a->a_name, "ptime")) {
dptime = atoi(a->a_value);
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_presence.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_presence.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_presence.c Mon Aug 20 13:37:13 2007
@@ -1033,7 +1033,7 @@
if ((ci = switch_loadable_module_get_chat_interface(proto))) {
ci->chat_send(SOFIA_CHAT_PROTO, from_addr, to_addr, "", msg, full_from);
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Chat Interface [%s]!\n", proto ? proto : "(none)");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Chat Interface [%s]!\n", proto);
}
}
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_sofia/sofia_reg.c Mon Aug 20 13:37:13 2007
@@ -435,6 +435,10 @@
}
reg:
+ if (regtype != REG_REGISTER) {
+ return 0;
+ }
+
if (exptime) {
if (!sofia_reg_find_reg_url(profile, to_user, to_host, buf, sizeof(buf))) {
sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','%q', '%q', %ld)",
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/Makefile
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/Makefile (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/Makefile Mon Aug 20 13:37:13 2007
@@ -1,9 +1,9 @@
BASE=../../../..
LIBPRI_HOST=http://ftp.digium.com/pub/libpri
-LIBPRI=libpri-1.2.4
+LIBPRI=libpri-1.2.5
LIBPRI_FILE=$(LIBPRI).tar.gz
LIBPRI_DIR=$(BASE)/libs/$(LIBPRI)
-WANPIPE=wanpipe-3.1.0
+WANPIPE=wanpipe-3.1.1
WANPIPE_HOST=ftp://ftp.sangoma.com/linux/current_wanpipe/
WANPIPE_FILE=$(WANPIPE).tgz
WANPIPE_DIR=$(BASE)/libs/$(WANPIPE)
Modified: freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c (original)
+++ freeswitch/branches/greenlizard/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c Mon Aug 20 13:37:13 2007
@@ -116,6 +116,7 @@
int configured_spans;
int configured_boost_spans;
char *dialplan;
+ char *context;
switch_hash_t *call_hash;
switch_mutex_t *hash_mutex;
switch_mutex_t *channel_mutex;
@@ -387,6 +388,16 @@
globals.dialplan = strdup(dialplan);
}
+static void set_global_context(char *context)
+{
+ if (globals.context) {
+ free(globals.context);
+ globals.context = NULL;
+ }
+
+ globals.context = strdup(context);
+}
+
static int str2node(char *node)
{
@@ -446,6 +457,7 @@
static void set_global_dialplan(char *dialplan);
+static void set_global_context(char *context);
static int str2node(char *node);
static int str2switch(char *swtype);
static switch_status_t wanpipe_on_init(switch_core_session_t *session);
@@ -1103,7 +1115,7 @@
if (num && *num > 47 && *num < 58) {
span = atoi(num);
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Syntax\n");
switch_core_session_destroy(new_session);
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
goto error;
@@ -1119,14 +1131,14 @@
} else if (num && *num > 47 && *num < 58) {
callno = atoi(num);
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Syntax\n");
switch_core_session_destroy(new_session);
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
goto error;
}
caller_profile->destination_number = p;
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Syntax\n");
switch_core_session_destroy(new_session);
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
goto error;
@@ -1546,7 +1558,7 @@
NULL,
NULL,
(char *)modname,
- NULL,
+ globals.context,
pevent->ring.callednum))) {
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
}
@@ -2225,6 +2237,8 @@
globals.dtmf_off = atoi(val);
} else if (!strcmp(var, "dialplan")) {
set_global_dialplan(val);
+ } else if (!strcmp(var, "context")) {
+ set_global_context(val);
} else if (!strcmp(var, "suppress-dtmf-tone")) {
globals.suppress_dtmf_tone = switch_true(val);
} else if (!strcmp(var, "ignore-dtmf-tone")) {
Modified: freeswitch/branches/greenlizard/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/event_handlers/mod_event_socket/mod_event_socket.c (original)
+++ freeswitch/branches/greenlizard/src/mod/event_handlers/mod_event_socket/mod_event_socket.c Mon Aug 20 13:37:13 2007
@@ -83,10 +83,12 @@
} listen_list;
static struct {
+ switch_mutex_t *mutex;
char *ip;
uint16_t port;
char *password;
int done;
+ int threads;
} prefs;
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip)
@@ -137,7 +139,7 @@
if (l->event_list[SWITCH_EVENT_ALL]) {
send = 1;
} else if ((l->event_list[event->event_id])) {
- if (event->event_id != SWITCH_EVENT_CUSTOM || (event->subclass && switch_core_hash_find(l->event_hash, event->subclass->name))) {
+ if (event->event_id != SWITCH_EVENT_CUSTOM || !event->subclass || (switch_core_hash_find(l->event_hash, event->subclass->name))) {
send = 1;
}
}
@@ -265,11 +267,19 @@
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_socket_shutdown)
{
listener_t *l;
+ int sanity = 0;
prefs.done = 1;
close_socket(&listen_list.sock);
+ while(prefs.threads) {
+ switch_yield(10000);
+ if (++sanity == 1000) {
+ break;
+ }
+ }
+
switch_mutex_lock(listen_list.mutex);
for (l = listen_list.listeners; l; l = l->next) {
close_socket(&l->sock);
@@ -346,7 +356,7 @@
start = time(NULL);
ptr = mbuf;
- while (listener->sock) {
+ while (listener->sock && !prefs.done) {
uint8_t do_sleep = 1;
mlen = 1;
status = switch_socket_recv(listener->sock, ptr, &mlen);
@@ -857,7 +867,7 @@
if (type == SWITCH_EVENT_ALL) {
uint32_t x = 0;
for (x = 0; x < SWITCH_EVENT_ALL; x++) {
- listener->event_list[x] = 0;
+ listener->event_list[x] = 1;
}
}
listener->event_list[type] = 1;
@@ -904,8 +914,9 @@
uint32_t x = 0;
key_count++;
- if (type == SWITCH_EVENT_ALL) {
-
+ if (type == SWITCH_EVENT_CUSTOM) {
+ custom++;
+ } else if (type == SWITCH_EVENT_ALL) {
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
listener->event_list[x] = 0;
}
@@ -918,10 +929,6 @@
}
listener->event_list[type] = 0;
}
-
- if (type == SWITCH_EVENT_CUSTOM) {
- custom++;
- }
}
cur = next;
@@ -980,6 +987,9 @@
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
+ switch_mutex_lock(listen_list.mutex);
+ prefs.threads++;
+ switch_mutex_unlock(listen_list.mutex);
assert(listener != NULL);
@@ -1055,7 +1065,7 @@
switch_clear_flag_locked(listener, LFLAG_RUNNING);
goto done;
}
- if (!switch_strlen_zero(reply)) {
+ if (*reply != '\0') {
snprintf(buf, sizeof(buf), "Content-Type: command/reply\nReply-Text: %s\n\n", reply);
len = strlen(buf);
switch_socket_send(listener->sock, buf, &len);
@@ -1084,7 +1094,7 @@
break;
}
- if (!switch_strlen_zero(reply)) {
+ if (*reply != '\0') {
snprintf(buf, sizeof(buf), "Content-Type: command/reply\nReply-Text: %s\n\n", reply);
len = strlen(buf);
switch_socket_send(listener->sock, buf, &len);
@@ -1113,6 +1123,9 @@
switch_core_destroy_memory_pool(&pool);
}
+ switch_mutex_lock(listen_list.mutex);
+ prefs.threads--;
+ switch_mutex_unlock(listen_list.mutex);
return NULL;
}
@@ -1226,7 +1239,7 @@
switch_log_bind_logger(socket_logger, SWITCH_LOG_DEBUG);
- for (;;) {
+ for(;;) {
if (switch_core_new_memory_pool(&listener_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n");
goto fail;
Modified: freeswitch/branches/greenlizard/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c (original)
+++ freeswitch/branches/greenlizard/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c Mon Aug 20 13:37:13 2007
@@ -30,8 +30,6 @@
*
*/
-#define _BSD_SOURCE 1
-
#include <switch.h>
#include <sys/stat.h>
#include <freeradius-client.h>
@@ -130,8 +128,8 @@
rc_handle *rad_config;
int retval = 0;
VALUE_PAIR *send = NULL;
- UINT4 client_port = 0;
- UINT4 status_type = PW_STATUS_START;
+ uint32_t client_port = 0;
+ uint32_t status_type = PW_STATUS_START;
char *uuid_str;
@@ -249,14 +247,14 @@
rc_handle *rad_config;
int retval = 0;
VALUE_PAIR *send = NULL;
- UINT4 client_port = 0;
- UINT4 status_type = PW_STATUS_STOP;
+ uint32_t client_port = 0;
+ uint32_t status_type = PW_STATUS_STOP;
switch_time_t callstartdate = 0;
switch_time_t callanswerdate = 0;
switch_time_t callenddate = 0;
switch_time_t calltransferdate = 0;
switch_time_t billusec = 0;
- UINT4 billsec = 0;
+ uint32_t billsec = 0;
char *uuid_str;
@@ -375,7 +373,7 @@
}
if (rc_avpair_add(rad_config, &send, PW_FS_BILLUSEC, &billusec, -1, PW_FS_PEC) == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
- "failed adding Freeswitch-Billusec: %u\n", (UINT4)billusec);
+ "failed adding Freeswitch-Billusec: %u\n", (uint32_t)billusec);
rc_destroy(rad_config);
return SWITCH_STATUS_TERM;
}
Modified: freeswitch/branches/greenlizard/src/mod/formats/mod_shout/Makefile
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/formats/mod_shout/Makefile (original)
+++ freeswitch/branches/greenlizard/src/mod/formats/mod_shout/Makefile Mon Aug 20 13:37:13 2007
@@ -27,17 +27,23 @@
$(LAME_DIR):
$(GETLIB) $(LAME).tar.gz
+
+$(LAME_DIR)/Makefile: $(LAME_DIR)
cd $(LAME_DIR) && ./configure $(DEFAULT_ARGS) --disable-decoder
+ $(TOUCH_TARGET)
-$(LAMELA): $(LAME_DIR)
+$(LAMELA): $(LAME_DIR)/Makefile
cd $(LAME_DIR) && $(MAKE)
$(TOUCH_TARGET)
$(SHOUT_DIR):
$(GETLIB) $(SHOUT).tar.gz
+
+$(SHOUT_DIR)/Makefile: $(SHOUT_DIR)
cd $(SHOUT_DIR) && ./configure $(DEFAULT_ARGS) --with-speex=no
+ $(TOUCH_TARGET)
-$(SHOUTLA): $(SHOUT_DIR)
+$(SHOUTLA): $(SHOUT_DIR)/Makefile
cd $(SHOUT_DIR) && $(MAKE)
$(TOUCH_TARGET)
Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Mon Aug 20 13:37:13 2007
@@ -354,12 +354,12 @@
if (etype == SWITCH_EVENT_CUSTOM) {
char *subclass_name;
- if (argc < 1) {
- *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
- return JS_TRUE;
+ if (argc > 1) {
+ subclass_name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+ } else {
+ subclass_name = "none";
}
- subclass_name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
if (switch_event_create_subclass(&event, etype, subclass_name) != SWITCH_STATUS_SUCCESS) {
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
return JS_TRUE;
@@ -693,7 +693,7 @@
}
if (err) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error Loading module %s\n**%s**\n", filename, err);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Loading module %s\n**%s**\n", filename, err);
return SWITCH_STATUS_GENERR;
}
@@ -715,7 +715,7 @@
}
-static switch_status_t sm_load_module(char *dir, char *fname)
+static switch_status_t sm_load_module(const char *dir, const char *fname)
{
switch_size_t len = 0;
char *path;
@@ -723,8 +723,6 @@
#ifdef WIN32
const char *ext = ".dll";
-#elif defined (MACOSX) || defined (DARWIN)
- const char *ext = ".dylib";
#else
const char *ext = ".so";
#endif
@@ -788,7 +786,7 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
continue;
}
- sm_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val);
+ sm_load_module(SWITCH_GLOBAL_dirs.mod_dir, val);
count++;
}
}
@@ -1527,15 +1525,15 @@
CHANNEL_SANITY_CHECK();
- if (argc > 0) {
- tts_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
- }
- if (argc > 1) {
- voice_name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
- }
- if (argc > 2) {
- text = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
+ if (argc < 3) {
+ *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+ return JS_FALSE;
}
+
+ tts_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+ voice_name = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
+ text = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
+
if (argc > 3) {
if ((function = JS_ValueToFunction(cx, argv[3]))) {
memset(&cb_state, 0, sizeof(cb_state));
@@ -1790,9 +1788,9 @@
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
-
- CHANNEL_SANITY_CHECK();
-
+ /* you can execute some apps before you answer */
+ /* CHANNEL_SANITY_CHECK(); */
+
if (argc > 0) {
const switch_application_interface_t *application_interface;
@@ -1964,7 +1962,9 @@
register unsigned int realsize = (unsigned int) (size * nmemb);
struct config_data *config_data = data;
- write(config_data->fd, ptr, realsize);
+ if ((write(config_data->fd, ptr, realsize) != (int)realsize)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to write all bytes!\n");
+ }
return realsize;
}
@@ -2311,7 +2311,7 @@
if (JS_ValueToObject(cx, argv[0], &session_obj)) {
struct js_session *old_jss = NULL;
- if ((old_jss = JS_GetPrivate(cx, session_obj))) {
+ if ((old_jss = JS_GetPrivate(cx, session_obj)) && old_jss->session) {
session = old_jss->session;
orig_caller_profile = switch_channel_get_caller_profile(switch_core_session_get_channel(session));
dialplan = orig_caller_profile->dialplan;
@@ -2752,24 +2752,31 @@
struct input_callback_state cb_state = { 0 };
JSFunction *function;
+ *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+
if (argc > 1) {
if (JS_ValueToObject(cx, argv[0], &session_obj_a)) {
if (!(jss_a = JS_GetPrivate(cx, session_obj_a))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Find Session [1]\n");
- return JS_FALSE;
+ eval_some_js("~throw new Error(\"Cannot find session A\");", cx, obj, rval);
+ return JS_TRUE;
}
}
if (JS_ValueToObject(cx, argv[1], &session_obj_b)) {
if (!(jss_b = JS_GetPrivate(cx, session_obj_b))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Find Session [1]\n");
- return JS_FALSE;
+ eval_some_js("~throw new Error(\"Cannot find session B\");", cx, obj, rval);
+ return JS_TRUE;
}
}
}
- if (!(jss_a && jss_b)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure! %s %s\n", jss_a ? "y" : "n", jss_b ? "y" : "n");
- return JS_FALSE;
+ if (!(jss_a && jss_a->session)) {
+ eval_some_js("~throw new Error(\"session A is not ready!\");", cx, obj, rval);
+ return JS_TRUE;
+ }
+
+ if (!(jss_b && jss_b->session)) {
+ eval_some_js("~throw new Error(\"session B is not ready!\");", cx, obj, rval);
+ return JS_TRUE;
}
@@ -2796,6 +2803,7 @@
switch_ivr_multi_threaded_bridge(jss_a->session, jss_b->session, dtmf_func, bp, bp);
JS_ResumeRequest(cx, cb_state.saveDepth);
+ *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
return JS_TRUE;
}
Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_core_db/mod_spidermonkey_core_db.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_core_db/mod_spidermonkey_core_db.c (original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_core_db/mod_spidermonkey_core_db.c Mon Aug 20 13:37:13 2007
@@ -73,17 +73,33 @@
return JS_FALSE;
}
-static void db_destroy(JSContext * cx, JSObject * obj)
+static JSBool db_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
struct db_obj *dbo = JS_GetPrivate(cx, obj);
-
+
if (dbo) {
- switch_memory_pool_t *pool = dbo->pool;
if (dbo->stmt) {
switch_core_db_finalize(dbo->stmt);
dbo->stmt = NULL;
}
- switch_core_db_close(dbo->db);
+ if (dbo->db) {
+ switch_core_db_close(dbo->db);
+ dbo->db = NULL;
+ }
+ }
+
+ return JS_TRUE;
+}
+
+static void db_destroy(JSContext *cx, JSObject *obj)
+{
+ struct db_obj *dbo = JS_GetPrivate(cx, obj);
+
+ if (dbo) {
+ switch_memory_pool_t *pool = dbo->pool;
+ jsval rval = JS_TRUE;
+
+ db_close(cx, obj, 0, NULL, &rval);
switch_core_destroy_memory_pool(&pool);
pool = NULL;
}
@@ -119,6 +135,10 @@
struct db_obj *dbo = JS_GetPrivate(cx, obj);
*rval = INT_TO_JSVAL(0);
+ if (!dbo->db) {
+ return JS_FALSE;
+ }
+
if (argc > 0) {
char *sql = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
char *err = NULL;
@@ -153,6 +173,10 @@
struct db_obj *dbo = JS_GetPrivate(cx, obj);
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+ if (!dbo->db) {
+ return JS_FALSE;
+ }
+
if (dbo->stmt) {
int running = 1;
while (running < 5000) {
@@ -180,6 +204,10 @@
char code[1024];
int x;
+ if (!dbo->db) {
+ return JS_FALSE;
+ }
+
snprintf(code, sizeof(code), "~var _dB_RoW_DaTa_ = {}");
eval_some_js(code, dbo->cx, dbo->obj, rval);
if (*rval == JS_FALSE) {
@@ -207,6 +235,10 @@
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+ if (!dbo->db) {
+ return JS_FALSE;
+ }
+
if (dbo->stmt) {
switch_core_db_finalize(dbo->stmt);
dbo->stmt = NULL;
@@ -229,6 +261,7 @@
static JSFunctionSpec db_methods[] = {
{"exec", db_exec, 1},
+ {"close", db_close, 0},
{"next", db_next, 0},
{"fetch", db_fetch, 1},
{"prepare", db_prepare, 0},
Modified: freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_etpan/mod_spidermonkey_etpan.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_etpan/mod_spidermonkey_etpan.c (original)
+++ freeswitch/branches/greenlizard/src/mod/languages/mod_spidermonkey_etpan/mod_spidermonkey_etpan.c Mon Aug 20 13:37:13 2007
@@ -180,7 +180,10 @@
close(ifd);
}
snprintf(buf, B64BUFFLEN, "/bin/cat %s | /usr/sbin/sendmail -tf \"%s\" %s", filename, from, to);
- system(buf);
+ if(!system(buf)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to execute command: %s\n",buf);
+ }
+
unlink(filename);
Modified: freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c (original)
+++ freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c Mon Aug 20 13:37:13 2007
@@ -40,11 +40,22 @@
char *errLogDir;
uint32_t delay;
uint32_t retries;
+ uint32_t shutdown;
} globals;
SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown);
SWITCH_MODULE_DEFINITION(mod_xml_cdr, mod_xml_cdr_load, NULL, NULL);
+/* this function would have access to the HTML returned by the webserver, we dont need it
+ * and the default curl activity is to print to stdout, something not as desirable
+ * so we have a dummy function here
+ */
+static void httpCallBack()
+{
+ return;
+}
+
static switch_status_t my_on_hangup(switch_core_session_t *session)
{
switch_xml_t cdr;
@@ -57,6 +68,7 @@
char *curl_xml_text;
char *logdir;
switch_channel_t *channel = switch_core_session_get_channel(session);
+ uint32_t i;
if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
@@ -110,6 +122,7 @@
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, curl_xml_text);
curl_easy_setopt(curl_handle, CURLOPT_URL, globals.url);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, httpCallBack);
/* these were used for testing, optionally they may be enabled if someone desires
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120); // tcp timeout
@@ -120,7 +133,6 @@
curl_easy_perform(curl_handle);
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE,&httpRes);
if(httpRes==200) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DEBUG XXX success posting\n");
curl_easy_cleanup(curl_handle);
free(curl_xml_text);
free(xml_text);
@@ -129,33 +141,40 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Got error [%ld] posting to web server\n",httpRes);
}
- /* bug? feature? we sleep even on the last failure before writing the file */
- switch_sleep(globals.delay * 1000);
+ /* make sure we dont sleep on the last try */
+ for(i=0;i<globals.delay && (curTry != (globals.retries));i++) {
+ switch_sleep(1000);
+ if(globals.shutdown) {
+ /* we are shutting down so dont try to webpost any more */
+ i=globals.delay;
+ curTry=globals.retries;
+ }
+ }
+
}
free(curl_xml_text);
curl_easy_cleanup(curl_handle);
- }
- /* if we are here the web post failed for some reason */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n");
+ /* if we are here the web post failed for some reason */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n");
- if ((path = switch_mprintf("%s/%s.cdr.xml", globals.errLogDir, switch_core_session_get_uuid(session)))) {
- if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
- write(fd, xml_text, (unsigned) strlen(xml_text));
- close(fd);
- fd = -1;
- } else {
- char ebuf[512] = { 0 };
+ if ((path = switch_mprintf("%s/%s.cdr.xml", globals.errLogDir, switch_core_session_get_uuid(session)))) {
+ if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
+ write(fd, xml_text, (unsigned) strlen(xml_text));
+ close(fd);
+ fd = -1;
+ } else {
+ char ebuf[512] = { 0 };
#ifdef WIN32
- strerror_s(ebuf, sizeof(ebuf), errno);
+ strerror_s(ebuf, sizeof(ebuf), errno);
#else
- strerror_r(errno, ebuf, sizeof(ebuf));
+ strerror_r(errno, ebuf, sizeof(ebuf));
#endif
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
+ }
+ free(path);
}
- free(path);
}
-
free(xml_text);
switch_xml_free(cdr);
} else {
@@ -165,16 +184,35 @@
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t do_config(void)
+
+static switch_state_handler_table_t state_handlers = {
+ /*.on_init */ NULL,
+ /*.on_ring */ NULL,
+ /*.on_execute */ NULL,
+ /*.on_hangup */ my_on_hangup,
+ /*.on_loopback */ NULL,
+ /*.on_transmit */ NULL
+};
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load)
{
char *cf = "xml_cdr.conf";
switch_xml_t cfg, xml, settings, param;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ /* test global state handlers */
+ switch_core_add_state_handler(&state_handlers);
+
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+
+ memset(&globals,0,sizeof(globals));
+
+ /* parse the config */
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");
@@ -214,35 +252,26 @@
if(!switch_strlen_zero(globals.url) && switch_strlen_zero(globals.errLogDir)) {
if ((globals.errLogDir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- return SWITCH_STATUS_FALSE;
+ status = SWITCH_STATUS_FALSE;
+ goto done;
}
}
- return SWITCH_STATUS_SUCCESS;
+
+ done:
+ switch_xml_free(xml);
+ return status;
}
-static switch_state_handler_table_t state_handlers = {
- /*.on_init */ NULL,
- /*.on_ring */ NULL,
- /*.on_execute */ NULL,
- /*.on_hangup */ my_on_hangup,
- /*.on_loopback */ NULL,
- /*.on_transmit */ NULL
-};
-SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load)
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown)
{
- /* test global state handlers */
- switch_core_add_state_handler(&state_handlers);
+
+ globals.shutdown=1;
+ return SWITCH_STATUS_SUCCESS;
+}
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
- memset(&globals,0,sizeof(globals));
- do_config();
-
- /* indicate that the module should continue to be loaded */
- return SWITCH_STATUS_SUCCESS;
-}
/* For Emacs:
* Local Variables:
Modified: freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c (original)
+++ freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c Mon Aug 20 13:37:13 2007
@@ -137,7 +137,6 @@
switch_safe_free(data);
if(httpRes==200) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got 200 response, calling switch_xml_parse_file: %s!\n", filename);
if (!(xml = switch_xml_parse_file(filename))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
}
@@ -165,7 +164,7 @@
if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <bindings> tag!\n");
- return SWITCH_STATUS_FALSE;
+ goto done;
}
for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) {
@@ -196,7 +195,7 @@
}
if (!(binding = malloc(sizeof(*binding)))) {
- return SWITCH_STATUS_FALSE;
+ goto done;
}
memset(binding, 0, sizeof(*binding));
@@ -219,6 +218,7 @@
binding = NULL;
}
+ done:
switch_xml_free(xml);
return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
Modified: freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c (original)
+++ freeswitch/branches/greenlizard/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c Mon Aug 20 13:37:13 2007
@@ -327,12 +327,12 @@
if (action) {
if (switch_core_management_exec(relative_oid, action, buf, sizeof(buf)) == SWITCH_STATUS_SUCCESS) {
if (action == SMA_SET) {
- if (switch_strlen_zero(buf)) {
+ if (*buf != '\0') {
snprintf(buf, sizeof(buf), "OK\n");
}
}
} else {
- if (switch_strlen_zero(buf)) {
+ if (*buf != '\0') {
snprintf(buf, sizeof(buf), "ERROR\n");
}
}
Modified: freeswitch/branches/greenlizard/src/switch.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch.c (original)
+++ freeswitch/branches/greenlizard/src/switch.c Mon Aug 20 13:37:13 2007
@@ -96,7 +96,9 @@
}
/* pull the pid from the file */
- fscanf(f, "%d", &pid);
+ if(fscanf(f, "%d", &pid)!=1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Unable to get the pid!\n");
+ }
/* if we have a valid pid */
if (pid > 0) {
Modified: freeswitch/branches/greenlizard/src/switch_core.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_core.c (original)
+++ freeswitch/branches/greenlizard/src/switch_core.c Mon Aug 20 13:37:13 2007
@@ -355,7 +355,9 @@
#ifdef WIN32
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
#else
- nice(-10);
+ if(nice(-10)!= -10) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+ }
#endif
#define USE_MLOCKALL
Modified: freeswitch/branches/greenlizard/src/switch_core_state_machine.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_core_state_machine.c (original)
+++ freeswitch/branches/greenlizard/src/switch_core_state_machine.c Mon Aug 20 13:37:13 2007
@@ -120,6 +120,9 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard EXECUTE\n");
+ top:
+ switch_channel_clear_flag(session->channel, CF_RESET);
+
if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) {
switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING);
return;
@@ -169,6 +172,11 @@
if (expanded != extension->current_application->application_data) {
switch_safe_free(expanded);
}
+
+ if (switch_channel_test_flag(session->channel, CF_RESET)) {
+ goto top;
+ }
+
extension->current_application = extension->current_application->next;
}
Modified: freeswitch/branches/greenlizard/src/switch_event.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_event.c (original)
+++ freeswitch/branches/greenlizard/src/switch_event.c Mon Aug 20 13:37:13 2007
@@ -455,7 +455,10 @@
(*event)->event_id = event_id;
if (subclass_name) {
- (*event)->subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name);
+ if (!((*event)->subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name))) {
+ switch_event_reserve_subclass((char *)subclass_name);
+ (*event)->subclass = switch_core_hash_find(CUSTOM_HASH, subclass_name);
+ }
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Subclass", "%s", subclass_name);
}
@@ -806,6 +809,7 @@
switch_time_exp_t tm;
char date[80] = "";
switch_size_t retsize;
+ switch_time_t ts = switch_time_now();
assert(BLOCK != NULL);
assert(RUNTIME_POOL != NULL);
@@ -822,11 +826,12 @@
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Name", "%s", switch_event_name((*event)->event_id));
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Core-UUID", "%s", switch_core_get_uuid());
- switch_time_exp_lt(&tm, switch_time_now());
+ switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Date-Local", "%s", date);
- switch_rfc822_date(date, switch_time_now());
+ switch_rfc822_date(date, ts);
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Date-GMT", "%s", date);
+ switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Date-timestamp", "%"SWITCH_UINT64_T_FMT, (uint64_t)ts);
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Calling-File", "%s", switch_cut_path(file));
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Calling-Function", "%s", func);
switch_event_add_header(*event, SWITCH_STACK_BOTTOM, "Event-Calling-Line-Number", "%d", line);
Modified: freeswitch/branches/greenlizard/src/switch_ivr.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_ivr.c (original)
+++ freeswitch/branches/greenlizard/src/switch_ivr.c Mon Aug 20 13:37:13 2007
@@ -283,7 +283,6 @@
return SWITCH_STATUS_FALSE;
}
- hlen = (switch_size_t) strlen(cmd);
cmd_hash = switch_hashfunc_default(cmd, &hlen);
switch_channel_set_flag(channel, CF_EVENT_PARSE);
@@ -891,8 +890,17 @@
switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL);
- if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))
- && (other_session = switch_core_session_locate(uuid))) {
+
+ /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE
+ * will not have a value, so we need to check SWITCH_BRIDGE_VARIABLE */
+
+ uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
+
+ if(!uuid) {
+ uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE);
+ }
+
+ if (uuid && (other_session = switch_core_session_locate(uuid))) {
switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL);
switch_core_session_rwunlock(other_session);
}
@@ -907,6 +915,9 @@
switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL);
switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL);
+
+ /* If we are transferring the CALLER out of the bridge, we do not want to hang up on them */
+ switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "false");
switch_channel_hangup(other_channel, SWITCH_CAUSE_BLIND_TRANSFER);
switch_ivr_media(uuid, SMF_NONE);
Modified: freeswitch/branches/greenlizard/src/switch_ivr_async.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_ivr_async.c (original)
+++ freeswitch/branches/greenlizard/src/switch_ivr_async.c Mon Aug 20 13:37:13 2007
@@ -623,7 +623,7 @@
return SWITCH_STATUS_MEMERR;
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Adding tone spec %s index %d\n", tone_spec, cont->index);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding tone spec %s index %d\n", tone_spec, cont->index);
i = 0;
p = (char *) tone_spec;
Modified: freeswitch/branches/greenlizard/src/switch_ivr_bridge.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_ivr_bridge.c (original)
+++ freeswitch/branches/greenlizard/src/switch_ivr_bridge.c Mon Aug 20 13:37:13 2007
@@ -56,6 +56,7 @@
switch_frame_t *read_frame;
switch_core_session_t *session_a, *session_b;
uint32_t loop_count = 0;
+ char *app_name = NULL, *app_arg = NULL;
session_a = data->session;
if (!(session_b = switch_core_session_locate(data->b_uuid))) {
@@ -186,6 +187,28 @@
msg.from = __FILE__;
switch_core_session_receive_message(session_a, &msg);
+ if (switch_channel_get_state(chan_a) < CS_HANGUP) {
+ if ((app_name = switch_channel_get_variable(chan_a, SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE))) {
+ switch_caller_extension_t *extension = NULL;
+ if ((extension = switch_caller_extension_new(session_a, app_name, app_name)) == 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n");
+ goto end;
+ }
+ app_arg = switch_channel_get_variable(chan_a, SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE);
+
+ switch_caller_extension_add_application(session_a, extension, (char *) app_name, app_arg);
+ switch_channel_set_caller_extension(chan_a, extension);
+
+ if (switch_channel_get_state(chan_a) == CS_EXECUTE) {
+ switch_channel_set_flag(chan_a, CF_RESET);
+ } else {
+ switch_channel_set_state(chan_a, CS_EXECUTE);
+ }
+ }
+ }
+
+ end:
+
switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
switch_core_session_reset(session_a);
switch_channel_set_variable(chan_a, SWITCH_BRIDGE_VARIABLE, NULL);
@@ -528,6 +551,9 @@
int stream_id = 0;
switch_status_t status = SWITCH_STATUS_SUCCESS;
+ assert(session != NULL);
+ assert(peer_session != NULL);
+
caller_channel = switch_core_session_get_channel(session);
assert(caller_channel != NULL);
@@ -641,8 +667,8 @@
done:
- if (switch_channel_get_state(caller_channel) < CS_HANGUP
- && switch_true(switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE))) {
+ if (switch_channel_get_state(caller_channel) < CS_HANGUP &&
+ switch_true(switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE))) {
switch_channel_hangup(caller_channel, switch_channel_get_cause(peer_channel));
}
Modified: freeswitch/branches/greenlizard/src/switch_ivr_originate.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_ivr_originate.c (original)
+++ freeswitch/branches/greenlizard/src/switch_ivr_originate.c Mon Aug 20 13:37:13 2007
@@ -373,7 +373,7 @@
fail_on_single_reject = 1;
}
- if (!switch_strlen_zero(file) && !strcmp(file, "undef")) {
+ if ((*file != '\0') && (!strcmp(file, "undef"))) {
*file = '\0';
}
Modified: freeswitch/branches/greenlizard/src/switch_ivr_play_say.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_ivr_play_say.c (original)
+++ freeswitch/branches/greenlizard/src/switch_ivr_play_say.c Mon Aug 20 13:37:13 2007
@@ -123,7 +123,7 @@
}
switch_url_encode(data, enc_hint, sizeof(enc_hint));
- snprintf(hint_data, sizeof(hint_data), "macro_name=%s&lang=%s&data=%s", macro_name, chan_lang, enc_hint);
+ snprintf(hint_data, sizeof(hint_data), "macro_name=%s&lang=%s&data=%s&destination_number=%s", macro_name, chan_lang, enc_hint, switch_channel_get_variable(channel,"destination_number"));
if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of phrases failed.\n");
@@ -942,10 +942,10 @@
olen = llen;
}
- write_frame.samples = olen;
+ write_frame.samples = (uint32_t)olen;
if (asis) {
- write_frame.datalen = olen;
+ write_frame.datalen = (uint32_t)olen;
} else {
write_frame.datalen = write_frame.samples * 2;
}
@@ -1156,7 +1156,7 @@
int lead_in_out = 10;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
- uint32_t rate = 0, samples = 0;
+ uint32_t rate = 0;
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
@@ -1170,9 +1170,8 @@
write_frame.data = abuf;
write_frame.buflen = sizeof(abuf);
- samples = (uint32_t) (sh->rate / 50);
- len = samples * 2;
-
+ len = sh->samples * 2;
+
flags = 0;
switch_sleep(200000);
switch_core_speech_feed_tts(sh, text, &flags);
@@ -1345,7 +1344,6 @@
{
switch_channel_t *channel;
int interval = 0;
- uint32_t samples = 0;
uint32_t len = 0;
switch_frame_t write_frame = { 0 };
switch_timer_t timer;
@@ -1366,9 +1364,9 @@
timer_name = switch_channel_get_variable(channel, "timer_name");
switch_core_session_reset(session);
-
+ read_codec = switch_core_session_get_read_codec(session);
+
if (rate == 0) {
- read_codec = switch_core_session_get_read_codec(session);
rate = read_codec->implementation->samples_per_second;
}
@@ -1382,9 +1380,9 @@
switch_channel_answer(channel);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "OPEN TTS %s\n", tts_name);
- interval = 20;
- samples = (uint32_t) (rate / 50);
- len = samples * 2;
+ interval = read_codec->implementation->microseconds_per_frame / 1000;
+ sh.samples = switch_bytes_per_frame(rate, interval);
+ len = sh.samples * 2;
codec_name = "L16";
@@ -1402,7 +1400,7 @@
}
if (timer_name) {
- if (switch_core_timer_init(&timer, timer_name, interval, (int) samples, pool) != SWITCH_STATUS_SUCCESS) {
+ if (switch_core_timer_init(&timer, timer_name, interval, (int) sh.samples, pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
switch_core_codec_destroy(write_frame.codec);
flags = 0;
Modified: freeswitch/branches/greenlizard/src/switch_loadable_module.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_loadable_module.c (original)
+++ freeswitch/branches/greenlizard/src/switch_loadable_module.c Mon Aug 20 13:37:13 2007
@@ -749,8 +749,6 @@
#ifdef WIN32
const char *ext = ".dll";
-#elif defined (MACOSX) || defined (DARWIN)
- const char *ext = ".dylib";
#else
const char *ext = ".so";
#endif
Modified: freeswitch/branches/greenlizard/src/switch_xml.c
==============================================================================
--- freeswitch/branches/greenlizard/src/switch_xml.c (original)
+++ freeswitch/branches/greenlizard/src/switch_xml.c Mon Aug 20 13:37:13 2007
@@ -951,8 +951,8 @@
char *arg, *e;
char *bp = expand_vars(buf, ebuf, sizeof(ebuf), &cur);
- /* we ignore <include> or </include> for the sake of validators */
- if (strstr(buf, "<include>") || strstr(buf, "</include>")) {
+ /* we ignore <include> or </include> for the sake of validators as well as <?xml version="1.0"?> type stuff */
+ if (strstr(buf, "<include>") || strstr(buf, "</include>") || strstr(buf, "<?")) {
continue;
}
@@ -966,12 +966,16 @@
}
}
- if ((cmd = strstr(bp, "<!--#"))) {
- write(write_fd, bp, (unsigned) (cmd - bp));
+ if ((cmd = strstr(bp, "<!--#"))) {
+ if(write(write_fd, bp, (unsigned) (cmd - bp)) != (cmd - bp)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Short write!\n");
+ }
if ((e = strstr(cmd, "-->"))) {
*e = '\0';
- e += 3;
- write(write_fd, e, (unsigned) strlen(e));
+ e += 3;
+ if(write(write_fd, e, (unsigned) strlen(e)) != (int) strlen(e)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Short write!\n");
+ }
} else {
ml++;
}
@@ -1027,8 +1031,11 @@
continue;
}
-
- write(write_fd, bp, (unsigned) cur);
+
+ if(write(write_fd, bp, (unsigned) cur) != (int) cur) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Short write!\n");
+ }
+
}
close(read_fd);
Modified: freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj
==============================================================================
--- freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj (original)
+++ freeswitch/branches/greenlizard/w32/Library/FreeSwitchCore.vcproj Mon Aug 20 13:37:13 2007
@@ -576,7 +576,7 @@
Name="Generated Header Files"
>
<File
- RelativePath="..\..\src\include\switch_am_config.h.in"
+ RelativePath="..\..\src\include\switch_am_config.h.template"
>
<FileConfiguration
Name="Debug|Win32"
@@ -596,7 +596,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\src\include\switch_version.h.in"
+ RelativePath="..\..\src\include\switch_version.h.template"
>
<FileConfiguration
Name="Debug|Win32"
@@ -604,7 +604,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Generating switch_version.h"
- CommandLine="cscript /nologo "$(ProjectDir)..\..\libs\win32\util.vbs" Version "$(ProjectDir)" "$(ProjectDir)..\..\" "$(ProjectDir)..\..\src\include\switch_version.h.in" "$(ProjectDir)..\..\src\include\switch_version.h"
"
+ CommandLine="cscript /nologo "$(ProjectDir)..\..\libs\win32\util.vbs" Version "$(ProjectDir)" "$(ProjectDir)..\..\" "$(ProjectDir)..\..\src\include\switch_version.h.template" "$(ProjectDir)..\..\src\include\switch_version.h"
"
AdditionalDependencies="..\..\src\include\switch.h;..\..\src\include\switch_apr.h;..\..\src\include\switch_buffer.h;..\..\src\include\switch_caller.h;..\..\src\include\switch_channel.h;..\..\src\include\switch_console.h;..\..\src\include\switch_core.h;..\..\src\include\switch_event.h;..\..\src\include\switch_frame.h;..\..\src\include\switch_ivr.h;..\..\src\include\switch_loadable_module.h;..\..\src\include\switch_log.h;..\..\src\include\switch_module_interfaces.h;..\..\src\include\switch_platform.h;..\..\src\include\switch_resample.h;..\..\src\include\switch_rtp.h;..\..\src\include\switch_sqlite.h;..\..\src\include\switch_stun.h;..\..\src\include\switch_types.h;..\..\src\include\switch_utils.h;..\..\src\include\switch_xml.h;..\..\src\switch_buffer.c;..\..\src\switch_caller.c;..\..\src\switch_channel.c;..\..\src\switch_config.c;..\..\src\switch_console.c;..\..\src\switch_core.c;..\..\src\switch_event.c;..\..\src\switch_ivr.c;..\..\src\switch_loadable_module.c;..\..\src\switch_log.c;..\..\src\switch_resample.c;..\..\src\switch_rtp.c;..\..\src\switch_stun.c;..\..\src\switch_utils.c;..\..\src\switch_xml.c"
Outputs="..\..\src\include\switch_version.h;lastversion"
/>
@@ -615,7 +615,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Generating switch_version.h"
- CommandLine="cscript /nologo "$(ProjectDir)..\..\libs\win32\util.vbs" Version "$(ProjectDir)" "$(ProjectDir)..\..\" "$(ProjectDir)..\..\src\include\switch_version.h.in" "$(ProjectDir)..\..\src\include\switch_version.h"
"
+ CommandLine="cscript /nologo "$(ProjectDir)..\..\libs\win32\util.vbs" Version "$(ProjectDir)" "$(ProjectDir)..\..\" "$(ProjectDir)..\..\src\include\switch_version.h.template" "$(ProjectDir)..\..\src\include\switch_version.h"
"
AdditionalDependencies="..\..\src\include\switch.h;..\..\src\include\switch_apr.h;..\..\src\include\switch_buffer.h;..\..\src\include\switch_caller.h;..\..\src\include\switch_channel.h;..\..\src\include\switch_console.h;..\..\src\include\switch_core.h;..\..\src\include\switch_event.h;..\..\src\include\switch_frame.h;..\..\src\include\switch_ivr.h;..\..\src\include\switch_loadable_module.h;..\..\src\include\switch_log.h;..\..\src\include\switch_module_interfaces.h;..\..\src\include\switch_platform.h;..\..\src\include\switch_resample.h;..\..\src\include\switch_rtp.h;..\..\src\include\switch_sqlite.h;..\..\src\include\switch_stun.h;..\..\src\include\switch_types.h;..\..\src\include\switch_utils.h;..\..\src\include\switch_xml.h;..\..\src\switch_buffer.c;..\..\src\switch_caller.c;..\..\src\switch_channel.c;..\..\src\switch_config.c;..\..\src\switch_console.c;..\..\src\switch_core.c;..\..\src\switch_event.c;..\..\src\switch_ivr.c;..\..\src\switch_loadable_module.c;..\..\src\switch_log.c;..\..\src\switch_resample.c;..\..\src\switch_rtp.c;..\..\src\switch_stun.c;..\..\src\switch_utils.c;..\..\src\switch_xml.c"
Outputs="..\..\src\include\switch_version.h;lastversion"
/>
1
0
[Freeswitch-branches] [commit] r5596 - freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp
by Freeswitch SVN 13 Aug '07
by Freeswitch SVN 13 Aug '07
13 Aug '07
Author: greenlizard
Date: Mon Aug 13 19:48:43 2007
New Revision: 5596
Modified:
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
Log:
speak-finished event now being handled, passed up to freeswitch to let it know speech has stopped. audio sounds fine
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Mon Aug 13 19:48:43 2007
@@ -176,7 +176,8 @@
typedef enum {
FLAG_HAS_TEXT = (1 << 0),
FLAG_BARGE = (1 << 1),
- FLAG_READY = (1 << 2)
+ FLAG_READY = (1 << 2),
+ FLAG_SPEAK_COMPLETE = (1 << 3)
} mrcp_flag_t;
typedef struct {
@@ -501,8 +502,21 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "!tts_session\n");
return MRCP_STATUS_FAILURE;
}
+
+ if (mrcp_message->start_line.method_name) {
+ if (!strcmp(mrcp_message->start_line.method_name,"SPEAK-COMPLETE")) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setting FLAG_SPEAK_COMPLETE\n");
+ switch_set_flag_locked(tts_session, FLAG_SPEAK_COMPLETE);
+ }
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ignoring method: %s\n", mrcp_message->start_line.method_name);
+ }
+ }
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "mrcp msg body: %s\n", mrcp_message->body);
+
+
return tts_session_signal_event(tts_session,OPENMRCP_EVENT_CHANNEL_MODIFY);
}
@@ -583,45 +597,6 @@
}
-/**
- * Called back by openmrcp client thread every time it receives audio
- * from the TTS server we are connected to. Puts audio in a queueu
- * and it will be pulled out from read_tts
- */
-static apr_status_t openmrcp_tts_write_frame_NEW(audio_sink_t *sink, media_frame_t *frame)
-{
- tts_session_t *tts_session = sink->object;
- media_frame_t *media_frame;
- switch_byte_t *buffer;
- size_t len;
- apr_status_t status = MRCP_STATUS_SUCCESS;
-
- len = frame->codec_frame.size;
-
- // since *frame might get freed by caller (true or false?), allocate a
- // new buffer and copy *data into it.
- buffer = (switch_byte_t *) switch_core_alloc(tts_session->pool, sizeof(switch_byte_t)*len);
- if (!buffer) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate buffer\n");
- return MRCP_STATUS_FAILURE;
- }
-
- // push audio to buffer
- switch_mutex_lock(tts_session->audio_lock);
- if (switch_buffer_write(tts_session->audio_buffer, buffer, len) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not write to buffer\n");
- status = MRCP_STATUS_FAILURE;
- }
- else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "wrote %d bytes to buffer\n", len);
- }
- switch_mutex_unlock(tts_session->audio_lock);
-
- return status;
-
-}
-
-
/**
* Called back by openmcp client thread every time its ready for more audio to send
* the recognition server we are connected to. Reads data that was put into a
@@ -1176,24 +1151,6 @@
* TODO: check the blocking flag passed in flags and act accordingly
* (see mod_cepstral.c)
*/
-static switch_status_t openmrcp_read_tts_OLD(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
-{
- media_frame_t *queue_frame = NULL;
- tts_session_t *tts_session = (tts_session_t *) sh->private_info;
-
- if (switch_queue_trypop(tts_session->audio_queue, (void *) &queue_frame)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "could not pop from queue\n");
- return SWITCH_STATUS_SUCCESS;
- }
- else {
- memcpy(data, queue_frame->codec_frame.buffer, queue_frame->codec_frame.size);
- *datalen = queue_frame->codec_frame.size;
- *rate = 8000;
- return SWITCH_STATUS_SUCCESS;
- }
-
-}
-
static switch_status_t openmrcp_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
{
media_frame_t *queue_frame = NULL;
@@ -1201,27 +1158,44 @@
size_t return_len=0;
size_t amt2copy=0;
size_t desired = *datalen;
-
+ switch_byte_t *audiodata = (switch_byte_t *) data;
while(return_len < desired) {
+ if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
+ // tell fs we are done
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
+ return SWITCH_STATUS_BREAK;
+ }
+
if (switch_queue_pop(tts_session->audio_queue, (void *) &queue_frame)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "could not pop from queue\n");
+ if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
+ // tell fs we are done
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
+ return SWITCH_STATUS_BREAK;
+ }
break;
}
else {
+ if (switch_test_flag(tts_session, FLAG_SPEAK_COMPLETE)) {
+ // tell fs we are done
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FLAG_SPEAK_COMPLETE\n");
+ return SWITCH_STATUS_BREAK;
+ }
+
if (queue_frame->codec_frame.size >= desired) {
amt2copy = desired;
}
else {
- // limit the amt we copy to data to be LTE datalen
+ // limit the amt we copy to audiodata to be LTE datalen
// if the queue frame has _more_, just ignore it (TODO: fix this!)
amt2copy = queue_frame->codec_frame.size;
}
- memcpy(data, queue_frame->codec_frame.buffer, amt2copy);
+ memcpy(audiodata, queue_frame->codec_frame.buffer, amt2copy);
return_len += amt2copy;
*datalen = return_len;
- data += amt2copy; // move pointer forward
+ audiodata += amt2copy; // move pointer forward
*rate = 8000;
}
@@ -1232,49 +1206,13 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no data read from buffer\n");
return SWITCH_STATUS_FALSE;
}
- else if (datalen < desired) {
+ else if (*datalen < desired) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "return_len: (%d) < desired: (%d)\n", return_len, desired);
}
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t openmrcp_read_tts_NEW(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
-{
- media_frame_t *queue_frame = NULL;
- tts_session_t *tts_session = (tts_session_t *) sh->private_info;
- switch_status_t status = SWITCH_STATUS_FALSE;
- size_t used, padding = 0;
- size_t desired = *datalen;
-
- *rate = 8000;
-
- switch_mutex_lock(tts_session->audio_lock);
- used = switch_buffer_inuse(tts_session->audio_buffer);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "used: %d\n", used);
- switch_mutex_unlock(tts_session->audio_lock);
-
- if (used == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "used == 0\n");
- //*datalen = 0;
- return SWITCH_STATUS_SUCCESS;
- }
-
- if (used < desired) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "used < desired (%d)\n", desired);
- //*datalen = 0;
- return SWITCH_STATUS_SUCCESS;
- }
-
- switch_mutex_lock(tts_session->audio_lock);
- *datalen = switch_buffer_read(tts_session->audio_buffer, data, desired);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "successfully read %d bytes into data buffer\n", *datalen);
- switch_mutex_unlock(tts_session->audio_lock);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-
static void openmrcp_flush_tts(switch_speech_handle_t *sh)
{
@@ -1385,6 +1323,8 @@
}
}
+ switch_xml_free(xml);
+
return SWITCH_STATUS_SUCCESS;
}
1
0
[Freeswitch-branches] [commit] r5594 - freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp
by Freeswitch SVN 13 Aug '07
by Freeswitch SVN 13 Aug '07
13 Aug '07
Author: greenlizard
Date: Mon Aug 13 17:40:48 2007
New Revision: 5594
Modified:
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
Log:
sync up Makefile to what was checked into trunk. tts audio sounding ok, going to deal with channel close events from tts source
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/Makefile Mon Aug 13 17:40:48 2007
@@ -11,18 +11,15 @@
# - re-enable the -Werror flag after openmrcp compilation warnings are fixed
# - needs to compile/link against the _freeswitch_ sofia libs (see FIXME)
# - Should this download and build openmrcp? What's the plan? (see FIXME)
+# - somehow consolidate libs and includes into less files
# FIXME!!!
OPENMRCP_DIR=/usr/src/openmrcp_trunk
OPENMRCP_INCLUDE=-I$(OPENMRCP_DIR)/mrcpcore/client/include/ -I$(OPENMRCP_DIR)/platform/openmrcpclient/include/ -I$(OPENMRCP_DIR)/mediaframe/include/ -I$(OPENMRCP_DIR)/mrcpcore/engine/include/ -I$(OPENMRCP_DIR)/mrcpcore/include/ -I$(OPENMRCP_DIR)/mrcpcore/parser/include/ -I$(OPENMRCP_DIR)/mrcpcore/server/include/ -I$(OPENMRCP_DIR)/mrcpcore/media/include/ -I$(OPENMRCP_DIR)/mrcpcore/util/include -I$(OPENMRCP_DIR)/mrcpcore/resource/include/
-OPENMRCP_LIBS_TRUNK=$(OPENMRCP_DIR)/platform/openmrcpclient/.libs/libopenmrcpclient.a $(OPENMRCP_DIR)/platform/openmrcpserver/.libs/libopenmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/client/.libs/libmrcpclient.a $(OPENMRCP_DIR)/mediaframe/.libs/libmediaframe.a $(OPENMRCP_DIR)/mrcpcore/engine/.libs/libmrcpengine.a $(OPENMRCP_DIR)/mrcpcore/parser/.libs/libmrcpparser.a $(OPENMRCP_DIR)/mrcpcore/server/.libs/libmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/media/.libs/libmrcpmedia.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/resource/.libs/libmrcpresource.a $(OPENMRCP_DIR)/module/plugin/demo/.libs/libdemoplugin.a $(OPENMRCP_DIR)/module/mrcpv2agent/.libs/libmrcpv2agent.a $(OPENMRCP_DIR)/module/mrcpmediaframe/.libs/libmrcpmediaframe.a $(OPENMRCP_DIR)/module/mrcpsofiasip/.libs/libmrcpsofiasip.a $(OPENMRCP_DIR)/mrcpcore/.libs/libmrcpcore.a
+OPENMRCP_LIBS=$(OPENMRCP_DIR)/platform/openmrcpclient/.libs/libopenmrcpclient.a $(OPENMRCP_DIR)/platform/openmrcpserver/.libs/libopenmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/client/.libs/libmrcpclient.a $(OPENMRCP_DIR)/mediaframe/.libs/libmediaframe.a $(OPENMRCP_DIR)/mrcpcore/engine/.libs/libmrcpengine.a $(OPENMRCP_DIR)/mrcpcore/parser/.libs/libmrcpparser.a $(OPENMRCP_DIR)/mrcpcore/server/.libs/libmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/media/.libs/libmrcpmedia.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/resource/.libs/libmrcpresource.a $(OPENMRCP_DIR)/module/plugin/demo/.libs/libdemoplugin.a $(OPENMRCP_DIR)/module/mrcpv2agent/.libs/libmrcpv2agent.a $(OPENMRCP_DIR)/module/mrcpmediaframe/.libs/libmrcpmediaframe.a $(OPENMRCP_DIR)/module/mrcpsofiasip/.libs/libmrcpsofiasip.a $(OPENMRCP_DIR)/mrcpcore/.libs/libmrcpcore.a
-# can remove this ..
-OPENMRCP_LIBS_STABLE=$(OPENMRCP_DIR)/platform/openmrcpclient/.libs/libopenmrcpclient.a $(OPENMRCP_DIR)/platform/openmrcpserver/.libs/libopenmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/client/.libs/libmrcpclient.a $(OPENMRCP_DIR)/mediaframe/.libs/libmediaframe.a $(OPENMRCP_DIR)/mrcpcore/engine/.libs/libmrcpengine.a $(OPENMRCP_DIR)/mrcpcore/parser/.libs/libmrcpparser.a $(OPENMRCP_DIR)/mrcpcore/server/.libs/libmrcpserver.a $(OPENMRCP_DIR)/mrcpcore/media/.libs/libmrcpmedia.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/util/.libs/libmrcputil.a $(OPENMRCP_DIR)/mrcpcore/resource/.libs/libmrcpresource.a $(OPENMRCP_DIR)/module/plugin/demo/.libs/libdemoplugin.a $(OPENMRCP_DIR)/module/mrcpv2agent/.libs/libmrcpv2agent.a $(OPENMRCP_DIR)/module/mrcplivemedia/.libs/libmrcplivemedia.a $(OPENMRCP_DIR)/module/mrcpsofiasip/.libs/libmrcpsofiasip.a $(OPENMRCP_DIR)/mrcpcore/.libs/libmrcpcore.a
-
-OPENMRCP_LIBS=$(OPENMRCP_LIBS_TRUNK)
MRCP_APR_INCLUDES = -I../../../../libs/apr/include
MRCP_APU_INCLUDES = -I../../../../libs/apr-util/include
MRCP_SOFIA_INCLUDES = -I/usr/local/include/sofia-sip-1.12 # FIXME!!
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Mon Aug 13 17:40:48 2007
@@ -87,7 +87,7 @@
#include <switch.h>
#define OPENMRCP_WAIT_TIMEOUT 5000
-#define MY_BUF_LEN 1024 * 32
+#define MY_BUF_LEN 1024 * 128
#define MY_BLOCK_SIZE MY_BUF_LEN
SWITCH_MODULE_LOAD_FUNCTION(mod_openmrcp_load);
@@ -261,6 +261,8 @@
return MRCP_STATUS_FAILURE;
}
+ switch_buffer_destroy(&tts_session->audio_buffer);
+
if(tts_session->pool) {
apr_pool_destroy(tts_session->pool);
tts_session->pool = NULL;
@@ -585,54 +587,39 @@
* Called back by openmrcp client thread every time it receives audio
* from the TTS server we are connected to. Puts audio in a queueu
* and it will be pulled out from read_tts
-
+ */
static apr_status_t openmrcp_tts_write_frame_NEW(audio_sink_t *sink, media_frame_t *frame)
{
tts_session_t *tts_session = sink->object;
media_frame_t *media_frame;
switch_byte_t *buffer;
size_t len;
+ apr_status_t status = MRCP_STATUS_SUCCESS;
len = frame->codec_frame.size;
- // create new media frame
- media_frame = (media_frame_t *) switch_core_alloc(tts_session->pool, sizeof(media_frame_t));
- if (!media_frame) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "media_frame creation failed\n");
- return SWITCH_STATUS_MEMERR;
- }
-
// since *frame might get freed by caller (true or false?), allocate a
// new buffer and copy *data into it.
buffer = (switch_byte_t *) switch_core_alloc(tts_session->pool, sizeof(switch_byte_t)*len);
if (!buffer) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate buffer\n");
- return SWITCH_STATUS_MEMERR;
+ return MRCP_STATUS_FAILURE;
}
- buffer = memcpy(buffer, frame->codec_frame.buffer, len);
- media_frame->codec_frame.buffer = buffer;
- media_frame->codec_frame.size = len;
- media_frame->type = MEDIA_FRAME_TYPE_AUDIO;
-
- // add audio to buffer
+ // push audio to buffer
switch_mutex_lock(tts_session->audio_lock);
if (switch_buffer_write(tts_session->audio_buffer, buffer, len) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not write to buffer\n");
+ status = MRCP_STATUS_FAILURE;
}
- switch_mutex_unlock(tts_session->audio_lock);
-
- switch_mutex_unlock(tts_session->audio_lock);
-
- if (switch_queue_trypush(tts_session->audio_queue, (void *) media_frame)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "could not push audio to queue\n");
- return MRCP_STATUS_FAILURE;
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "wrote %d bytes to buffer\n", len);
}
+ switch_mutex_unlock(tts_session->audio_lock);
- return MRCP_STATUS_SUCCESS;
+ return status;
}
-*/
/**
@@ -1140,6 +1127,8 @@
synth_stop(tts_client_context,tts_session); // TODO
wait_for_event(tts_session->event_queue,OPENMRCP_EVENT_CHANNEL_MODIFY,5000);
+
+
/* terminate tts session */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Terminate tts_session\n");
mrcp_client_context_session_terminate(tts_client_context,tts_session->client_session);
@@ -1187,7 +1176,7 @@
* TODO: check the blocking flag passed in flags and act accordingly
* (see mod_cepstral.c)
*/
-static switch_status_t openmrcp_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
+static switch_status_t openmrcp_read_tts_OLD(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
{
media_frame_t *queue_frame = NULL;
tts_session_t *tts_session = (tts_session_t *) sh->private_info;
@@ -1205,6 +1194,87 @@
}
+static switch_status_t openmrcp_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
+{
+ media_frame_t *queue_frame = NULL;
+ tts_session_t *tts_session = (tts_session_t *) sh->private_info;
+ size_t return_len=0;
+ size_t amt2copy=0;
+ size_t desired = *datalen;
+
+
+ while(return_len < desired) {
+
+ if (switch_queue_pop(tts_session->audio_queue, (void *) &queue_frame)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "could not pop from queue\n");
+ break;
+ }
+ else {
+ if (queue_frame->codec_frame.size >= desired) {
+ amt2copy = desired;
+ }
+ else {
+ // limit the amt we copy to data to be LTE datalen
+ // if the queue frame has _more_, just ignore it (TODO: fix this!)
+ amt2copy = queue_frame->codec_frame.size;
+ }
+ memcpy(data, queue_frame->codec_frame.buffer, amt2copy);
+ return_len += amt2copy;
+ *datalen = return_len;
+ data += amt2copy; // move pointer forward
+ *rate = 8000;
+ }
+
+ }
+
+ // double check we actually read something
+ if (*datalen == 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no data read from buffer\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ else if (datalen < desired) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "return_len: (%d) < desired: (%d)\n", return_len, desired);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t openmrcp_read_tts_NEW(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags)
+{
+ media_frame_t *queue_frame = NULL;
+ tts_session_t *tts_session = (tts_session_t *) sh->private_info;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ size_t used, padding = 0;
+ size_t desired = *datalen;
+
+ *rate = 8000;
+
+ switch_mutex_lock(tts_session->audio_lock);
+ used = switch_buffer_inuse(tts_session->audio_buffer);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "used: %d\n", used);
+ switch_mutex_unlock(tts_session->audio_lock);
+
+ if (used == 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "used == 0\n");
+ //*datalen = 0;
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ if (used < desired) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "used < desired (%d)\n", desired);
+ //*datalen = 0;
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ switch_mutex_lock(tts_session->audio_lock);
+ *datalen = switch_buffer_read(tts_session->audio_buffer, data, desired);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "successfully read %d bytes into data buffer\n", *datalen);
+ switch_mutex_unlock(tts_session->audio_lock);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
static void openmrcp_flush_tts(switch_speech_handle_t *sh)
{
1
0
[Freeswitch-branches] [commit] r5592 - freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp
by Freeswitch SVN 13 Aug '07
by Freeswitch SVN 13 Aug '07
13 Aug '07
Author: greenlizard
Date: Mon Aug 13 14:14:48 2007
New Revision: 5592
Modified:
freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
Log:
remove warnings coming from module before merge to trunk
Modified: freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c
==============================================================================
--- freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c (original)
+++ freeswitch/branches/greenlizard/src/mod/asr_tts/mod_openmrcp/mod_openmrcp.c Mon Aug 13 14:14:48 2007
@@ -53,6 +53,9 @@
* - fix audio problem with TTS, convert from using queue to using a switch_buffer
* (in progress)
*
+ * - use a regex for extracting xml from raw result received from mrcp recognition
+ * server
+ *
*/
#ifdef __ICC
@@ -582,28 +585,25 @@
* Called back by openmrcp client thread every time it receives audio
* from the TTS server we are connected to. Puts audio in a queueu
* and it will be pulled out from read_tts
- */
+
static apr_status_t openmrcp_tts_write_frame_NEW(audio_sink_t *sink, media_frame_t *frame)
{
tts_session_t *tts_session = sink->object;
media_frame_t *media_frame;
switch_byte_t *buffer;
size_t len;
- apr_status_t status =
len = frame->codec_frame.size;
- /* create new media frame */
+ // create new media frame
media_frame = (media_frame_t *) switch_core_alloc(tts_session->pool, sizeof(media_frame_t));
if (!media_frame) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "media_frame creation failed\n");
return SWITCH_STATUS_MEMERR;
}
- /**
- * since *frame might get freed by caller (true or false?), allocate a
- * new buffer and copy *data into it.
- **/
+ // since *frame might get freed by caller (true or false?), allocate a
+ // new buffer and copy *data into it.
buffer = (switch_byte_t *) switch_core_alloc(tts_session->pool, sizeof(switch_byte_t)*len);
if (!buffer) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate buffer\n");
@@ -615,7 +615,7 @@
media_frame->type = MEDIA_FRAME_TYPE_AUDIO;
- /* add audio to buffer */
+ // add audio to buffer
switch_mutex_lock(tts_session->audio_lock);
if (switch_buffer_write(tts_session->audio_buffer, buffer, len) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not write to buffer\n");
@@ -632,6 +632,7 @@
return MRCP_STATUS_SUCCESS;
}
+*/
/**
@@ -1190,8 +1191,6 @@
{
media_frame_t *queue_frame = NULL;
tts_session_t *tts_session = (tts_session_t *) sh->private_info;
- size_t requested_len = *datalen;
- size_t return_len = 0;
if (switch_queue_trypop(tts_session->audio_queue, (void *) &queue_frame)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "could not pop from queue\n");
1
0