From: Christopher Rienzo Date: Thu, 16 Jun 2011 16:25:00 +0000 (+0000) Subject: Update to latest UniMRCP version. MRCP requests can no timeout if there is no server... X-Git-Tag: v1.2-rc1~108^2~11^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17099473a3a8b1347b13331f260bd8ea9fd90804;p=thirdparty%2Ffreeswitch.git Update to latest UniMRCP version. MRCP requests can no timeout if there is no server response. --- diff --git a/conf/autoload_configs/unimrcp.conf.xml b/conf/autoload_configs/unimrcp.conf.xml index 452936bf7c..45dda798a1 100644 --- a/conf/autoload_configs/unimrcp.conf.xml +++ b/conf/autoload_configs/unimrcp.conf.xml @@ -12,6 +12,7 @@ + diff --git a/libs/unimrcp/.update b/libs/unimrcp/.update index 2c9225f323..05e080f0c9 100644 --- a/libs/unimrcp/.update +++ b/libs/unimrcp/.update @@ -1 +1 @@ -Mon Feb 22 09:40:01 CST 2010 +Thu Jun 16 15:02:31 UTC 2011 diff --git a/libs/unimrcp/AUTHORS b/libs/unimrcp/AUTHORS index d032c9e71a..6c7b0eee09 100644 --- a/libs/unimrcp/AUTHORS +++ b/libs/unimrcp/AUTHORS @@ -14,3 +14,4 @@ Contributor(s): Carlos Pina Soares Chaitanya Chokkareddy Tomas Valenta + Danijel Korzinek diff --git a/libs/unimrcp/Makefile.am b/libs/unimrcp/Makefile.am index eeb00cecb4..0421198eb9 100644 --- a/libs/unimrcp/Makefile.am +++ b/libs/unimrcp/Makefile.am @@ -14,7 +14,7 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure $(AUX_DIST) ACLOCAL = aclocal -I $(macrodir) -SUBDIRS = conf data libs modules plugins platforms build +SUBDIRS = build conf data libs modules plugins platforms if TEST_SUITES SUBDIRS += tests endif diff --git a/libs/unimrcp/NOTICE b/libs/unimrcp/NOTICE index bcd5c17ac5..37f1bf3c01 100644 --- a/libs/unimrcp/NOTICE +++ b/libs/unimrcp/NOTICE @@ -1,5 +1,5 @@ The UniMRCP Project (http://www.unimrcp.org) -Copyright (C) 2008 Arsen Chaloyan +Copyright (C) 2008-2010 Arsen Chaloyan Licensed under the Apache License, Version 2.0 (the "License"). This product includes a number of subcomponents with diff --git a/libs/unimrcp/acinclude.m4 b/libs/unimrcp/acinclude.m4 index 46eb391ab8..7a487f7046 100644 --- a/libs/unimrcp/acinclude.m4 +++ b/libs/unimrcp/acinclude.m4 @@ -3,7 +3,6 @@ m4_include([build/acmacros/apu.m4]) m4_include([build/acmacros/find_apr.m4]) m4_include([build/acmacros/find_apu.m4]) m4_include([build/acmacros/sofia-sip.m4]) -m4_include([build/acmacros/swift.m4]) m4_include([build/acmacros/sphinxbase.m4]) m4_include([build/acmacros/pocketsphinx.m4]) m4_include([build/acmacros/flite.m4]) diff --git a/libs/unimrcp/build/Makefile.am b/libs/unimrcp/build/Makefile.am index dfacd94fc1..822c9173c8 100644 --- a/libs/unimrcp/build/Makefile.am +++ b/libs/unimrcp/build/Makefile.am @@ -1,5 +1,9 @@ MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = uni_revision.h -SUBDIRS = pkgconfig +SUBDIRS = pkgconfig svnrev -include_HEADERS = uni_version.h +include_HEADERS = uni_version.h uni_revision.h + +uni_revision.h : + svnrev/svnrev -rsvnrev/svnrev.input -p../ -ouni_revision.h diff --git a/libs/unimrcp/build/acmacros/flite.m4 b/libs/unimrcp/build/acmacros/flite.m4 index a1991bc16b..5585e963b4 100644 --- a/libs/unimrcp/build/acmacros/flite.m4 +++ b/libs/unimrcp/build/acmacros/flite.m4 @@ -13,21 +13,28 @@ AC_DEFUN([UNIMRCP_CHECK_FLITE], found_flite="no" - flite_libdir="build/libs" + flite_config="config/config" for dir in $flite_path ; do cd $dir && flite_dir=`pwd` && cd - > /dev/null - if test -d "$dir/$flite_libdir"; then - found_flite="yes" - UNIMRCP_FLITE_INCLUDES="-I$flite_dir/include" - UNIMRCP_FLITE_LIBS="$dir/$flite_libdir/libflite_cmu_us_awb.a \ - $dir/$flite_libdir/libflite_cmu_us_kal.a \ - $dir/$flite_libdir/libflite_cmu_us_rms.a \ - $dir/$flite_libdir/libflite_cmu_us_slt.a \ - $dir/$flite_libdir/libflite_cmulex.a \ - $dir/$flite_libdir/libflite_usenglish.a \ - $dir/$flite_libdir/libflite.a" - break - fi + if test -f "$flite_dir/$flite_config"; then + target_os=`grep TARGET_OS "$flite_dir/$flite_config" | sed "s/^.*= //"` ;\ + target_cpu=`grep TARGET_CPU "$flite_dir/$flite_config" | sed "s/^.*= //"` ;\ + flite_libdir=$flite_dir/build/$target_cpu-$target_os/lib + if test -d "$flite_libdir"; then + UNIMRCP_FLITE_INCLUDES="-I$flite_dir/include" + UNIMRCP_FLITE_LIBS="$flite_libdir/libflite_cmu_us_awb.a \ + $flite_libdir/libflite_cmu_us_kal.a \ + $flite_libdir/libflite_cmu_us_rms.a \ + $flite_libdir/libflite_cmu_us_slt.a \ + $flite_libdir/libflite_cmulex.a \ + $flite_libdir/libflite_usenglish.a \ + $flite_libdir/libflite.a" + found_flite="yes" + break + else + AC_MSG_WARN(Cannot find Flite lib dir: $flite_libdir) + fi + fi done if test x_$found_flite != x_yes; then diff --git a/libs/unimrcp/build/acmacros/swift.m4 b/libs/unimrcp/build/acmacros/swift.m4 deleted file mode 100644 index b9049767a4..0000000000 --- a/libs/unimrcp/build/acmacros/swift.m4 +++ /dev/null @@ -1,28 +0,0 @@ -dnl UNIMRCP_CHECK_SWIFT - -AC_DEFUN([UNIMRCP_CHECK_SWIFT], -[ - AC_MSG_NOTICE([Cepstral Swift library configuration]) - - AC_MSG_CHECKING([for Swift]) - AC_ARG_WITH(swift, - [ --with-swift=PATH prefix for installed Swift], - [swift_path=$withval], - [swift_path="/opt/swift"] - ) - - if test -d "$swift_path"; then - found_swift="yes" - UNIMRCP_SWIFT_INCLUDES="-I$swift_path/include" - UNIMRCP_SWIFT_LIBS="-lswift -lceplex_us -lceplang_en -lm" - UNIMRCP_SWIFT_LDFLAGS="-L$swift_path/lib/ -R$swift_path/lib/" - - AC_SUBST(UNIMRCP_SWIFT_INCLUDES) - AC_SUBST(UNIMRCP_SWIFT_LIBS) - AC_SUBST(UNIMRCP_SWIFT_LDFLAGS) - - AC_MSG_RESULT($swift_path) - else - AC_MSG_WARN([not found - looked for $swift_path]) - fi -]) diff --git a/libs/unimrcp/build/init.d/unimrcp-server b/libs/unimrcp/build/init.d/unimrcp-server new file mode 100755 index 0000000000..29be4f3653 --- /dev/null +++ b/libs/unimrcp/build/init.d/unimrcp-server @@ -0,0 +1,271 @@ +#!/bin/sh +# +# unimrcp-server This shell script takes care of starting and stopping the UniMRCP server. +# +# chkconfig: 2345 65 35 +# description: UniMRCP is an open source MRCP v1 & v2 server + +# Some global variables + +# Application +APP_NAME="unimrcpserver" +APP_LONG_NAME="unimrcpserver" +UNIMRCP_DIR="/usr/local/unimrcp/" + +EXEC="${UNIMRCP_DIR}bin/${APP_NAME} -d -o 2 -r ${UNIMRCP_DIR}" + +# sudo user +USERNAME=root + +# Priority at which to run the server. See "man nice" for valid priorities. +# nice is only used if a priority is specified. +PRIORITY= + +# Location of the pid file. +PIDDIR="/var/run/" +pid= + +LOG="/var/log/${APP_NAME}.log" + +if [ -e $PIDDIR ]; then +echo +else +mkdir $PIDDIR +fi + +# Allow configuration overrides in /etc/sysconfig/$APP_NAME +CONFIGFILE=/etc/sysconfig/$APP_NAME + +[ -x $CONFIGFILE ] && . $CONFIGFILE + +# Do not modify anything beyond this point +#----------------------------------------------------------------------------- + +# Get the fully qualified path to the script +case $0 in + /*) + SCRIPT="$0" + ;; + *) + PWD=`pwd` + SCRIPT="$PWD/$0" + ;; +esac + +# Change spaces to ":" so the tokens can be parsed. +SCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'` +# Get the real path to this script, resolving any symbolic links +TOKENS=`echo $SCRIPT | sed -e 's;/; ;g'` +REALPATH= +for C in $TOKENS; do +REALPATH="$REALPATH/$C" + while [ -h "$REALPATH" ] ; do +LS="`ls -ld "$REALPATH"`" + LINK="`expr "$LS" : '.*-> \(.*\)$'`" + if expr "$LINK" : '/.*' > /dev/null; then +REALPATH="$LINK" + else +REALPATH="`dirname "$REALPATH"`""/$LINK" + fi +done +done +# Change ":" chars back to spaces. +REALPATH=`echo $REALPATH | sed -e 's;:; ;g'` + +# Change the current directory to the location of the script +cd "`dirname "$REALPATH"`" + +chown $USERNAME $PIDDIR + +# Process ID +PIDFILE="$PIDDIR/$APP_NAME.pid" + +# Resolve the location of the 'ps' command +PSEXE="/usr/bin/ps" +if [ ! -x $PSEXE ] +then +PSEXE="/bin/ps" + if [ ! -x $PSEXE ] + then +echo "Unable to locate 'ps'." + echo "Please report this with the location on your system." + exit 1 + fi +fi + +# Build the nice clause +if [ "X$PRIORITY" = "X" ] +then +CMDNICE="" +else +CMDNICE="nice -$PRIORITY" +fi + +getpid() { + if [ -f $PIDFILE ] + then +if [ -r $PIDFILE ] + then +pid=`cat $PIDFILE` + if [ "X$pid" != "X" ] + then + # Verify that a process with this pid is still running. + pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` + if [ "X$pid" = "X" ] + then + # This is a stale pid file. + rm -f $PIDFILE + echo "Removed stale pid file: $PIDFILE" + fi +fi +else +echo "Cannot read $PIDFILE." + exit 1 + fi +fi +} + +testpid() { + pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` + if [ "X$pid" = "X" ] + then + # Process is gone so remove the pid file. + rm -f $PIDFILE + fi +} + +console() { + echo "Running $APP_LONG_NAME..." + getpid + if [ "X$pid" = "X" ] + then +exec sudo -u $USERNAME $CMDNICE $EXEC + else +echo "$APP_LONG_NAME is already running." + exit 1 + fi +} + +start() { + echo "Starting $APP_LONG_NAME..." + getpid + if [ "X$pid" = "X" ] + then +sudo -u $USERNAME $CMDNICE $EXEC + pid=`$PSEXE -C $APP_NAME -o pid=` +echo $pid +echo $pid > $PIDFILE + else +echo "$APP_LONG_NAME is already running." + exit 1 + fi +} + +stopit() { + echo "Stopping $APP_LONG_NAME..." + getpid + if [ "X$pid" = "X" ] + then +echo "$APP_LONG_NAME was not running." + else + # Running so try to stop it. + sudo -u $USERNAME kill $pid + if [ $? -ne 0 ] + then + # An explanation for the failure should have been given + echo "Unable to stop $APP_LONG_NAME." + exit 1 + fi + + # We can not predict how long it will take for the wrapper to + # actually stop as it depends on settings in wrapper.conf. + # Loop until it does. + savepid=$pid + CNT=0 + TOTCNT=0 + while [ "X$pid" != "X" ] + do + # Loop for up to 5 minutes + if [ "$TOTCNT" -lt "300" ] + then +if [ "$CNT" -lt "5" ] + then +CNT=`expr $CNT + 1` + else +echo "Waiting for $APP_LONG_NAME to exit..." + CNT=0 + fi +TOTCNT=`expr $TOTCNT + 1` + + sleep 1 + + testpid + else +pid= + fi +done + +pid=$savepid + testpid + if [ "X$pid" != "X" ] + then +echo "Timed out waiting for $APP_LONG_NAME to exit." + echo " Attempting a forced exit..." + kill -9 $pid + fi + +pid=$savepid + testpid + if [ "X$pid" != "X" ] + then +echo "Failed to stop $APP_LONG_NAME." + exit 1 + else +echo "Stopped $APP_LONG_NAME." + fi +fi +} + +status() { + getpid + if [ "X$pid" = "X" ] + then +echo "$APP_LONG_NAME is not running." + exit 1 + else +echo "$APP_LONG_NAME is running ($pid)." + exit 0 + fi +} + +case "$1" in + + 'console') + console + ;; + + 'start') + start + ;; + + 'stop') + stopit + ;; + + 'restart') + stopit + start + ;; + + 'status') + status + ;; + + *) + echo "Usage: $0 { console | start | stop | restart | status }" + exit 1 + ;; +esac + +exit 0 + diff --git a/libs/unimrcp/build/svnrev/Makefile.am b/libs/unimrcp/build/svnrev/Makefile.am new file mode 100644 index 0000000000..5ce3ff2644 --- /dev/null +++ b/libs/unimrcp/build/svnrev/Makefile.am @@ -0,0 +1,10 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = $(UNIMRCP_APR_INCLUDES) $(UNIMRCP_APU_INCLUDES) + +noinst_PROGRAMS = svnrev +svnrev_LDADD = $(UNIMRCP_APR_LIBS) $(UNIMRCP_APU_LIBS) +svnrev_SOURCES = svnrev.c + +rev: + ./svnrev -rsvnrev.input -p../../ -o../uni_revision.h diff --git a/libs/unimrcp/build/svnrev/svnrev.c b/libs/unimrcp/build/svnrev/svnrev.c new file mode 100644 index 0000000000..154b07ef3f --- /dev/null +++ b/libs/unimrcp/build/svnrev/svnrev.c @@ -0,0 +1,381 @@ +/* SvnRev + * + * This utility retrieves the highest number that follows the "$Id: $" keyword + * or a combination of the $Rev: $ and $Date: $ keywords. The Subversion + * version control system expands these keywords and keeps them up to date. + * For an example of the tag, see the end of this comment. + * + * Details on the usage and the operation of this utility is available on-line + * at http://www.compuphase.com/svnrev.htm. + * + * + * Acknowledgements + * + * The support for .java files is contributed by Tom McCann (tommc@spoken.com). + * The option for prefixing and/or suffixing the build number (in the string + * constant SVN_REVSTR) was suggested by Robert Nitzel. + * + * + * License + * + * Copyright (c) 2005-2009, ITB CompuPhase (www.compuphase.com). + * + * This software is provided "as-is", without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id: svnrev.c 1497 2010-02-12 17:20:21Z achaloyan $ + */ + +#include +#include +#include + +#include +#include + + +#if defined __WIN32__ || defined _Win32 || defined _WIN32 + #define DIRSEP '\\' +#elif defined macintosh + #define DIRSEP ':' +#else + /* assume Linux/Unix */ + #define DIRSEP '/' +#endif + +#define MAX_LINELENGTH 512 +#define MAX_SYMBOLLENGTH 32 + +static void about(void) +{ + printf("svnrev 1.7.\n\n"); + printf("Usage: svnrev [options] [input [...]]\n\n" + "Options:\n" + "-ofilename\tOutput filename for the file with the build number. When no\n" + "\t\tfilename follows \"-o\", the result is written to stdout. The\n" + "\t\tdefault filename is \"svnrev.h\" for C/C++ and \"VersionInfo.java\"\n" + "\t\tfor Java.\n\n" + "-fpattern\tFormat: Adds text before or after the build number in the\n" + "\t\tconstant SVN_REVSTR. The pattern has the form \"text#text\"\n" + "\t\t(without the quotes) where \"text\" is arbitrary text and \"#\"\n" + "\t\twill be replaced by the build number.\n\n" + "-i\t\tIncremental: this option should be used when the list of input\n" + "\t\tfiles is a subset of all files in the project. When -i is\n" + "\t\tpresent, svnrev also scans the output file that was generated\n" + "\t\ton a previous run.\n\n" + "-jname\t\tJava: this option writes a java package file instead of a C/C++\n" + "\t\theader file. The name of the Java package must follow the\n" + "\t\toption (this is not the filename).\n\n" + "-v\t\tVerbose: prints the names of files that are modified since the\n" + "\t\tlast commit (into version control) to stderr.\n"); + exit(1); +} + +static void processfile(const char *name, int failsilent, + int *max_build, int *accum_build, + int *max_year, int *max_month, int *max_day, + int *ismodified) + +{ + char str[MAX_LINELENGTH], str_base[MAX_LINELENGTH]; + char name_base[MAX_LINELENGTH]; + char *p1; + FILE *fp, *fp_base; + int build, maj_build; + int year, month, day; + int cnt; + char modchar; + + /* since we also want to verify whether the file is modified in version + * control, get the path to the working copy name + * for every source file "\, the "working copy" base can + * be found in "\.svn\text-base\.svn-base" + */ + if ((p1 = strrchr(name, DIRSEP)) != NULL) { + ++p1; /* skip directory separator character ('\' in Windows, '/' in Linux) */ + strncpy(name_base, name, (int)(p1 - name)); + name_base[(int)(p1 - name)] = '\0'; + } else { + name_base[0] = '\0'; + p1 = (char*)name; + } /* if */ + sprintf(name_base + strlen(name_base), ".svn%ctext-base%c%s.svn-base", + DIRSEP, DIRSEP, p1); + + /* first extract the revision keywords */ + fp = fopen(name, "r"); + if (fp == NULL) { + if (!failsilent) + fprintf(stderr, "Failed to open input file '%s'\n", name); + return; + } /* if */ + fp_base = fopen(name_base, "r"); /* fail silently */ + build = 0; + maj_build = 0; /* RCS / CVS */ + year = month = day = 0; + + while (fgets(str, sizeof str, fp) != NULL) { + if (fp_base == NULL || fgets(str_base, sizeof str_base, fp_base) == NULL) + str_base[0] = '\0'; + if ((p1 = strstr(str, "$Id:")) != NULL && strchr(p1+1, '$') != NULL) { + if (sscanf(p1, "$Id: %*s %d %d-%d-%d", &build, &year, &month, &day) < 4 + && sscanf(p1, "$Id: %*s %d %d/%d/%d", &build, &year, &month, &day) < 4) + if (sscanf(p1, "$Id: %*s %d.%d %d-%d-%d", &maj_build, &build, &year, &month, &day) < 5) + sscanf(p1, "$Id: %*s %d.%d %d/%d/%d", &maj_build, &build, &year, &month, &day); + } else if ((p1 = strstr(str, "$Rev:")) != NULL && strchr(p1+1, '$') != NULL) { + if (sscanf(p1, "$Rev: %d.%d", &maj_build, &build) < 2) { + sscanf(p1, "$Rev: %d", &build); + maj_build = 0; + } /* if */ + } else if ((p1 = strstr(str, "$Revision:")) != NULL && strchr(p1+1, '$') != NULL) { + if (sscanf(p1, "$Revision: %d.%d", &maj_build, &build) < 2) { + /* SvnRev also writes this keyword in its own generated file; read it + * back for partial updates + */ + cnt = sscanf(p1, "$Revision: %d%c", &build, &modchar); + if (cnt == 2 && modchar == 'M' && ismodified != NULL) + *ismodified = 1; + maj_build = 0; + } /* if */ + } else if ((p1 = strstr(str, "$Date:")) != NULL && strchr(p1+1, '$') != NULL) { + if (sscanf(p1, "$Date: %d-%d-%d", &year, &month, &day) < 3) + sscanf(p1, "$Date: %d/%d/%d", &year, &month, &day); + } else if (ismodified != NULL && *ismodified == 0 && fp_base != NULL) { + /* no keyword present, compare the lines for equivalence */ + *ismodified = strcmp(str, str_base) != 0; + } /* if */ + + if (maj_build) + *accum_build += build; /* RCS / CVS */ + else if (build > *max_build) + *max_build = build; /* Subversion */ + if (year > *max_year + || (year == *max_year && month > *max_month) + || (year == *max_year && month == *max_month && day > *max_day)) + { + *max_year = year; + *max_month = month; + *max_day = day; + } /* if */ + if (build > 0 && year > 0 && (fp_base == NULL || ismodified == NULL || *ismodified != 0)) + break; /* both build # and date found, not comparing or modification + * already found => no need to search further */ + + } /* while */ + fclose(fp); + if (fp_base != NULL) + fclose(fp_base); +} + +int main(int argc, char *argv[]) +{ + char *outname = NULL; + FILE *fp; + FILE *input_file; + char *input_file_name = NULL; + char *path_prefix = NULL; + int index; + int process_self = 0; + int verbose = 0; + int max_build, accum_build; + int max_year, max_month, max_day; + int ismodified, filemodified; + char prefix[MAX_SYMBOLLENGTH], suffix[MAX_SYMBOLLENGTH]; + char modified_suffix[2]; + int write_java = 0; /* flag for Java output, 0=.h output, 1=.java output */ + /* java package to put revision info in. + * REVIEW - I assume if you want Java output you will specify a package. */ + char *java_package = NULL; + + if (argc <= 1) + about(); + + /* collect the options */ + prefix[0] = '\0'; + suffix[0] = '\0'; + + for (index = 1; index < argc; index++) { + /* check for options */ + if (argv[index][0] == '-' +#if defined __WIN32__ || defined _Win32 || defined _WIN32 + || argv[index][0] == '/' +#endif + ) + { + switch (argv[index][1]) { + case 'f': { + int len; + char *ptr = strchr(&argv[index][2], '#'); + len = (ptr != NULL) ? (int)(ptr - &argv[index][2]) : (int)strlen(&argv[index][2]); + if (len >= MAX_SYMBOLLENGTH) + len = MAX_SYMBOLLENGTH - 1; + strncpy(prefix, &argv[index][2], len); + prefix[len] = '\0'; + ptr = (ptr != NULL) ? ptr + 1 : strchr(argv[index], '\0'); + len = (int)strlen(ptr); + if (len >= MAX_SYMBOLLENGTH) + len = MAX_SYMBOLLENGTH - 1; + strncpy(suffix, ptr, len); + suffix[len] = '\0'; + break; + } /* case */ + case 'i': + process_self = 1; + break; + case 'j': + write_java=1; + java_package = &argv[index][2]; + break; + case 'o': + outname = &argv[index][2]; + break; + case 'r': + input_file_name = &argv[index][2]; + break; + case 'p': + path_prefix = &argv[index][2]; + break; + case 'v': + verbose = 1; + break; + default: + fprintf(stderr, "Invalid option '%s'\n", argv[index]); + about(); + } /* switch */ + } /* if */ + } /* for */ + + if (outname == NULL) + outname = write_java ? "SvnRevision.java" : "uni_revision.h"; + if (!process_self && *outname != '\0') + remove(outname); + + /* phase 1: scan through all files and get the highest build number */ + + max_build = 0; + accum_build = 0; /* for RCS / CVS */ + max_year = max_month = max_day = 0; + ismodified = 0; + + if(input_file_name) { + input_file = fopen(input_file_name, "r"); + if (input_file != NULL) { + apr_dir_t *dir; + apr_finfo_t finfo; + apr_status_t rv; + apr_pool_t *pool; + char *file_path; + char dir_path[256]; /* line */ + int offset = 0; + if(path_prefix) + offset = sprintf(dir_path, "%s", path_prefix); + else + offset = sprintf(dir_path, "../../"); + + apr_initialize(); + apr_pool_create(&pool,NULL); + while (fgets(dir_path + offset, sizeof(dir_path) - offset, input_file) != NULL ) { /* read a line */ + size_t len = strlen(dir_path)-1; + if(dir_path[len] == '\n') + dir_path[len] = 0; + rv = apr_dir_open(&dir,dir_path,pool); + if(rv == APR_SUCCESS) { + while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { /* get next file */ + if(finfo.filetype != APR_REG) continue; + + apr_filepath_merge(&file_path,dir_path,finfo.name,0,pool); + + filemodified = 0; + if (strcasecmp(file_path, outname)!=0) + processfile(file_path, 0, &max_build, &accum_build, &max_year, &max_month, &max_day, &filemodified); + if (filemodified && verbose) + fprintf(stderr, "\tNotice: modified file '%s'\n", file_path); + ismodified = ismodified || filemodified; + } + apr_dir_close(dir); + } + else { + fprintf(stderr, "No such directory '%s'\n", dir_path); + } + } + fclose (input_file); + apr_pool_destroy(pool); + apr_terminate(); + } + else { + fprintf(stderr, "No such input file '%s'\n", input_file_name); + } + } + else { + for (index = 1; index < argc; index++) { + /* skip the options (already handled) */ + if (argv[index][0] == '-' +#if defined __WIN32__ || defined _Win32 || defined _WIN32 + || argv[index][0] == '/' +#endif + ) + continue; + + filemodified = 0; + if (strcasecmp(argv[index], outname)!=0) + processfile(argv[index], 0, &max_build, &accum_build, &max_year, &max_month, &max_day, &filemodified); + if (filemodified && verbose) + fprintf(stderr, "\tNotice: modified file '%s'\n", argv[index]); + ismodified = ismodified || filemodified; + } /* for */ + } + + /* also run over the existing header file, if any */ + if (process_self && *outname != '\0') + processfile(outname, 1, &max_build, &accum_build, &max_year, &max_month, &max_day, NULL/*&ismodified*/); + + if (accum_build > max_build) + max_build = accum_build; + modified_suffix[0] = ismodified ? 'M' : '\0'; + modified_suffix[1] = '\0'; + + /* phase 2: write a file with this highest build number */ + if (*outname == '\0') { + fp = stdout; + } else if ((fp = fopen(outname, "w")) == NULL) { + fprintf(stderr, "Failed to create output file '%s'\n", outname); + return 2; + } /* if */ + if (*outname != '\0') { + /* don't print the comments to stdout */ + fprintf(fp, "/* This file was generated by the \"svnrev\" utility\n" + " * (http://www.compuphase.com/svnrev.htm).\n" + " * You should not modify it manually, as it may be re-generated.\n" + " *\n" + " * $Revision: %d%s$\n" + " * $Date: %04d-%02d-%02d$\n" + " */\n\n", max_build, modified_suffix, max_year, max_month, max_day); + } /* if */ + + fprintf(fp, "#ifndef UNI_REVISION_H\n"); + fprintf(fp, "#define UNI_REVISION_H\n\n"); + fprintf(fp, "#define UNI_REVISION\t\t%d\n", max_build); + fprintf(fp, "#define UNI_REVISION_STRING\t\"%s%d%s%s\"\n", prefix, max_build, modified_suffix, suffix); + fprintf(fp, "#define UNI_REVISION_DATE\t\"%04d-%02d-%02d\"\n", max_year, max_month, max_day); + fprintf(fp, "#define UNI_REVISION_STAMP\t%04d%02d%02dL\n", max_year, max_month, max_day); + fprintf(fp, "#define UNI_REVISION_MODIFIED\t%d\n", ismodified); + fprintf(fp, "\n#endif /* UNI_REVISION_H */\n"); + + if (*outname != '\0') + fclose(fp); + + return 0; +} diff --git a/libs/unimrcp/build/svnrev/svnrev.input b/libs/unimrcp/build/svnrev/svnrev.input new file mode 100644 index 0000000000..1f73eb847e --- /dev/null +++ b/libs/unimrcp/build/svnrev/svnrev.input @@ -0,0 +1,32 @@ +build +libs/apr-toolkit/include +libs/apr-toolkit/src +libs/mpf/include +libs/mpf/src +libs/mrcp/control/include +libs/mrcp/control/src +libs/mrcp/include +libs/mrcp/message/include +libs/mrcp/message/src +libs/mrcp/resources/include +libs/mrcp/resources/src +libs/mrcp-client/include +libs/mrcp-client/src +libs/mrcp-server/include +libs/mrcp-server/src +libs/mrcp-engine/include +libs/mrcp-engine/src +libs/mrcp-signaling/include +libs/mrcp-signaling/src +libs/mrcpv2-transport/include +libs/mrcpv2-transport/src +libs/uni-rtsp/include +libs/uni-rtsp/src +modules/mrcp-sofiasip/include +modules/mrcp-sofiasip/src +modules/mrcp-unirtsp/include +modules/mrcp-unirtsp/src +platforms/libunimrcp-client/include +platforms/libunimrcp-client/src +platforms/libunimrcp-server/include +platforms/libunimrcp-server/src \ No newline at end of file diff --git a/libs/unimrcp/build/svnrev/svnrev.vcproj b/libs/unimrcp/build/svnrev/svnrev.vcproj new file mode 100644 index 0000000000..44259880b7 --- /dev/null +++ b/libs/unimrcp/build/svnrev/svnrev.vcproj @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/unimrcp/build/tools/prepare.2008.vcproj b/libs/unimrcp/build/tools/prepare.2008.vcproj deleted file mode 100644 index d19d002f7e..0000000000 --- a/libs/unimrcp/build/tools/prepare.2008.vcproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/build/tools/prepare.vcproj b/libs/unimrcp/build/tools/prepare.vcproj index 370cabb3f6..4fec72ee99 100644 --- a/libs/unimrcp/build/tools/prepare.vcproj +++ b/libs/unimrcp/build/tools/prepare.vcproj @@ -28,7 +28,7 @@ > - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/build/tools/unimrcp_service.c b/libs/unimrcp/build/tools/unimrcp_service.c index b8a1bd7a2d..c76459fa19 100644 --- a/libs/unimrcp/build/tools/unimrcp_service.c +++ b/libs/unimrcp/build/tools/unimrcp_service.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: unimrcp_service.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/build/tools/unimrcpservice.2008.vcproj b/libs/unimrcp/build/tools/unimrcpservice.2008.vcproj deleted file mode 100644 index 2ae65f7c05..0000000000 --- a/libs/unimrcp/build/tools/unimrcpservice.2008.vcproj +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/build/tools/unimrcpservice.vcproj b/libs/unimrcp/build/tools/unimrcpservice.vcproj index 0b3f899e18..1c0b13840f 100644 --- a/libs/unimrcp/build/tools/unimrcpservice.vcproj +++ b/libs/unimrcp/build/tools/unimrcpservice.vcproj @@ -51,7 +51,7 @@ /> - /** major version * Major API changes that could cause compatibility problems for older * programs such as structure size changes. No binary compatibility is * possible across a change in the major version. */ -#define UNI_MAJOR_VERSION 0 +#define UNI_MAJOR_VERSION 1 /** minor version * Minor API changes that do not cause binary compatibility problems. * Reset to 0 when upgrading UNI_MAJOR_VERSION */ -#define UNI_MINOR_VERSION 9 +#define UNI_MINOR_VERSION 0 /** patch level * The Patch Level never includes API changes, simply bug fixes. @@ -57,10 +57,40 @@ || ((major) == UNI_MAJOR_VERSION && (minor) < UNI_MINOR_VERSION) \ || ((major) == UNI_MAJOR_VERSION && (minor) == UNI_MINOR_VERSION && (patch) <= UNI_PATCH_VERSION)) + +/** Properly quote a value as a string in the C preprocessor */ +#define UNI_STRINGIFY(n) UNI_STRINGIFY_HELPER(n) +/** Helper macro for UNI_STRINGIFY */ +#define UNI_STRINGIFY_HELPER(n) #n + /** The formatted string of UniMRCP's version */ #define UNI_VERSION_STRING \ - APR_STRINGIFY(UNI_MAJOR_VERSION) "." \ - APR_STRINGIFY(UNI_MINOR_VERSION) "." \ - APR_STRINGIFY(UNI_PATCH_VERSION) + UNI_STRINGIFY(UNI_MAJOR_VERSION) "." \ + UNI_STRINGIFY(UNI_MINOR_VERSION) "." \ + UNI_STRINGIFY(UNI_PATCH_VERSION) + +/** An alternative formatted string of UniMRCP's version + macro for Win32 .rc files using numeric csv representation */ +#define UNI_VERSION_STRING_CSV UNI_MAJOR_VERSION ##, \ + ##UNI_MINOR_VERSION ##, \ + ##UNI_PATCH_VERSION + +/** The Copyright */ +#define UNI_COPYRIGHT "Copyright 2008-2010 Arsen Chaloyan" + +/** The License */ +#define UNI_LICENSE \ + "Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0" \ + "" \ + "Unless required by applicable law or agreed to in writing, software" \ + "distributed under the License is distributed on an ""AS IS"" BASIS," \ + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." \ + "See the License for the specific language governing permissions and" \ + "limitations under the License." + -#endif /* __UNI_VERSION_H__ */ +#endif /* UNI_VERSION_H */ diff --git a/libs/unimrcp/build/vsprops/apr.props b/libs/unimrcp/build/vsprops/apr.props deleted file mode 100644 index 660a970181..0000000000 --- a/libs/unimrcp/build/vsprops/apr.props +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - $(LibRootDir)libs\apr - $(LibRootDir)libs\apr-util - $(LibRootDir)libs\apr-iconv - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(AprDir)\include;$(AprUtilDir)\include;%(AdditionalIncludeDirectories) - - - - - $(AprDir) - - - $(AprUtilDir) - - - $(AprIconvDir) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/apt.props b/libs/unimrcp/build/vsprops/apt.props deleted file mode 100644 index 8ede1684dc..0000000000 --- a/libs/unimrcp/build/vsprops/apt.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ProjectRootDir)libs\apr-toolkit\include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;%(PreprocessorDefinitions) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/cepstral.vsprops b/libs/unimrcp/build/vsprops/cepstral.vsprops deleted file mode 100644 index 8df44eba0f..0000000000 --- a/libs/unimrcp/build/vsprops/cepstral.vsprops +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/libs/unimrcp/build/vsprops/mpf.props b/libs/unimrcp/build/vsprops/mpf.props deleted file mode 100644 index ff68ceaef2..0000000000 --- a/libs/unimrcp/build/vsprops/mpf.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ProjectRootDir)libs\mpf\include;%(AdditionalIncludeDirectories) - MPF_STATIC_LIB;%(PreprocessorDefinitions) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/mrcp.props b/libs/unimrcp/build/vsprops/mrcp.props deleted file mode 100644 index fa4ee3539b..0000000000 --- a/libs/unimrcp/build/vsprops/mrcp.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ProjectRootDir)libs\mrcp\include;$(ProjectRootDir)libs\mrcp\message\include;$(ProjectRootDir)libs\mrcp\control\include;$(ProjectRootDir)libs\mrcp\resources\include;%(AdditionalIncludeDirectories) - MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/mrcpclient.props b/libs/unimrcp/build/vsprops/mrcpclient.props deleted file mode 100644 index b650e07d91..0000000000 --- a/libs/unimrcp/build/vsprops/mrcpclient.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ProjectRootDir)libs\mrcp-client\include;%(AdditionalIncludeDirectories) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/mrcpsignaling.props b/libs/unimrcp/build/vsprops/mrcpsignaling.props deleted file mode 100644 index 5e0c884a9f..0000000000 --- a/libs/unimrcp/build/vsprops/mrcpsignaling.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ProjectRootDir)libs\mrcp-signaling\include;%(AdditionalIncludeDirectories) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/mrcpv2transport.props b/libs/unimrcp/build/vsprops/mrcpv2transport.props deleted file mode 100644 index c71836559b..0000000000 --- a/libs/unimrcp/build/vsprops/mrcpv2transport.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ProjectRootDir)libs\mrcpv2-transport\include;%(AdditionalIncludeDirectories) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/sofiasip.props b/libs/unimrcp/build/vsprops/sofiasip.props deleted file mode 100644 index 3714d30977..0000000000 --- a/libs/unimrcp/build/vsprops/sofiasip.props +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - $(LibRootDir)libs\sofia-sip - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(SofiaDir)\win32;$(SofiaDir)\libsofia-sip-ua\su;$(SofiaDir)\libsofia-sip-ua\nua;$(SofiaDir)\libsofia-sip-ua\url;$(SofiaDir)\libsofia-sip-ua\sip;$(SofiaDir)\libsofia-sip-ua\msg;$(SofiaDir)\libsofia-sip-ua\sdp;$(SofiaDir)\libsofia-sip-ua\nta;$(SofiaDir)\libsofia-sip-ua\nea;$(SofiaDir)\libsofia-sip-ua\soa;$(SofiaDir)\libsofia-sip-ua\iptsec;$(SofiaDir)\libsofia-sip-ua\bnf;$(SofiaDir)\libsofia-sip-ua\features;%(AdditionalIncludeDirectories) - - - - - $(SofiaDir) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/unibase.props b/libs/unimrcp/build/vsprops/unibase.props deleted file mode 100644 index 097e8596ab..0000000000 --- a/libs/unimrcp/build/vsprops/unibase.props +++ /dev/null @@ -1,26 +0,0 @@ - - - - $(ProjectDir)..\..\ - $(SolutionDir) - - - <_ProjectFileVersion>10.0.30319.1 - - - - WIN32;%(PreprocessorDefinitions) - Level4 - true - 4100;%(DisableSpecificWarnings) - - - - - $(ProjectRootDir) - - - $(LibRootDir) - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/unidebug.props b/libs/unimrcp/build/vsprops/unidebug.props deleted file mode 100644 index e9778995ab..0000000000 --- a/libs/unimrcp/build/vsprops/unidebug.props +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - ProgramDatabase - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/unimrcpclient.vsprops b/libs/unimrcp/build/vsprops/unimrcpclient.vsprops index 613b2ff02f..8f1edceebd 100644 --- a/libs/unimrcp/build/vsprops/unimrcpclient.vsprops +++ b/libs/unimrcp/build/vsprops/unimrcpclient.vsprops @@ -11,6 +11,6 @@ /> diff --git a/libs/unimrcp/build/vsprops/unimrcpplugin.vsprops b/libs/unimrcp/build/vsprops/unimrcpplugin.vsprops deleted file mode 100644 index 53c6857dfd..0000000000 --- a/libs/unimrcp/build/vsprops/unimrcpplugin.vsprops +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/libs/unimrcp/build/vsprops/unimrcpserver.vsprops b/libs/unimrcp/build/vsprops/unimrcpserver.vsprops index 0a44b670dd..8f812676ea 100644 --- a/libs/unimrcp/build/vsprops/unimrcpserver.vsprops +++ b/libs/unimrcp/build/vsprops/unimrcpserver.vsprops @@ -11,6 +11,6 @@ /> diff --git a/libs/unimrcp/build/vsprops/unirelease.props b/libs/unimrcp/build/vsprops/unirelease.props deleted file mode 100644 index 8081506815..0000000000 --- a/libs/unimrcp/build/vsprops/unirelease.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - - - ProgramDatabase - - - \ No newline at end of file diff --git a/libs/unimrcp/build/vsprops/unirtsp.props b/libs/unimrcp/build/vsprops/unirtsp.props deleted file mode 100644 index 7ed01cb9a8..0000000000 --- a/libs/unimrcp/build/vsprops/unirtsp.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ProjectRootDir)libs\uni-rtsp\include;%(AdditionalIncludeDirectories) - RTSP_STATIC_LIB;%(PreprocessorDefinitions) - - - \ No newline at end of file diff --git a/libs/unimrcp/conf/Makefile.am b/libs/unimrcp/conf/Makefile.am index 9241bbe561..d317e66ecb 100644 --- a/libs/unimrcp/conf/Makefile.am +++ b/libs/unimrcp/conf/Makefile.am @@ -2,10 +2,17 @@ MAINTAINERCLEANFILES = Makefile.in def-conf: test -d $(confdir) || $(mkinstalldirs) $(confdir) - for conffile in `find ./ -name \*.xml` ; do \ + for conffile in `find ./ -maxdepth 1 -name \*.xml -o -name \*.xsd` ; do \ filename=`echo $$conffile | sed -e 's|^.*/||'`; \ $(INSTALL) -m 644 $$filename $(confdir); \ done + test -d $(confdir)/client-profiles || $(mkinstalldirs) $(confdir)/client-profiles + for conffile in `find ./client-profiles/ -maxdepth 1 -name \*.xml -o -name \*.xsd` ; do \ + filename=`echo $$conffile | sed -e 's|^.*/||'`; \ + $(INSTALL) -m 644 client-profiles/$$filename $(confdir)/client-profiles; \ + done + + install-data-local: test -d $(confdir) || $(MAKE) def-conf diff --git a/libs/unimrcp/conf/client-profiles/lumenvox.xml b/libs/unimrcp/conf/client-profiles/lumenvox.xml new file mode 100644 index 0000000000..4b592a5450 --- /dev/null +++ b/libs/unimrcp/conf/client-profiles/lumenvox.xml @@ -0,0 +1,50 @@ + + + + + + + + + 5060 + + + + + + + + 554 + + + + + + + + + + + + SIP-Agent-1 + MRCPv2-Agent-1 + Media-Engine-1 + RTP-Factory-1 + LumenVox-SIP-Settings + RTP-Settings-1 + + + + + RTSP-Agent-1 + Media-Engine-1 + RTP-Factory-1 + LumenVox-RTSP-Settings + RTP-Settings-1 + + + + + diff --git a/libs/unimrcp/conf/client-profiles/nuance.xml b/libs/unimrcp/conf/client-profiles/nuance.xml new file mode 100644 index 0000000000..083f0cf8c4 --- /dev/null +++ b/libs/unimrcp/conf/client-profiles/nuance.xml @@ -0,0 +1,76 @@ + + + + + + + + + 5060 + + + + + + + + + 4900 + + media + + + + + + + + + + 50 + 200 + + 20 + PCMU PCMA L16/96/8000 telephone-event/101/8000 + + + + 2 + + 5000 + + 1000 + + + + + + + + + SIP-Agent-1 + MRCPv2-Agent-1 + Media-Engine-1 + RTP-Factory-1 + Nuance-SIP-Settings + Nuance-RTP-Settings + + + + + RTSP-Agent-1 + Media-Engine-1 + RTP-Factory-1 + Nuance-RTSP-Settings + Nuance-RTP-Settings + + + + + diff --git a/libs/unimrcp/conf/client-profiles/speechpro.xml b/libs/unimrcp/conf/client-profiles/speechpro.xml new file mode 100644 index 0000000000..9f765bef61 --- /dev/null +++ b/libs/unimrcp/conf/client-profiles/speechpro.xml @@ -0,0 +1,33 @@ + + + + + + + + + 8000 + + + + + + + + + + + + + RTSP-Agent-1 + Media-Engine-1 + RTP-Factory-1 + SpeechPro-RTSP-Settings + RTP-Settings-1 + + + + + diff --git a/libs/unimrcp/conf/client-profiles/unimrcp.xml b/libs/unimrcp/conf/client-profiles/unimrcp.xml new file mode 100644 index 0000000000..e29d8784fd --- /dev/null +++ b/libs/unimrcp/conf/client-profiles/unimrcp.xml @@ -0,0 +1,51 @@ + + + + + + + + + 8060 + + + + + + + + 1554 + + media + + + + + + + + + + + SIP-Agent-1 + MRCPv2-Agent-1 + Media-Engine-1 + RTP-Factory-1 + UniMRCP-SIP-Settings + RTP-Settings-1 + + + + + RTSP-Agent-1 + Media-Engine-1 + RTP-Factory-1 + UniMRCP-RTSP-Settings + RTP-Settings-1 + + + + + diff --git a/libs/unimrcp/conf/logger.xml b/libs/unimrcp/conf/logger.xml new file mode 100644 index 0000000000..73ae9b5cac --- /dev/null +++ b/libs/unimrcp/conf/logger.xml @@ -0,0 +1,38 @@ + + + + + INFO + + + CONSOLE + + + DATE,TIME,PRIORITY + + + NONE + diff --git a/libs/unimrcp/conf/umcscenarios.xml b/libs/unimrcp/conf/umcscenarios.xml index a9f1ce67cb..d5c713e201 100644 --- a/libs/unimrcp/conf/umcscenarios.xml +++ b/libs/unimrcp/conf/umcscenarios.xml @@ -1,3 +1,4 @@ + - + @@ -33,7 +35,7 @@ For instance, --> - + @@ -55,7 +57,7 @@ For instance, --> - + @@ -72,7 +74,7 @@ For instance, --> - + --> @@ -89,8 +91,24 @@ For instance, --> - + + + + + + + + + + + + + - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - + + + + + + 8062 + udp + UniMRCP SofiaSIP + UniMRCPClient + + + + + - - - + + 100 + + UniMRCPClient + + + + + 100 + false + 1024 + 1024 + + + + + + 1 + + + + + + + + 4000 + 5000 + + + + + + + + 50 + 200 + + 20 + PCMU PCMA L16/96/8000 telephone-event/101/8000 + + + + - + 1 - + 5000 - - - - - - - - - - - - - - - - - - - - - - - + 1000 + + + diff --git a/libs/unimrcp/conf/unimrcpclient.xsd b/libs/unimrcp/conf/unimrcpclient.xsd new file mode 100644 index 0000000000..349cae4252 --- /dev/null +++ b/libs/unimrcp/conf/unimrcpclient.xsd @@ -0,0 +1,266 @@ + + + + + UniMRCP client document + + + + + + Generic properties + + + + + + + + + + + + + + + + + + + + + + + + Common components + + + + + + Factory of MRCP resources + + + + + + + + + + + + + + + SIP signaling agent + + + + + + + + + + + + + + + + + + + + + + RTSP signaling agent + + + + + + + + + + + + + + + MRCPv2 connection agent + + + + + + + + + + + + + + + + Media processing engine + + + + + + + + + + + + Factory of RTP terminations + + + + + + + + + + + + + + + + + + Settings + + + + + + SIP settings + + + + + + + + + + + + + + + RTSP settings + + + + + + + + + + + + + + + + + + + + + + + + + + + RTP settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Profiles + + + + + + MRCPv2 profile + + + + + + + + + + + + + + + + + MRCPv1 profile + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libs/unimrcp/conf/unimrcpserver.xml b/libs/unimrcp/conf/unimrcpserver.xml index b48e58a6e8..29189a8d03 100644 --- a/libs/unimrcp/conf/unimrcpserver.xml +++ b/libs/unimrcp/conf/unimrcpserver.xml @@ -1,103 +1,157 @@ - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + 8060 + udp,tcp + + UniMRCP SofiaSIP + UniMRCPServer + + + + + + + + + + + + 1554 + + + + + + 100 + UniMRCPServer + + + + + + + 1544 + 100 + false + 1024 + 1024 + + + + + 1 + + + + + + + + 5000 + 6000 + - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - + + + - - - + + + 50 + 200 + + 20 + PCMU PCMA L16/96/8000 telephone-event/101/8000 + + + + - - - + 1 + + 5000 - - - - - - - - - - - - - + 1000 + + - + - - - - - - + + SIP-Agent-1 + MRCPv2-Agent-1 + Media-Engine-1 + RTP-Factory-1 + RTP-Settings-1 + + + + - - - - - + + RTSP-Agent-1 + Media-Engine-1 + RTP-Factory-1 + RTP-Settings-1 + diff --git a/libs/unimrcp/conf/unimrcpserver.xsd b/libs/unimrcp/conf/unimrcpserver.xsd new file mode 100644 index 0000000000..920e5072f8 --- /dev/null +++ b/libs/unimrcp/conf/unimrcpserver.xsd @@ -0,0 +1,266 @@ + + + + + UniMRCP server document + + + + + + Generic properties + + + + + + + + + + + + + + + + + + + Common components + + + + + + Factory of MRCP resources + + + + + + + + + + + + + + + SIP signaling agent + + + + + + + + + + + + + + + + + + + + + + + RTSP signaling agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MRCPv2 connection agent + + + + + + + + + + + + + + + + + Media processing engine + + + + + + + + + + + + Factory of RTP terminations + + + + + + + + + + + + + + + Factory of plugins (MRCP engines) + + + + + + + + + + + + + + + + + + + + + + + + + + + + Settings + + + + + + RTP settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Profiles + + + + + + MRCPv2 profile + + + + + + + + + + + + + + + + MRCPv1 profile + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/unimrcp/configure.ac b/libs/unimrcp/configure.ac index 1ba581189b..f0fa56f737 100644 --- a/libs/unimrcp/configure.ac +++ b/libs/unimrcp/configure.ac @@ -3,14 +3,11 @@ AC_PREREQ(2.57) -AC_INIT([unimrcp],[0.9.0]) +AC_INIT([unimrcp],[1.0.0]) AC_CONFIG_AUX_DIR([build]) AC_CONFIG_MACRO_DIR([build/acmacros]) AC_PREFIX_DEFAULT(/usr/local/unimrcp) -CFLAGS="$CFLAGS $CONFIGURE_CFLAGS" -CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS" -LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS" plugindir='${prefix}/plugin' confdir='${prefix}/conf' @@ -120,6 +117,15 @@ AC_ARG_ENABLE(demorecog-plugin, AM_CONDITIONAL([DEMORECOG_PLUGIN],[test "${enable_demorecog_plugin}" = "yes"]) +#Enable demo verifier plugin +AC_ARG_ENABLE(demoverifier-plugin, + [AC_HELP_STRING([--disable-demoverifier-plugin ],[exclude demo verifier plugin from build])], + [enable_demoverifier_plugin="$enableval"], + [enable_demoverifier_plugin="yes"]) + +AM_CONDITIONAL([DEMOVERIFIER_PLUGIN],[test "${enable_demoverifier_plugin}" = "yes"]) + + #Enable recorder plugin AC_ARG_ENABLE(recorder-plugin, [AC_HELP_STRING([--disable-recorder-plugin ],[exclude recorder plugin from build])], @@ -129,20 +135,6 @@ AC_ARG_ENABLE(recorder-plugin, AM_CONDITIONAL([RECORDER_PLUGIN],[test "${enable_recorder_plugin}" = "yes"]) -#Enable Cepstral Swift plugin -AC_ARG_ENABLE(cepstral-plugin, - [AC_HELP_STRING([--disable-cepstral-plugin ],[exclude cepstral plugin from build])], - [enable_cepstral_plugin="$enableval"], - [enable_cepstral_plugin="yes"]) - -if test "${enable_cepstral_plugin}" != "no"; then - UNIMRCP_CHECK_SWIFT -fi - -AM_CONDITIONAL([CEPSTRAL_PLUGIN],[test "${enable_cepstral_plugin}" = "yes" &&\ - test "${found_swift}" = "yes"]) - - #Enable PocketSphinx plugin AC_ARG_ENABLE(pocketsphinx-plugin, [AC_HELP_STRING([--enable-pocketsphinx-plugin ],[enable pocketsphinx plugin])], @@ -191,12 +183,12 @@ AC_CONFIG_FILES([ modules/mrcp-sofiasip/Makefile modules/mrcp-unirtsp/Makefile plugins/Makefile - plugins/mrcp-cepstral/Makefile plugins/mrcp-pocketsphinx/Makefile plugins/mrcp-flite/Makefile plugins/mrcp-recorder/Makefile plugins/demo-synth/Makefile plugins/demo-recog/Makefile + plugins/demo-verifier/Makefile platforms/Makefile platforms/libunimrcp-server/Makefile platforms/libunimrcp-client/Makefile @@ -216,8 +208,10 @@ AC_CONFIG_FILES([ build/pkgconfig/unimrcpclient.pc build/pkgconfig/unimrcpserver.pc build/pkgconfig/unimrcpplugin.pc + build/svnrev/Makefile conf/Makefile data/Makefile + docs/doxygen.conf ]) AC_OUTPUT @@ -231,6 +225,7 @@ AC_MSG_NOTICE([ Sofia-SIP: $sofia_version]) AC_MSG_NOTICE([Plugins:]) AC_MSG_NOTICE([ Demo Synthesizer: $enable_demosynth_plugin]) AC_MSG_NOTICE([ Demo Recognizer: $enable_demorecog_plugin]) -AC_MSG_NOTICE([ Cepstral: $enable_cepstral_plugin]) +AC_MSG_NOTICE([ Demo Verifier: $enable_demoverifier_plugin]) +AC_MSG_NOTICE([ Recorder: $enable_recorder_plugin]) AC_MSG_NOTICE([ PocketSphinx: $enable_pocketsphinx_plugin]) AC_MSG_NOTICE([ Flite: $enable_flite_plugin]) diff --git a/libs/unimrcp/data/demo-16kHz.pcm b/libs/unimrcp/data/demo-16kHz.pcm index 01ace40952..5341461c25 100644 Binary files a/libs/unimrcp/data/demo-16kHz.pcm and b/libs/unimrcp/data/demo-16kHz.pcm differ diff --git a/libs/unimrcp/data/demo-8kHz.pcm b/libs/unimrcp/data/demo-8kHz.pcm index 7c5bf2720b..5121fdc483 100644 Binary files a/libs/unimrcp/data/demo-8kHz.pcm and b/libs/unimrcp/data/demo-8kHz.pcm differ diff --git a/libs/unimrcp/data/grammar.mixed b/libs/unimrcp/data/grammar.mixed new file mode 100644 index 0000000000..2f706e7632 --- /dev/null +++ b/libs/unimrcp/data/grammar.mixed @@ -0,0 +1,19 @@ + +--break +Content-Type:text/uri-list +Content-Length: 22 + +builtin:grammar/digits + +--break +Content-Type:application/srgs+xml +Content-Length: 230 + + + + + one two three four five + + +--break-- \ No newline at end of file diff --git a/libs/unimrcp/data/johnsmith-16kHz.pcm b/libs/unimrcp/data/johnsmith-16kHz.pcm new file mode 100644 index 0000000000..235338077d Binary files /dev/null and b/libs/unimrcp/data/johnsmith-16kHz.pcm differ diff --git a/libs/unimrcp/data/johnsmith-8kHz.pcm b/libs/unimrcp/data/johnsmith-8kHz.pcm new file mode 100644 index 0000000000..8332f40732 Binary files /dev/null and b/libs/unimrcp/data/johnsmith-8kHz.pcm differ diff --git a/libs/unimrcp/data/result-verification.xml b/libs/unimrcp/data/result-verification.xml new file mode 100644 index 0000000000..fa0c8ceef3 --- /dev/null +++ b/libs/unimrcp/data/result-verification.xml @@ -0,0 +1,21 @@ + + + + + + 500 + cellular-phone + male + accepted + 0.85 + + + 1500 + cellular-phone + male + accepted + 0.75 + + + + \ No newline at end of file diff --git a/libs/unimrcp/data/speak.txt b/libs/unimrcp/data/speak.txt index 3245b20dc9..894d43a75f 100644 --- a/libs/unimrcp/data/speak.txt +++ b/libs/unimrcp/data/speak.txt @@ -1 +1 @@ -Hello World. \ No newline at end of file +Welcome to Uni MRCP. \ No newline at end of file diff --git a/libs/unimrcp/data/speak.xml b/libs/unimrcp/data/speak.xml index e9a9ec3ebd..c64e8dfb31 100644 --- a/libs/unimrcp/data/speak.xml +++ b/libs/unimrcp/data/speak.xml @@ -1,6 +1,6 @@ - - - Hello World. - + +

+ Welcome to Uni MRCP. +

\ No newline at end of file diff --git a/libs/unimrcp/docs/doxygen.conf b/libs/unimrcp/docs/doxygen.conf.in similarity index 91% rename from libs/unimrcp/docs/doxygen.conf rename to libs/unimrcp/docs/doxygen.conf.in index 8b375cefd9..b405be48f0 100644 --- a/libs/unimrcp/docs/doxygen.conf +++ b/libs/unimrcp/docs/doxygen.conf.in @@ -1,6 +1,7 @@ PROJECT_NAME="UniMRCP" +PROJECT_NUMBER = @VERSION@ -INPUT=. +INPUT=. docs/mainpage.docs QUIET=YES RECURSIVE=YES FILE_PATTERNS=*.h diff --git a/libs/unimrcp/docs/mainpage.docs b/libs/unimrcp/docs/mainpage.docs new file mode 100644 index 0000000000..8961b43da3 --- /dev/null +++ b/libs/unimrcp/docs/mainpage.docs @@ -0,0 +1,92 @@ +/** +@mainpage UniMRCP + +
+@section Introduction + +UniMRCP is an open source cross-platform MRCP project, which provides everything required for MRCP client and server side deployment. +
+UniMRCP encapsulates SIP/MRCPv2, RTSP, SDP and RTP/RTCP stacks inside and provides MRCP version independent user level interface for the integration. +
+
+@section Source Tree Structure + +
+Libraries + +* apr-toolkit - set of utilities built on top of APR and APR-Util libraries (task abstraction, logging, etc) +
+* mpf - media processing framework +
+* mrcp - implementation of MRCP basics (message, parser, resources) +
+* mrcpv2-transport - implementation of MRCPv2 transport layer +
+* mrcp-signaling - abstract MRCP signaling (session management) interface +
+* mrcp-engine - abstract resource engine interface +
+* mrcp-client - implementation of MRCP client stack based on abstract signaling interface +
+* mrcp-server - implementation of MRCP server stack based on abstract signaling and engine interfaces +
+* uni-rtsp - implementation of minimal RTSP stack required for MRCPv1 + + +
+Modules + +* mrcp-sofiasip - implementation of abstract signaling interface using SofiaSIP library +
+* mrcp-unirtsp - implementation of abstract signaling interface using UniRTSP library +
+ + +
+Plugins + +* demo-synth - simulation of actual synthesizer engine +
+* demo-recog - simulation of actual recognizer engine +
+* mrcp-recorder - implementation of recorder resource +
+* mrcp-flite - implementation of synthesizer resource using open source Flite engine +
+* mrcp-pocketsphinx - implementation of recognizer resource using open source PocketSphinx engine + +
+Platforms + +* libunimrcpclient - unimrcp client stack based on libraries and modules above +
+* libunimrcpserver - unimrcp server stack based on libraries, modules and plugins above +
+* unimrcpclient - sample C application based on unimrcp client stack +
+* umc - sample C++ application based on unimrcp client stack +
+* unimrcpserver - final unimrcp server application + +
+@section Dependencies + + APR - Apache Portable Runtime +
+ Sofia-SIP - SIP User Agent Library + +
+@section Project Links + + Website +
+ Downloads +
+ Wiki +
+ Issue Tracker +
+ Discussion Group +
+ +*/ diff --git a/libs/unimrcp/libs/apr-toolkit/Makefile.am b/libs/unimrcp/libs/apr-toolkit/Makefile.am index e887e398c2..0647143824 100644 --- a/libs/unimrcp/libs/apr-toolkit/Makefile.am +++ b/libs/unimrcp/libs/apr-toolkit/Makefile.am @@ -8,38 +8,43 @@ noinst_LTLIBRARIES = libaprtoolkit.la include_HEADERS = include/apt.h \ include/apt_obj_list.h \ include/apt_cyclic_queue.h \ + include/apt_dir_layout.h \ include/apt_task.h \ include/apt_task_msg.h \ include/apt_consumer_task.h \ - include/apt_net_server_task.h \ - include/apt_net_client_task.h \ include/apt_pollset.h \ + include/apt_poller_task.h \ include/apt_pool.h \ include/apt_log.h \ include/apt_pair.h \ include/apt_string.h \ include/apt_string_table.h \ + include/apt_header_field.h \ include/apt_text_stream.h \ + include/apt_text_message.h \ include/apt_net.h \ include/apt_nlsml_doc.h \ - include/apt_dir_layout.h \ + include/apt_multipart_content.h \ + include/apt_timer_queue.h \ include/apt_test_suite.h libaprtoolkit_la_SOURCES = src/apt_obj_list.c \ src/apt_cyclic_queue.c \ + src/apt_dir_layout.c \ src/apt_task.c \ src/apt_task_msg.c \ src/apt_consumer_task.c \ - src/apt_net_server_task.c \ - src/apt_net_client_task.c \ src/apt_pollset.c \ + src/apt_poller_task.c \ src/apt_pool.c \ src/apt_log.c \ src/apt_pair.c \ src/apt_string_table.c \ + src/apt_header_field.c \ src/apt_text_stream.c \ + src/apt_text_message.c \ src/apt_net.c \ src/apt_nlsml_doc.c \ - src/apt_dir_layout.c \ + src/apt_multipart_content.c \ + src/apt_timer_queue.c \ src/apt_test_suite.c - diff --git a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj b/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj deleted file mode 100644 index d77441afa5..0000000000 --- a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj +++ /dev/null @@ -1,409 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2010.vcxproj b/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2010.vcxproj deleted file mode 100644 index 9288736c40..0000000000 --- a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2010.vcxproj +++ /dev/null @@ -1,157 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - aprtoolkit - {13DEECA0-BDD4-4744-A1A2-8EB0A44DF3D2} - aprtoolkit - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - APT_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;%(PreprocessorDefinitions) - ProgramDatabase - - - - - APT_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {f057da7f-79e5-4b00-845c-ef446ef055e3} - false - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2010.vcxproj.filters b/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2010.vcxproj.filters deleted file mode 100644 index db0b3156b3..0000000000 --- a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2010.vcxproj.filters +++ /dev/null @@ -1,125 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {4c2fadb2-8996-43e3-9db1-e3fc3eccee30} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.vcproj b/libs/unimrcp/libs/apr-toolkit/aprtoolkit.vcproj index 9ea77e93a6..bb2746e815 100644 --- a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.vcproj +++ b/libs/unimrcp/libs/apr-toolkit/aprtoolkit.vcproj @@ -254,19 +254,19 @@ > + + @@ -309,10 +313,18 @@ RelativePath=".\include\apt_test_suite.h" > + + + + + + @@ -382,10 +398,18 @@ RelativePath=".\src\apt_test_suite.c" > + + + + diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt.h b/libs/unimrcp/libs/apr-toolkit/include/apt.h index 2c0353161e..963b28b65a 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __APT_H__ -#define __APT_H__ +#ifndef APT_H +#define APT_H /** * @file apt.h @@ -56,4 +58,4 @@ /** Boolean value */ typedef int apt_bool_t; -#endif /*__APT_H__*/ +#endif /* APT_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_consumer_task.h b/libs/unimrcp/libs/apr-toolkit/include/apt_consumer_task.h index 59eff4015f..9085f0c3ba 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_consumer_task.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_consumer_task.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_consumer_task.h 1708 2010-05-24 17:03:25Z achaloyan $ */ -#ifndef __APT_CONSUMER_TASK_H__ -#define __APT_CONSUMER_TASK_H__ +#ifndef APT_CONSUMER_TASK_H +#define APT_CONSUMER_TASK_H /** * @file apt_consumer_task.h @@ -44,7 +46,7 @@ APT_DECLARE(apt_consumer_task_t*) apt_consumer_task_create( * Get task base. * @param task the consumer task to get base for */ -APT_DECLARE(apt_task_t*) apt_consumer_task_base_get(apt_consumer_task_t *task); +APT_DECLARE(apt_task_t*) apt_consumer_task_base_get(const apt_consumer_task_t *task); /** * Get task vtable. @@ -56,8 +58,8 @@ APT_DECLARE(apt_task_vtable_t*) apt_consumer_task_vtable_get(apt_consumer_task_t * Get consumer task object. * @param task the consumer task to get object from */ -APT_DECLARE(void*) apt_consumer_task_object_get(apt_consumer_task_t *task); +APT_DECLARE(void*) apt_consumer_task_object_get(const apt_consumer_task_t *task); APT_END_EXTERN_C -#endif /*__APT_CONSUMER_TASK_H__*/ +#endif /* APT_CONSUMER_TASK_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_cyclic_queue.h b/libs/unimrcp/libs/apr-toolkit/include/apt_cyclic_queue.h index 7c6ea3ab08..b0500855d6 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_cyclic_queue.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_cyclic_queue.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_cyclic_queue.h 1708 2010-05-24 17:03:25Z achaloyan $ */ -#ifndef __APT_CYCLIC_QUEUE_H__ -#define __APT_CYCLIC_QUEUE_H__ +#ifndef APT_CYCLIC_QUEUE_H +#define APT_CYCLIC_QUEUE_H /** * @file apt_cyclic_queue.h @@ -69,9 +71,9 @@ APT_DECLARE(void) apt_cyclic_queue_clear(apt_cyclic_queue_t *queue); * @param queue the queue to query * @return TRUE if empty, otherwise FALSE */ -APT_DECLARE(apt_bool_t) apt_cyclic_queue_is_empty(apt_cyclic_queue_t *queue); +APT_DECLARE(apt_bool_t) apt_cyclic_queue_is_empty(const apt_cyclic_queue_t *queue); APT_END_EXTERN_C -#endif /*__APT_CYCLIC_QUEUE_H__*/ +#endif /* APT_CYCLIC_QUEUE_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_dir_layout.h b/libs/unimrcp/libs/apr-toolkit/include/apt_dir_layout.h index 497265d381..6adda9fab8 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_dir_layout.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_dir_layout.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_dir_layout.h 1524 2010-02-15 20:44:16Z achaloyan $ */ -#ifndef __APT_DIR_LAYOUT_H__ -#define __APT_DIR_LAYOUT_H__ +#ifndef APT_DIR_LAYOUT_H +#define APT_DIR_LAYOUT_H /** * @file apt_dir_layout.h @@ -56,12 +58,13 @@ APT_DECLARE(apt_dir_layout_t*) apt_custom_dir_layout_create( const char *data_dir_path, apr_pool_t *pool); -/** - * Construct file path with the given file name relative to data dir. - */ +/** Construct file path relative to data dir using the file name specified. */ APT_DECLARE(char*) apt_datadir_filepath_get(const apt_dir_layout_t *dir_layout, const char *file_name, apr_pool_t *pool); +/** Construct file path relative to conf dir using the file name specified. */ +APT_DECLARE(char*) apt_confdir_filepath_get(const apt_dir_layout_t *dir_layout, const char *file_name, apr_pool_t *pool); + APT_END_EXTERN_C -#endif /*__APT_DIR_LAYOUT_H__*/ +#endif /* APT_DIR_LAYOUT_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_header_field.h b/libs/unimrcp/libs/apr-toolkit/include/apt_header_field.h new file mode 100644 index 0000000000..72932059dd --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_header_field.h @@ -0,0 +1,178 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_header_field.h 1719 2010-05-31 21:09:51Z achaloyan $ + */ + +#ifndef APT_HEADER_FIELD_H +#define APT_HEADER_FIELD_H + +/** + * @file apt_header_field.h + * @brief Header Field Declaration (RFC5322) + */ + +#ifdef WIN32 +#pragma warning(disable: 4127) +#endif +#include +#include "apt_string.h" + +APT_BEGIN_EXTERN_C + +/** Header field declaration */ +typedef struct apt_header_field_t apt_header_field_t; +/** Header section declaration */ +typedef struct apt_header_section_t apt_header_section_t; + +/** Header field */ +struct apt_header_field_t { + /** Ring entry */ + APR_RING_ENTRY(apt_header_field_t) link; + + /** Name of the header field */ + apt_str_t name; + /** Value of the header field */ + apt_str_t value; + + /** Numeric identifier associated with name */ + apr_size_t id; +}; + +/** + * Header section + * @remark The header section is a collection of header fields. + * The header fields are stored in both a ring and an array. + * The goal is to ensure efficient access and manipulation on the header fields. + */ +struct apt_header_section_t { + /** List of header fields (name-value pairs) */ + APR_RING_HEAD(apt_head_t, apt_header_field_t) ring; + /** Array of pointers to header fields */ + apt_header_field_t **arr; + /** Max number of header fields */ + apr_size_t arr_size; +}; + + +/** + * Allocate an empty header field. + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_header_field_t*) apt_header_field_alloc(apr_pool_t *pool); + +/** + * Create a header field using given name and value APT strings. + * @param name the name of the header field + * @param value the value of the header field + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_header_field_t*) apt_header_field_create(const apt_str_t *name, const apt_str_t *value, apr_pool_t *pool); + +/** + * Create a header field using given name and value C strings. + * @param name the name of the header field + * @param value the value of the header field + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_header_field_t*) apt_header_field_create_c(const char *name, const char *value, apr_pool_t *pool); + +/** + * Create a header field from entire text line consisting of a name and value pair. + * @param line the text line, which consists of a name and value pair + * @param separator the name and value separator + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_header_field_t*) apt_header_field_create_from_line(const apt_str_t *line, char separator, apr_pool_t *pool); + +/** + * Copy specified header field. + * @param src_header_field the header field to copy + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_header_field_t*) apt_header_field_copy(const apt_header_field_t *src_header_field, apr_pool_t *pool); + +/** + * Initialize header section (collection of header fields). + * @param header the header section to initialize + */ +APT_DECLARE(void) apt_header_section_init(apt_header_section_t *header); + +/** + * Allocate header section to set/get header fields by numeric identifiers. + * @param header the header section to allocate + * @param max_field_count the max number of header fields in the section (protocol dependent) + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_bool_t) apt_header_section_array_alloc(apt_header_section_t *header, apr_size_t max_field_count, apr_pool_t *pool); + +/** + * Add (append) header field to header section. + * @param header the header section to add field to + * @param header_field the header field to add + */ +APT_DECLARE(apt_bool_t) apt_header_section_field_add(apt_header_section_t *header, apt_header_field_t *header_field); + +/** + * Insert header field to header section based on numreic identifier if specified. + * @param header the header section to insert field into + * @param header_field the header field to insert + */ +APT_DECLARE(apt_bool_t) apt_header_section_field_insert(apt_header_section_t *header, apt_header_field_t *header_field); + +/** + * Set header field in the array of header fields using associated numeric identifier. + * @param header the header section to set field for + * @param header_field the header field to set + * @remark Typically, the header field should be already added to the header section using apt_header_section_field_add() + */ +APT_DECLARE(apt_bool_t) apt_header_section_field_set(apt_header_section_t *header, apt_header_field_t *header_field); + +/** + * Remove header field from header section. + * @param header the header section to remove field from + * @param header_field the header field to remove + */ +APT_DECLARE(apt_bool_t) apt_header_section_field_remove(apt_header_section_t *header, apt_header_field_t *header_field); + +/** + * Check whether specified header field is set. + * @param header the header section to use + * @param id the identifier associated with the header_field to check + */ +static APR_INLINE apt_bool_t apt_header_section_field_check(const apt_header_section_t *header, apr_size_t id) +{ + if(id < header->arr_size) { + return header->arr[id] ? TRUE : FALSE; + } + return FALSE; +} + +/** + * Get header field by specified identifier. + * @param header the header section to use + * @param id the identifier associated with the header_field + */ +static APR_INLINE apt_header_field_t* apt_header_section_field_get(const apt_header_section_t *header, apr_size_t id) +{ + if(id < header->arr_size) { + return header->arr[id]; + } + return NULL; +} + +APT_END_EXTERN_C + +#endif /* APT_HEADER_FIELD_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_log.h b/libs/unimrcp/libs/apr-toolkit/include/apt_log.h index ea2c561331..4d7c1bc5ed 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_log.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_log.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_log.h 1792 2011-01-10 21:08:52Z achaloyan $ */ -#ifndef __APT_LOG_H__ -#define __APT_LOG_H__ +#ifndef APT_LOG_H +#define APT_LOG_H /** * @file apt_log.h @@ -44,8 +46,10 @@ APT_BEGIN_EXTERN_C #define APT_SIDRES_FMT "<%s@%s>" /** Format to log pointers and identifiers */ #define APT_PTRSID_FMT APT_PTR_FMT" "APT_SID_FMT -/** Format to log pointers, identifiers and resources */ -#define APT_PTRSIDRES_FMT APT_PTR_FMT" "APT_SIDRES_FMT +/** Format to log pointers and identifiers */ +#define APT_NAMESID_FMT "%s "APT_SID_FMT +/** Format to log names, identifiers and resources */ +#define APT_NAMESIDRES_FMT "%s "APT_SIDRES_FMT /** Priority of log messages ordered from highest priority to lowest (rfc3164) */ @@ -69,22 +73,30 @@ typedef enum { APT_LOG_HEADER_TIME = 0x02, /**< enable time output */ APT_LOG_HEADER_PRIORITY = 0x04, /**< enable priority name output */ APT_LOG_HEADER_MARK = 0x08, /**< enable file:line mark output */ + APT_LOG_HEADER_THREAD = 0x10, /**< enable thread identifier output */ APT_LOG_HEADER_DEFAULT = APT_LOG_HEADER_DATE | APT_LOG_HEADER_TIME | APT_LOG_HEADER_PRIORITY } apt_log_header_e; -/** Log output modes */ +/** Mode of log output */ typedef enum { APT_LOG_OUTPUT_NONE = 0x00, /**< disable logging */ APT_LOG_OUTPUT_CONSOLE = 0x01, /**< enable console output */ APT_LOG_OUTPUT_FILE = 0x02 /**< enable log file output */ } apt_log_output_e; +/** Masking mode of private data */ +typedef enum { + APT_LOG_MASKING_NONE, /**< log everything as is */ + APT_LOG_MASKING_COMPLETE, /**< mask private data completely */ + APT_LOG_MASKING_ENCRYPTED /**< encrypt private data */ +} apt_log_masking_e; + /** Opaque logger declaration */ typedef struct apt_logger_t apt_logger_t; /** Prototype of extended log handler function */ -typedef apt_bool_t (*apt_log_ext_handler_f)(const char *file, int line, const char *id, +typedef apt_bool_t (*apt_log_ext_handler_f)(const char *file, int line, const char *obj, apt_log_priority_e priority, const char *format, va_list arg_ptr); /** @@ -95,6 +107,13 @@ typedef apt_bool_t (*apt_log_ext_handler_f)(const char *file, int line, const ch */ APT_DECLARE(apt_bool_t) apt_log_instance_create(apt_log_output_e mode, apt_log_priority_e priority, apr_pool_t *pool); +/** + * Create and load the singleton instance of the logger. + * @param config_file the path to configuration file to load settings from + * @param pool the memory pool to use + */ +APT_DECLARE(apt_bool_t) apt_log_instance_load(const char *config_file, apr_pool_t *pool); + /** * Destroy the singleton instance of the logger. */ @@ -116,13 +135,15 @@ APT_DECLARE(apt_bool_t) apt_log_instance_set(apt_logger_t *logger); * @param file_name the name of the log file * @param max_file_size the max size of the log file * @param max_file_count the max number of files used in log rotation + * @param append whether to append or to truncate (start over) the log file * @param pool the memory pool to use */ APT_DECLARE(apt_bool_t) apt_log_file_open( - const char *dir_path, - const char *file_name, - apr_size_t max_file_size, - apr_size_t max_file_count, + const char *dir_path, + const char *file_name, + apr_size_t max_file_size, + apr_size_t max_file_count, + apt_bool_t append, apr_pool_t *pool); /** @@ -131,23 +152,73 @@ APT_DECLARE(apt_bool_t) apt_log_file_open( APT_DECLARE(apt_bool_t) apt_log_file_close(void); /** - * Set the logging output. + * Set the logging output mode. * @param mode the mode to set */ APT_DECLARE(apt_bool_t) apt_log_output_mode_set(apt_log_output_e mode); +/** + * Check the logging output mode to be enabled (set) or not. + * @param mode the mode to check + */ +APT_DECLARE(apt_bool_t) apt_log_output_mode_check(apt_log_output_e mode); + +/** + * Translate the output mode string to bitmask of apt_log_output_e values. + * @param str the string to translate + */ +APT_DECLARE(int) apt_log_output_mode_translate(char *str); + /** * Set the logging priority (log level). * @param priority the priority to set */ APT_DECLARE(apt_bool_t) apt_log_priority_set(apt_log_priority_e priority); +/** + * Translate the priority (log level) string to enum. + * @param str the string to translate + */ +APT_DECLARE(apt_log_priority_e) apt_log_priority_translate(const char *str); + /** * Set the header (format) for log messages. * @param header the header to set (used as bitmask) */ APT_DECLARE(apt_bool_t) apt_log_header_set(int header); +/** + * Translate the header string to bitmask of apt_log_header_e values. + * @param str the string to translate + */ +APT_DECLARE(int) apt_log_header_translate(char *str); + +/** + * Set the masking mode of private data. + * @param masking the masking mode to set + */ +APT_DECLARE(apt_bool_t) apt_log_masking_set(apt_log_masking_e masking); + +/** + * Get the current masking mode of private data. + */ +APT_DECLARE(apt_log_masking_e) apt_log_masking_get(); + +/** + * Translate the masking mode string to enum. + * @param str the string to translate + */ +APT_DECLARE(apt_log_masking_e) apt_log_masking_translate(const char *str); + +/** + * Mask private data based on the masking mode + * @param data_in the data to mask + * @param length the length of the data to mask on input, the length of the masked data on output + * @param pool the memory pool to use if needed + * @return The masked data. + */ +APT_DECLARE(const char*) apt_log_data_mask(const char *data_in, apr_size_t *length, apr_pool_t *pool); + /** * Set the extended external log handler. * @param handler the handler to pass log events to @@ -165,6 +236,16 @@ APT_DECLARE(apt_bool_t) apt_log_ext_handler_set(apt_log_ext_handler_f handler); */ APT_DECLARE(apt_bool_t) apt_log(const char *file, int line, apt_log_priority_e priority, const char *format, ...); +/** + * Do logging. + * @param file the file name log entry is generated from + * @param line the line number log entry is generated from + * @param priority the priority of the entire log entry + * @param obj the associated object + * @param format the format of the entire log entry + */ +APT_DECLARE(apt_bool_t) apt_obj_log(const char *file, int line, apt_log_priority_e priority, void *obj, const char *format, ...); + APT_END_EXTERN_C -#endif /*__APT_LOG_H__*/ +#endif /* APT_LOG_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_multipart_content.h b/libs/unimrcp/libs/apr-toolkit/include/apt_multipart_content.h new file mode 100644 index 0000000000..c3f2dd8de2 --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_multipart_content.h @@ -0,0 +1,108 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_multipart_content.h 1722 2010-06-01 08:40:35Z achaloyan $ + */ + +#ifndef APT_MULTIPART_CONTENT_H +#define APT_MULTIPART_CONTENT_H + +/** + * @file apt_multipart_content.h + * @brief Multipart Content Routine + */ + +#include "apt_header_field.h" + +APT_BEGIN_EXTERN_C + +/** Opaque multipart content declaration */ +typedef struct apt_multipart_content_t apt_multipart_content_t; + +/** Content part declaration */ +typedef struct apt_content_part_t apt_content_part_t; + +/** Content part */ +struct apt_content_part_t { + /** Header section */ + apt_header_section_t header; + /** Body */ + apt_str_t body; + + /** Pointer to parsed content-type header field */ + apt_str_t *type; + /** Pointer to parsed content-id header field */ + apt_str_t *id; + /** Pointer to parsed content-length header field */ + apt_str_t *length; +}; + +/** + * Create an empty multipart content + * @param max_content_size the max size of the content (body) + * @param boundary the boundary to separate content parts + * @param pool the pool to allocate memory from + * @return an empty multipart content + */ +APT_DECLARE(apt_multipart_content_t*) apt_multipart_content_create(apr_size_t max_content_size, const apt_str_t *boundary, apr_pool_t *pool); + +/** + * Add content part to multipart content + * @param multipart_content the multipart content to add content part to + * @param content_part the content part to add + * @return TRUE on success + */ +APT_DECLARE(apt_bool_t) apt_multipart_content_add(apt_multipart_content_t *multipart_content, const apt_content_part_t *content_part); + +/** + * Add content part to multipart content by specified header fields and body + * @param multipart_content the multipart content to add content part to + * @param content_type the type of content part + * @param content_id the identifier of content part + * @param body the body of content part + * @return TRUE on success + */ +APT_DECLARE(apt_bool_t) apt_multipart_content_add2(apt_multipart_content_t *multipart_content, const apt_str_t *content_type, const apt_str_t *content_id, const apt_str_t *body); + +/** + * Finalize multipart content generation + * @param multipart_content the multipart content to finalize + * @return generated multipart content + */ +APT_DECLARE(apt_str_t*) apt_multipart_content_finalize(apt_multipart_content_t *multipart_content); + + +/** + * Assign body to multipart content to get (parse) each content part from + * @param body the body of multipart content to parse + * @param boundary the boundary to separate content parts + * @param pool the pool to allocate memory from + * @return multipart content with assigned body + */ +APT_DECLARE(apt_multipart_content_t*) apt_multipart_content_assign(const apt_str_t *body, const apt_str_t *boundary, apr_pool_t *pool); + +/** + * Get the next content part + * @param multipart_content the multipart content to get the next content part from + * @param content_part the parsed content part + * @param is_final indicates the final boundary is reached + * @return TRUE on success + */ +APT_DECLARE(apt_bool_t) apt_multipart_content_get(apt_multipart_content_t *multipart_content, apt_content_part_t *content_part, apt_bool_t *is_final); + + +APT_END_EXTERN_C + +#endif /* APT_MULTIPART_CONTENT_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_net.h b/libs/unimrcp/libs/apr-toolkit/include/apt_net.h index 7c9d109851..d413c7f871 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_net.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_net.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_net.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __APT_NET_H__ -#define __APT_NET_H__ +#ifndef APT_NET_H +#define APT_NET_H /** * @file apt_net.h @@ -43,4 +45,4 @@ void apt_ntp_time_get(apr_uint32_t *sec, apr_uint32_t *frac); APT_END_EXTERN_C -#endif /*__APT_NET_H__*/ +#endif /* APT_NET_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_net_client_task.h b/libs/unimrcp/libs/apr-toolkit/include/apt_net_client_task.h deleted file mode 100644 index 0cd9466f6a..0000000000 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_net_client_task.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2008 Arsen Chaloyan - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __APT_NET_CLIENT_TASK_H__ -#define __APT_NET_CLIENT_TASK_H__ - -/** - * @file apt_net_client_task.h - * @brief Network Client Task Base - */ - -#include -#include "apt_task.h" - -APT_BEGIN_EXTERN_C - -/** Opaque network client task declaration */ -typedef struct apt_net_client_task_t apt_net_client_task_t; -/** Network client connection declaration */ -typedef struct apt_net_client_connection_t apt_net_client_connection_t; -/** Virtual table of network client events */ -typedef struct apt_net_client_vtable_t apt_net_client_vtable_t; - -/** Network client connection */ -struct apt_net_client_connection_t { - /** Memory pool */ - apr_pool_t *pool; - /** External object */ - void *obj; - /** Connected socket */ - apr_socket_t *sock; - /** Socket poll descriptor */ - apr_pollfd_t sock_pfd; - /** String identifier used for traces */ - const char *id; -}; - -/** Virtual table of network client events */ -struct apt_net_client_vtable_t { - /** Message receive handler */ - apt_bool_t (*on_receive)(apt_net_client_task_t *task, apt_net_client_connection_t *connection); -}; - - -/** - * Create network client task. - * @param max_connection_count the number of max connections - * @param obj the external object - * @param client_vtable the table of virtual methods of the net client task - * @param msg_pool the pool of task messages - * @param pool the pool to allocate memory from - */ -APT_DECLARE(apt_net_client_task_t*) apt_net_client_task_create( - apr_size_t max_connection_count, - void *obj, - const apt_net_client_vtable_t *client_vtable, - apt_task_msg_pool_t *msg_pool, - apr_pool_t *pool); - -/** - * Destroy network client task. - * @param task the task to destroy - */ -APT_DECLARE(apt_bool_t) apt_net_client_task_destroy(apt_net_client_task_t *task); - -/** - * Start network client task and wait for incoming requests. - * @param task the task to start - */ -APT_DECLARE(apt_bool_t) apt_net_client_task_start(apt_net_client_task_t *task); - -/** - * Terminate connection task. - * @param task the task to terminate - */ -APT_DECLARE(apt_bool_t) apt_net_client_task_terminate(apt_net_client_task_t *task); - -/** - * Get task base. - * @param task the network client task to get task base from - */ -APT_DECLARE(apt_task_t*) apt_net_client_task_base_get(apt_net_client_task_t *task); - -/** - * Get task vtable. - * @param task the network client task to get vtable from - */ -APT_DECLARE(apt_task_vtable_t*) apt_net_client_task_vtable_get(apt_net_client_task_t *task); - -/** - * Get external object. - * @param task the task to get object from - */ -APT_DECLARE(void*) apt_net_client_task_object_get(apt_net_client_task_t *task); - -/** - * Create connection. - */ -APT_DECLARE(apt_net_client_connection_t*) apt_net_client_connect(apt_net_client_task_t *task, const char *ip, apr_port_t port); - -/** - * Close connection. - */ -APT_DECLARE(apt_bool_t) apt_net_client_connection_close(apt_net_client_task_t *task, apt_net_client_connection_t *connection); - -/** - * Close and destroy connection. - */ -APT_DECLARE(apt_bool_t) apt_net_client_disconnect(apt_net_client_task_t *task, apt_net_client_connection_t *connection); - - -APT_END_EXTERN_C - -#endif /*__APT_NET_CLIENT_TASK_H__*/ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_net_server_task.h b/libs/unimrcp/libs/apr-toolkit/include/apt_net_server_task.h deleted file mode 100644 index fa97836463..0000000000 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_net_server_task.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2008 Arsen Chaloyan - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __APT_NET_SERVER_TASK_H__ -#define __APT_NET_SERVER_TASK_H__ - -/** - * @file apt_net_server_task.h - * @brief Network Server Task Base - */ - -#include -#include "apt_task.h" - -APT_BEGIN_EXTERN_C - -/** Opaque network server task declaration */ -typedef struct apt_net_server_task_t apt_net_server_task_t; -/** Network server connection declaration */ -typedef struct apt_net_server_connection_t apt_net_server_connection_t; -/** Virtual table of network server events */ -typedef struct apt_net_server_vtable_t apt_net_server_vtable_t; - -/** Network server connection */ -struct apt_net_server_connection_t { - /** Memory pool */ - apr_pool_t *pool; - /** External object */ - void *obj; - /** Client IP address */ - char *client_ip; - /** Accepted socket */ - apr_socket_t *sock; - /** Socket poll descriptor */ - apr_pollfd_t sock_pfd; - /** String identifier used for traces */ - const char *id; -}; - -/** Virtual table of network server events */ -struct apt_net_server_vtable_t { - /** Connect event handler */ - apt_bool_t (*on_connect)(apt_net_server_task_t *task, apt_net_server_connection_t *connection); - /** Disconnect event handler */ - apt_bool_t (*on_disconnect)(apt_net_server_task_t *task, apt_net_server_connection_t *connection); - /** Message receive handler */ - apt_bool_t (*on_receive)(apt_net_server_task_t *task, apt_net_server_connection_t *connection); -}; - - -/** - * Create network server task. - * @param listen_ip the listen IP address - * @param listen_port the listen port - * @param max_connection_count the number of max connections to accept - * @param obj the external object - * @param server_vtable the table of virtual methods of the net server task - * @param msg_pool the pool of task messages - * @param pool the pool to allocate memory from - */ -APT_DECLARE(apt_net_server_task_t*) apt_net_server_task_create( - const char *listen_ip, - apr_port_t listen_port, - apr_size_t max_connection_count, - void *obj, - const apt_net_server_vtable_t *server_vtable, - apt_task_msg_pool_t *msg_pool, - apr_pool_t *pool); - -/** - * Destroy network server task. - * @param task the task to destroy - */ -APT_DECLARE(apt_bool_t) apt_net_server_task_destroy(apt_net_server_task_t *task); - -/** - * Start network server task and wait for incoming requests. - * @param task the task to start - */ -APT_DECLARE(apt_bool_t) apt_net_server_task_start(apt_net_server_task_t *task); - -/** - * Terminate connection task. - * @param task the task to terminate - */ -APT_DECLARE(apt_bool_t) apt_net_server_task_terminate(apt_net_server_task_t *task); - -/** - * Get task base. - * @param task the network server task to get task base from - */ -APT_DECLARE(apt_task_t*) apt_net_server_task_base_get(apt_net_server_task_t *task); - -/** - * Get task vtable. - * @param task the network server task to get vtable from - */ -APT_DECLARE(apt_task_vtable_t*) apt_net_server_task_vtable_get(apt_net_server_task_t *task); - -/** - * Get external object. - * @param task the task to get object from - */ -APT_DECLARE(void*) apt_net_server_task_object_get(apt_net_server_task_t *task); - -/** - * Close connection. - */ -APT_DECLARE(apt_bool_t) apt_net_server_connection_close(apt_net_server_task_t *task, apt_net_server_connection_t *connection); - -/** - * Destroy connection. - */ -APT_DECLARE(void) apt_net_server_connection_destroy(apt_net_server_connection_t *connection); - - -APT_END_EXTERN_C - -#endif /*__APT_NET_SERVER_TASK_H__*/ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_nlsml_doc.h b/libs/unimrcp/libs/apr-toolkit/include/apt_nlsml_doc.h index ab8724598f..ca29a07ad8 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_nlsml_doc.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_nlsml_doc.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_nlsml_doc.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __APT_NLSML_DOC_H__ -#define __APT_NLSML_DOC_H__ +#ifndef APT_NLSML_DOC_H +#define APT_NLSML_DOC_H /** * @file apt_nlsml_doc.h @@ -45,4 +47,4 @@ APT_DECLARE(const char *) nlsml_input_attrib_get(const apr_xml_elem *input, cons APT_END_EXTERN_C -#endif /*__APT_NLSML_DOC_H__*/ +#endif /* APT_NLSML_DOC_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_obj_list.h b/libs/unimrcp/libs/apr-toolkit/include/apt_obj_list.h index ed3359567d..3d17a81595 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_obj_list.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_obj_list.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_obj_list.h 1708 2010-05-24 17:03:25Z achaloyan $ */ -#ifndef __APT_OBJ_LIST_H__ -#define __APT_OBJ_LIST_H__ +#ifndef APT_OBJ_LIST_H +#define APT_OBJ_LIST_H /** * @file apt_obj_list.h @@ -65,40 +67,40 @@ APT_DECLARE(void*) apt_list_pop_front(apt_obj_list_t *list); * Retrieve object of the first element in the list. * @param list the list to retrieve from */ -APT_DECLARE(void*) apt_list_head(apt_obj_list_t *list); +APT_DECLARE(void*) apt_list_head(const apt_obj_list_t *list); /** * Retrieve object of the last element in the list. * @param list the list to retrieve from */ -APT_DECLARE(void*) apt_obj_list_tail(apt_obj_list_t *list); +APT_DECLARE(void*) apt_obj_list_tail(const apt_obj_list_t *list); /** * Retrieve the first element of the list. * @param list the list to retrieve from */ -APT_DECLARE(apt_list_elem_t*) apt_list_first_elem_get(apt_obj_list_t *list); +APT_DECLARE(apt_list_elem_t*) apt_list_first_elem_get(const apt_obj_list_t *list); /** * Retrieve the last element of the list. * @param list the list to retrieve from */ -APT_DECLARE(apt_list_elem_t*) apt_list_last_elem_get(apt_obj_list_t *list); +APT_DECLARE(apt_list_elem_t*) apt_list_last_elem_get(const apt_obj_list_t *list); /** * Retrieve the next element of the list. * @param list the list to retrieve from * @param elem the element to retrieve next element from */ -APT_DECLARE(apt_list_elem_t*) apt_list_next_elem_get(apt_obj_list_t *list, apt_list_elem_t *elem); +APT_DECLARE(apt_list_elem_t*) apt_list_next_elem_get(const apt_obj_list_t *list, apt_list_elem_t *elem); /** * Retrieve the prev element of the list. * @param list the list to retrieve from * @param elem the element to retrieve prev element from */ -APT_DECLARE(apt_list_elem_t*) apt_list_prev_elem_get(apt_obj_list_t *list, apt_list_elem_t *elem); +APT_DECLARE(apt_list_elem_t*) apt_list_prev_elem_get(const apt_obj_list_t *list, apt_list_elem_t *elem); /** * Insert element to the list. @@ -123,15 +125,15 @@ APT_DECLARE(apt_list_elem_t*) apt_list_elem_remove(apt_obj_list_t *list, apt_lis * @param list the list to query * @return TRUE if empty, otherwise FALSE */ -APT_DECLARE(apt_bool_t) apt_list_is_empty(apt_obj_list_t *list); +APT_DECLARE(apt_bool_t) apt_list_is_empty(const apt_obj_list_t *list); /** * Retrieve the object associated with element. * @param elem the element to retrieve object from */ -APT_DECLARE(void*) apt_list_elem_object_get(apt_list_elem_t *elem); +APT_DECLARE(void*) apt_list_elem_object_get(const apt_list_elem_t *elem); APT_END_EXTERN_C -#endif /*__APT_OBJ_LIST_H__*/ +#endif /* APT_OBJ_LIST_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_pair.h b/libs/unimrcp/libs/apr-toolkit/include/apt_pair.h index 36b74dfbaa..4f3d8c55d6 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_pair.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_pair.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_pair.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __APT_PAIR_H__ -#define __APT_PAIR_H__ +#ifndef APT_PAIR_H +#define APT_PAIR_H /** * @file apt_pair.h @@ -70,4 +72,4 @@ APT_DECLARE(const apt_pair_t*) apt_pair_array_get(const apt_pair_arr_t *arr, int APT_END_EXTERN_C -#endif /*__APT_PAIR_H__*/ +#endif /* APT_PAIR_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_poller_task.h b/libs/unimrcp/libs/apr-toolkit/include/apt_poller_task.h new file mode 100644 index 0000000000..e1a3c6a655 --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_poller_task.h @@ -0,0 +1,122 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_poller_task.h 1708 2010-05-24 17:03:25Z achaloyan $ + */ + +#ifndef APT_POLLER_TASK_H +#define APT_POLLER_TASK_H + +/** + * @file apt_poller_task.h + * @brief Poller Task + */ + +#include "apt_pollset.h" +#include "apt_task.h" +#include "apt_timer_queue.h" + +APT_BEGIN_EXTERN_C + +/** Opaque poller task declaration */ +typedef struct apt_poller_task_t apt_poller_task_t; + +/** Function prototype to handle signalled descripors */ +typedef apt_bool_t (*apt_poll_signal_f)(void *obj, const apr_pollfd_t *descriptor); + + +/** + * Create poller task. + * @param max_pollset_size the maximum number of descriptors pollset can hold + * @param signal_handler the handler of signalled descriptors + * @param obj the external object to pass to callback + * @param msg_pool the pool of task messages + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_poller_task_t*) apt_poller_task_create( + apr_size_t max_pollset_size, + apt_poll_signal_f signal_handler, + void *obj, + apt_task_msg_pool_t *msg_pool, + apr_pool_t *pool); + +/** + * Destroy poller task. + * @param task the task to destroy + */ +APT_DECLARE(apt_bool_t) apt_poller_task_destroy(apt_poller_task_t *task); + +/** + * Cleanup poller task. + * @param task the task to cleanup + * + * @remark This function should be considered in protected scope. + * It will be called on task destroy unless you override the behavior. + */ +APT_DECLARE(void) apt_poller_task_cleanup(apt_poller_task_t *task); + +/** + * Start poller task and wait for incoming messages. + * @param task the task to start + */ +APT_DECLARE(apt_bool_t) apt_poller_task_start(apt_poller_task_t *task); + +/** + * Terminate poller task. + * @param task the task to terminate + */ +APT_DECLARE(apt_bool_t) apt_poller_task_terminate(apt_poller_task_t *task); + +/** + * Get task base. + * @param task the poller task to get task base from + */ +APT_DECLARE(apt_task_t*) apt_poller_task_base_get(const apt_poller_task_t *task); + +/** + * Get task vtable. + * @param task the poller task to get vtable from + */ +APT_DECLARE(apt_task_vtable_t*) apt_poller_task_vtable_get(apt_poller_task_t *task); + +/** + * Get external object. + * @param task the poller task to get object from + */ +APT_DECLARE(void*) apt_poller_task_object_get(const apt_poller_task_t *task); + +/** + * Get pollset. + * @param task the poller task to get pollset from + */ +APT_DECLARE(apt_pollset_t*) apt_poller_task_pollset_get(const apt_poller_task_t *task); + +/** + * Create timer. + * @param task the poller task to create timer in the scope of + * @param proc the timer callback + * @param obj the object to pass to callback + * @param pool the pool to allocate memory from + */ +APT_DECLARE(apt_timer_t*) apt_poller_task_timer_create( + apt_poller_task_t *task, + apt_timer_proc_f proc, + void *obj, + apr_pool_t *pool); + + +APT_END_EXTERN_C + +#endif /* APT_POLLER_TASK_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_pollset.h b/libs/unimrcp/libs/apr-toolkit/include/apt_pollset.h index 05ba559bd3..3f7d56527b 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_pollset.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_pollset.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_pollset.h 1565 2010-03-06 07:13:04Z achaloyan $ */ -#ifndef __APT_POLLSET_H__ -#define __APT_POLLSET_H__ +#ifndef APT_POLLSET_H +#define APT_POLLSET_H /** * @file apt_pollset.h @@ -39,7 +41,7 @@ APT_BEGIN_EXTERN_C typedef struct apt_pollset_t apt_pollset_t; /** - * Create interruptable pollset on top of APR pollset + * Create interruptable pollset on top of APR pollset. * @param size the maximum number of descriptors pollset can hold * @param pool the pool to allocate memory from */ @@ -69,7 +71,7 @@ APT_DECLARE(apt_bool_t) apt_pollset_remove(apt_pollset_t *pollset, const apr_pol * Block for activity on the descriptor(s) in a pollset. * @param pollset the pollset to use * @param timeout the timeout in microseconds - * @param num nthe umber of signalled descriptors (output parameter) + * @param num the number of signalled descriptors (output parameter) * @param descriptors the array of signalled descriptors (output parameter) */ APT_DECLARE(apr_status_t) apt_pollset_poll( @@ -93,4 +95,4 @@ APT_DECLARE(apt_bool_t) apt_pollset_is_wakeup(apt_pollset_t *pollset, const apr_ APT_END_EXTERN_C -#endif /*__APT_POLLSET_H__*/ +#endif /* APT_POLLSET_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_pool.h b/libs/unimrcp/libs/apr-toolkit/include/apt_pool.h index b2bff52688..7f1aabaf2b 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_pool.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_pool.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_pool.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __APT_POOL_H__ -#define __APT_POOL_H__ +#ifndef APT_POOL_H +#define APT_POOL_H /** * @file apt_pool.h @@ -44,4 +46,4 @@ APT_DECLARE(apr_pool_t*) apt_subpool_create(apr_pool_t *parent); APT_END_EXTERN_C -#endif /*__APT_POOL_H__*/ +#endif /* APT_POOL_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_string.h b/libs/unimrcp/libs/apr-toolkit/include/apt_string.h index 31dd72c0b4..23be9655d4 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_string.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_string.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_string.h 1531 2010-02-20 14:19:53Z achaloyan $ */ -#ifndef __APT_STRING_H__ -#define __APT_STRING_H__ +#ifndef APT_STRING_H +#define APT_STRING_H /** * @file apt_string.h @@ -65,7 +67,7 @@ static APR_INLINE apr_size_t apt_string_length_get(const apt_str_t *str) /** Check whether string is empty. */ static APR_INLINE apr_size_t apt_string_is_empty(const apt_str_t *str) { - return str->length ? TRUE : FALSE; + return str->length ? FALSE : TRUE; } /** @@ -140,4 +142,4 @@ static APR_INLINE apt_bool_t apt_string_compare(const apt_str_t *str1, const apt APT_END_EXTERN_C -#endif /*__APT_STRING_H__*/ +#endif /* APT_STRING_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_string_table.h b/libs/unimrcp/libs/apr-toolkit/include/apt_string_table.h index 112bd6bffc..3ba927f44e 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_string_table.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_string_table.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_string_table.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __APT_STRING_TABLE_H__ -#define __APT_STRING_TABLE_H__ +#ifndef APT_STRING_TABLE_H +#define APT_STRING_TABLE_H /** * @file apt_string_table.h @@ -60,4 +62,4 @@ APT_DECLARE(apr_size_t) apt_string_table_id_find(const apt_str_table_item_t tabl APT_END_EXTERN_C -#endif /*__APT_STRING_TABLE_H__*/ +#endif /* APT_STRING_TABLE_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_task.h b/libs/unimrcp/libs/apr-toolkit/include/apt_task.h index 29c2dea399..031eff6af8 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_task.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_task.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_task.h 1696 2010-05-20 15:44:16Z achaloyan $ */ -#ifndef __APT_TASK_H__ -#define __APT_TASK_H__ +#ifndef APT_TASK_H +#define APT_TASK_H /** * @file apt_task.h @@ -124,19 +126,19 @@ APT_DECLARE(apt_bool_t) apt_task_msg_process(apt_task_t *task, apt_task_msg_t *m * Get parent (master) task. * @param task the task to get parent from */ -APT_DECLARE(apt_task_t*) apt_task_parent_get(apt_task_t *task); +APT_DECLARE(apt_task_t*) apt_task_parent_get(const apt_task_t *task); /** * Get memory pool associated with task. * @param task the task to get pool from */ -APT_DECLARE(apr_pool_t*) apt_task_pool_get(apt_task_t *task); +APT_DECLARE(apr_pool_t*) apt_task_pool_get(const apt_task_t *task); /** * Get external object associated with the task. * @param task the task to get object from */ -APT_DECLARE(void*) apt_task_object_get(apt_task_t *task); +APT_DECLARE(void*) apt_task_object_get(const apt_task_t *task); /** * Get task vtable. @@ -155,7 +157,7 @@ APT_DECLARE(void) apt_task_name_set(apt_task_t *task, const char *name); * Get task name. * @param task the task to get name from */ -APT_DECLARE(const char*) apt_task_name_get(apt_task_t *task); +APT_DECLARE(const char*) apt_task_name_get(const apt_task_t *task); /** * Enable/disable auto ready mode. @@ -170,6 +172,36 @@ APT_DECLARE(void) apt_task_auto_ready_set(apt_task_t *task, apt_bool_t auto_read */ APT_DECLARE(apt_bool_t) apt_task_ready(apt_task_t *task); +/** + * Get the running flag. + * @param task the task + */ +APT_DECLARE(apt_bool_t*) apt_task_running_flag_get(apt_task_t *task); + +/** + * Add start request. + * @param task the task + */ +APT_DECLARE(apt_bool_t) apt_task_start_request_add(apt_task_t *task); + +/** + * Remove start request. + * @param task the task + */ +APT_DECLARE(apt_bool_t) apt_task_start_request_remove(apt_task_t *task); + +/** + * Add termination request. + * @param task the task + */ +APT_DECLARE(apt_bool_t) apt_task_terminate_request_add(apt_task_t *task); + +/** + * Remove termination request. + * @param task the task + */ +APT_DECLARE(apt_bool_t) apt_task_terminate_request_remove(apt_task_t *task); + /** * Hold task execution. * @param msec the time to hold @@ -197,26 +229,16 @@ struct apt_task_vtable_t { apt_task_event_f on_pre_run; /** Virtual post-run event handler */ apt_task_event_f on_post_run; + /** Virtual start-request event handler */ + apt_task_event_f on_start_request; /** Virtual start-complete event handler */ apt_task_event_f on_start_complete; + /** Virtual terminate-request event handler */ + apt_task_event_f on_terminate_request; /** Virtual terminate-complete event handler */ apt_task_event_f on_terminate_complete; }; -static APR_INLINE void apt_task_vtable_reset(apt_task_vtable_t *vtable) -{ - vtable->destroy = NULL; - vtable->start = NULL; - vtable->terminate = NULL; - vtable->run = NULL; - vtable->signal_msg = NULL; - vtable->process_msg = NULL; - vtable->on_pre_run = NULL; - vtable->on_post_run = NULL; - vtable->on_start_complete = NULL; - vtable->on_terminate_complete = NULL; -} - APT_END_EXTERN_C -#endif /*__APT_TASK_H__*/ +#endif /* APT_TASK_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_task_msg.h b/libs/unimrcp/libs/apr-toolkit/include/apt_task_msg.h index 4d43ee5ca3..8680bf4491 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_task_msg.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_task_msg.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_task_msg.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __APT_TASK_MSG_H__ -#define __APT_TASK_MSG_H__ +#ifndef APT_TASK_MSG_H +#define APT_TASK_MSG_H /** * @file apt_task_msg.h @@ -77,4 +79,4 @@ APT_DECLARE(void) apt_task_msg_release(apt_task_msg_t *task_msg); APT_END_EXTERN_C -#endif /*__APT_TASK_MSG_H__*/ +#endif /* APT_TASK_MSG_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_test_suite.h b/libs/unimrcp/libs/apr-toolkit/include/apt_test_suite.h index 3e1b2cbeca..ce19f477c7 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_test_suite.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_test_suite.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_test_suite.h 1708 2010-05-24 17:03:25Z achaloyan $ */ -#ifndef __APT_TEST_SUITE_H__ -#define __APT_TEST_SUITE_H__ +#ifndef APT_TEST_SUITE_H +#define APT_TEST_SUITE_H /** * @file apt_test_suite.h @@ -92,8 +94,8 @@ APT_DECLARE(apt_bool_t) apt_test_framework_run(apt_test_framework_t *framework, * Retrieve the memory pool. * @param framework the test framework to retrieve memory pool from */ -APT_DECLARE(apr_pool_t*) apt_test_framework_pool_get(apt_test_framework_t *framework); +APT_DECLARE(apr_pool_t*) apt_test_framework_pool_get(const apt_test_framework_t *framework); APT_END_EXTERN_C -#endif /*__APT_TEST_SUITE_H__*/ +#endif /* APT_TEST_SUITE_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_text_message.h b/libs/unimrcp/libs/apr-toolkit/include/apt_text_message.h new file mode 100644 index 0000000000..40edf0af50 --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_text_message.h @@ -0,0 +1,125 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_text_message.h 1722 2010-06-01 08:40:35Z achaloyan $ + */ + +#ifndef APT_TEXT_MESSAGE_H +#define APT_TEXT_MESSAGE_H + +/** + * @file apt_text_message.h + * @brief Text Message Interface (RFC5322) + */ + +#include "apt_header_field.h" +#include "apt_text_stream.h" + +APT_BEGIN_EXTERN_C + +/** Status of text message processing (parsing/generation) */ +typedef enum { + APT_MESSAGE_STATUS_COMPLETE, + APT_MESSAGE_STATUS_INCOMPLETE, + APT_MESSAGE_STATUS_INVALID +} apt_message_status_e; + + +/** Opaque text message parser */ +typedef struct apt_message_parser_t apt_message_parser_t; +/** Vtable of text message parser */ +typedef struct apt_message_parser_vtable_t apt_message_parser_vtable_t; + +/** Opaque text message generator */ +typedef struct apt_message_generator_t apt_message_generator_t; +/** Vtable of text message generator */ +typedef struct apt_message_generator_vtable_t apt_message_generator_vtable_t; + +/** Temporary context associated with message and used for its parsing or generation */ +typedef struct apt_message_context_t apt_message_context_t; + +/** Create message parser */ +APT_DECLARE(apt_message_parser_t*) apt_message_parser_create(void *obj, const apt_message_parser_vtable_t *vtable, apr_pool_t *pool); + +/** Parse message by raising corresponding event handlers */ +APT_DECLARE(apt_message_status_e) apt_message_parser_run(apt_message_parser_t *parser, apt_text_stream_t *stream, void **message); + +/** Get external object associated with parser */ +APT_DECLARE(void*) apt_message_parser_object_get(apt_message_parser_t *parser); + +/** Set verbose mode for the parser */ +APT_DECLARE(void) apt_message_parser_verbose_set(apt_message_parser_t *parser, apt_bool_t verbose); + + +/** Create message generator */ +APT_DECLARE(apt_message_generator_t*) apt_message_generator_create(void *obj, const apt_message_generator_vtable_t *vtable, apr_pool_t *pool); + +/** Generate message */ +APT_DECLARE(apt_message_status_e) apt_message_generator_run(apt_message_generator_t *generator, void *message, apt_text_stream_t *stream); + +/** Get external object associated with generator */ +APT_DECLARE(void*) apt_message_generator_object_get(apt_message_generator_t *generator); + +/** Set verbose mode for the parser */ +APT_DECLARE(void) apt_message_generator_verbose_set(apt_message_generator_t *generator, apt_bool_t verbose); + + +/** Parse individual header field (name-value pair) */ +APT_DECLARE(apt_header_field_t*) apt_header_field_parse(apt_text_stream_t *stream, apr_pool_t *pool); + +/** Generate individual header field (name-value pair) */ +APT_DECLARE(apt_bool_t) apt_header_field_generate(const apt_header_field_t *header_field, apt_text_stream_t *stream); + +/** Parse header section */ +APT_DECLARE(apt_bool_t) apt_header_section_parse(apt_header_section_t *header, apt_text_stream_t *stream, apr_pool_t *pool); + +/** Generate header section */ +APT_DECLARE(apt_bool_t) apt_header_section_generate(const apt_header_section_t *header, apt_text_stream_t *stream); + + +/** Temporary context associated with message and used for its parsing or generation */ +struct apt_message_context_t { + /** Context or ptotocol specific message */ + void *message; + /** Header section of the message */ + apt_header_section_t *header; + /** Body or content of the message */ + apt_str_t *body; +}; + +/** Vtable of text message parser */ +struct apt_message_parser_vtable_t { + /** Start new message parsing by associating corresponding context and reading its start-line if applicable */ + apt_bool_t (*on_start)(apt_message_parser_t *parser, apt_message_context_t *context, apt_text_stream_t *stream, apr_pool_t *pool); + /** Header section handler is invoked when entire header section has been read and parsed into header fields */ + apt_bool_t (*on_header_complete)(apt_message_parser_t *parser, apt_message_context_t *context); + /** Body handler is invoked when entire body has been read */ + apt_bool_t (*on_body_complete)(apt_message_parser_t *parser, apt_message_context_t *context); +}; + +/** Vtable of text message generator */ +struct apt_message_generator_vtable_t { + /** Start message generation by associating corresponding context and generating message start-line if applicable */ + apt_bool_t (*on_start)(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream); + /** Header section handler is invoked to notify header section has been generated */ + apt_bool_t (*on_header_complete)(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream); + /** Body handler is invoked to notify body has been generated */ + apt_bool_t (*on_body_complete)(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream); +}; + + +APT_END_EXTERN_C + +#endif /* APT_TEXT_MESSAGE_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_text_stream.h b/libs/unimrcp/libs/apr-toolkit/include/apt_text_stream.h index e9e40cad5b..3df2565145 100644 --- a/libs/unimrcp/libs/apr-toolkit/include/apt_text_stream.h +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_text_stream.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,25 +12,27 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_text_stream.h 1672 2010-04-28 20:37:22Z achaloyan $ */ -#ifndef __APT_TEXT_STREAM_H__ -#define __APT_TEXT_STREAM_H__ +#ifndef APT_TEXT_STREAM_H +#define APT_TEXT_STREAM_H /** * @file apt_text_stream.h * @brief Text Stream Parse/Generate Routine */ -#include "apt_string.h" +#include "apt_string_table.h" #include "apt_pair.h" APT_BEGIN_EXTERN_C -/** Named tokens */ - /** Space */ -#define APT_TOKEN_SP ' ' +#define APT_TOKEN_SP 0x20 +/** Horizontal tab */ +#define APT_TOKEN_HTAB 0x09 /** Carrige return */ #define APT_TOKEN_CR 0x0D /** Line feed */ @@ -52,73 +54,77 @@ struct apt_text_stream_t { apt_bool_t is_eos; }; + /** - * Navigate through the lines of the text stream (message). - * @param stream the text stream to navigate + * Read entire line of the text stream. + * @param stream the text stream to navigate on * @param line the read line to return * @return TRUE if the line is successfully read, otherwise FALSE + * @remark To be used to navigate through the lines of the text stream (message). */ APT_DECLARE(apt_bool_t) apt_text_line_read(apt_text_stream_t *stream, apt_str_t *line); /** - * Navigate through the headers (name:value pairs) of the text stream (message). + * Read header field (name-value pair) of the text stream by scanning entire line. * @param stream the text stream to navigate * @param pair the read pair to return * @return TRUE if the header is successfully read, otherwise FALSE + * @remark To be used to navigate through the lines and read header fields + * (name:value pairs) of the text stream (message). */ APT_DECLARE(apt_bool_t) apt_text_header_read(apt_text_stream_t *stream, apt_pair_t *pair); /** - * Navigate through the fields of the line. + * Read the field terminated with specified separator. * @param stream the text stream to navigate * @param separator the field separator * @param skip_spaces whether to skip spaces or not * @param field the read field to return - * @return TRUE if the length of the field > 0, otherwise FALSE + * @return TRUE if the read field isn't empty, otherwise FALSE + * @remark To be used to navigate through the fields of the text stream (message). */ APT_DECLARE(apt_bool_t) apt_text_field_read(apt_text_stream_t *stream, char separator, apt_bool_t skip_spaces, apt_str_t *field); +/** Generate name-value pair line */ +APT_DECLARE(apt_bool_t) apt_text_name_value_insert(apt_text_stream_t *stream, const apt_str_t *name, const apt_str_t *value); - -/** Generate header */ -APT_DECLARE(apt_bool_t) apt_text_header_generate(const apt_pair_t *pair, apt_text_stream_t *text_stream); - -/** Generate only the name ("name:") of the header */ -APT_DECLARE(apt_bool_t) apt_text_header_name_generate(const apt_str_t *name, apt_text_stream_t *text_stream); +/** Generate only the name ("name:") of the header field */ +APT_DECLARE(apt_bool_t) apt_text_header_name_insert(apt_text_stream_t *stream, const apt_str_t *name); /** Parse array of name-value pairs */ APT_DECLARE(apt_bool_t) apt_pair_array_parse(apt_pair_arr_t *arr, const apt_str_t *value, apr_pool_t *pool); /** Generate array of name-value pairs */ -APT_DECLARE(apt_bool_t) apt_pair_array_generate(apt_pair_arr_t *arr, apt_text_stream_t *text_stream); +APT_DECLARE(apt_bool_t) apt_pair_array_generate(const apt_pair_arr_t *arr, apt_str_t *str, apr_pool_t *pool); + +/** Insert array of name-value pairs */ +APT_DECLARE(apt_bool_t) apt_text_pair_array_insert(apt_text_stream_t *stream, const apt_pair_arr_t *arr); /** Parse boolean-value */ APT_DECLARE(apt_bool_t) apt_boolean_value_parse(const apt_str_t *str, apt_bool_t *value); +/** Generate apr_size_t value from pool (buffer is allocated from pool) */ +APT_DECLARE(apt_bool_t) apt_boolean_value_generate(apt_bool_t value, apt_str_t *str, apr_pool_t *pool); -/** Generate boolean-value */ -APT_DECLARE(apt_bool_t) apt_boolean_value_generate(apt_bool_t value, apt_text_stream_t *str); +/** Insert boolean-value */ +APT_DECLARE(apt_bool_t) apt_text_boolean_value_insert(apt_text_stream_t *stream, apt_bool_t value); -/** Parse size_t value */ +/** Parse apr_size_t value */ APT_DECLARE(apr_size_t) apt_size_value_parse(const apt_str_t *str); +/** Generate apr_size_t value from pool (buffer is allocated from pool) */ +APT_DECLARE(apt_bool_t) apt_size_value_generate(apr_size_t value, apt_str_t *str, apr_pool_t *pool); -/** Generate apr_size_t value */ -APT_DECLARE(apt_bool_t) apt_size_value_generate(apr_size_t value, apt_text_stream_t *stream); +/** Insert apr_size_t value */ +APT_DECLARE(apt_bool_t) apt_text_size_value_insert(apt_text_stream_t *stream, apr_size_t value); /** Parse float value */ APT_DECLARE(float) apt_float_value_parse(const apt_str_t *str); +/** Generate float value (buffer is allocated from pool) */ +APT_DECLARE(apt_bool_t) apt_float_value_generate(float value, apt_str_t *str, apr_pool_t *pool); -/** Generate float value */ -APT_DECLARE(apt_bool_t) apt_float_value_generate(float value, apt_text_stream_t *stream); - -/** Generate string value */ -static APR_INLINE apt_bool_t apt_string_value_generate(const apt_str_t *str, apt_text_stream_t *stream) -{ - if(str->length) { - memcpy(stream->pos,str->buf,str->length); - stream->pos += str->length; - } - return TRUE; -} +/** Insert float value */ +APT_DECLARE(apt_bool_t) apt_text_float_value_insert(apt_text_stream_t *stream, float value); +/** Insert string value */ +APT_DECLARE(apt_bool_t) apt_text_string_insert(apt_text_stream_t *stream, const apt_str_t *str); /** Reset navigation related data of the text stream */ static APR_INLINE void apt_text_stream_reset(apt_text_stream_t *stream) @@ -137,36 +143,74 @@ static APR_INLINE void apt_text_stream_init(apt_text_stream_t *stream, char *buf } /** Insert end of the line symbol(s) */ -static APR_INLINE void apt_text_eol_insert(apt_text_stream_t *stream) +static APR_INLINE apt_bool_t apt_text_eol_insert(apt_text_stream_t *stream) { - *stream->pos++ = APT_TOKEN_CR; - *stream->pos++ = APT_TOKEN_LF; + if(stream->pos + 2 < stream->end) { + *stream->pos++ = APT_TOKEN_CR; + *stream->pos++ = APT_TOKEN_LF; + return TRUE; + } + return FALSE; } /** Insert character */ -static APR_INLINE void apt_text_char_insert(apt_text_stream_t *stream, char ch) +static APR_INLINE apt_bool_t apt_text_char_insert(apt_text_stream_t *stream, char ch) { - *stream->pos++ = ch; + if(stream->pos + 1 < stream->end) { + *stream->pos++ = ch; + return TRUE; + } + return FALSE; } /** Insert space */ -static APR_INLINE void apt_text_space_insert(apt_text_stream_t *stream) +static APR_INLINE apt_bool_t apt_text_space_insert(apt_text_stream_t *stream) { - *stream->pos++ = APT_TOKEN_SP; + return apt_text_char_insert(stream,APT_TOKEN_SP); } -/** Skip spaces */ +/** Insert space */ +static APR_INLINE apt_bool_t apt_text_htab_insert(apt_text_stream_t *stream) +{ + return apt_text_char_insert(stream,APT_TOKEN_HTAB); +} + +/** Check whether specified character is a white space (WSP = SP / HTAB) */ +static APR_INLINE apt_bool_t apt_text_is_wsp(char ch) +{ + return (ch == APT_TOKEN_SP || ch == APT_TOKEN_HTAB) ? TRUE : FALSE; +} + +/** Skip sequence of spaces */ static APR_INLINE void apt_text_spaces_skip(apt_text_stream_t *stream) { - const char *end = stream->text.buf + stream->text.length; - while(stream->pos < end && *stream->pos == APT_TOKEN_SP) stream->pos++; + while(stream->pos < stream->end && *stream->pos == APT_TOKEN_SP) + stream->pos++; +} + +/** Skip sequence of white spaces (WSP = SP / HTAB) */ +static APR_INLINE void apt_text_white_spaces_skip(apt_text_stream_t *stream) +{ + while(stream->pos < stream->end && apt_text_is_wsp(*stream->pos) == TRUE) + stream->pos++; } /** Skip specified character */ static APR_INLINE void apt_text_char_skip(apt_text_stream_t *stream, char ch) { - const char *end = stream->text.buf + stream->text.length; - if(stream->pos < end && *stream->pos == ch) stream->pos++; + if(stream->pos < stream->end && *stream->pos == ch) stream->pos++; +} + +/** Skip sequence of specified characters */ +static APR_INLINE void apt_text_chars_skip(apt_text_stream_t *stream, char ch) +{ + while(stream->pos < stream->end && *stream->pos == ch) stream->pos++; +} + +/** Skip to specified character */ +static APR_INLINE void apt_text_skip_to_char(apt_text_stream_t *stream, char ch) +{ + while(stream->pos < stream->end && *stream->pos != ch) stream->pos++; } /** Check whether end of stream is reached */ @@ -180,13 +224,14 @@ APT_DECLARE(apt_bool_t) apt_text_stream_scroll(apt_text_stream_t *stream); /** Parse id at resource string */ APT_DECLARE(apt_bool_t) apt_id_resource_parse(const apt_str_t *str, char separator, apt_str_t *id, apt_str_t *resource, apr_pool_t *pool); - /** Generate id at resource string */ APT_DECLARE(apt_bool_t) apt_id_resource_generate(const apt_str_t *id, const apt_str_t *resource, char separator, apt_str_t *str, apr_pool_t *pool); /** Generate value plus the length (number of digits) of the value itself */ APT_DECLARE(apt_bool_t) apt_var_length_value_generate(apr_size_t *value, apr_size_t max_count, apt_str_t *str); +/** Generate completion-cause */ +APT_DECLARE(apt_bool_t) apt_completion_cause_generate(const apt_str_table_item_t table[], apr_size_t size, apr_size_t cause, apt_str_t *str, apr_pool_t *pool); /** * Generate unique identifier (hex string) @@ -199,4 +244,4 @@ APT_DECLARE(apt_bool_t) apt_unique_id_generate(apt_str_t *id, apr_size_t length, APT_END_EXTERN_C -#endif /*__APT_TEXT_STREAM_H__*/ +#endif /* APT_TEXT_STREAM_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/include/apt_timer_queue.h b/libs/unimrcp/libs/apr-toolkit/include/apt_timer_queue.h new file mode 100644 index 0000000000..0536e94a8d --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/include/apt_timer_queue.h @@ -0,0 +1,68 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_timer_queue.h 1642 2010-04-08 13:37:57Z achaloyan $ + */ + +#ifndef APT_TIMER_QUEUE_H +#define APT_TIMER_QUEUE_H + +/** + * @file apt_timer_queue.h + * @brief Timer Queue + */ + +#include "apt.h" + +APT_BEGIN_EXTERN_C + +/** Opaque timer declaration */ +typedef struct apt_timer_t apt_timer_t; +/** Opaque timer queue declaration */ +typedef struct apt_timer_queue_t apt_timer_queue_t; + +/** Prototype of timer callback */ +typedef void (*apt_timer_proc_f)(apt_timer_t *timer, void *obj); + + +/** Create timer queue */ +APT_DECLARE(apt_timer_queue_t*) apt_timer_queue_create(apr_pool_t *pool); + +/** Destroy timer queue */ +APT_DECLARE(void) apt_timer_queue_destroy(apt_timer_queue_t *timer_queue); + +/** Advance scheduled timers */ +APT_DECLARE(void) apt_timer_queue_advance(apt_timer_queue_t *timer_queue, apr_uint32_t elapsed_time); + +/** Is timer queue empty */ +APT_DECLARE(apt_bool_t) apt_timer_queue_is_empty(const apt_timer_queue_t *timer_queue); + +/** Get current timeout */ +APT_DECLARE(apt_bool_t) apt_timer_queue_timeout_get(const apt_timer_queue_t *timer_queue, apr_uint32_t *timeout); + + +/** Create timer */ +APT_DECLARE(apt_timer_t*) apt_timer_create(apt_timer_queue_t *timer_queue, apt_timer_proc_f proc, void *obj, apr_pool_t *pool); + +/** Set one-shot timer */ +APT_DECLARE(apt_bool_t) apt_timer_set(apt_timer_t *timer, apr_uint32_t timeout); + +/** Kill timer */ +APT_DECLARE(apt_bool_t) apt_timer_kill(apt_timer_t *timer); + + +APT_END_EXTERN_C + +#endif /* APT_TIMER_QUEUE_H */ diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_consumer_task.c b/libs/unimrcp/libs/apr-toolkit/src/apt_consumer_task.c index ceb9320d98..28c691a274 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_consumer_task.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_consumer_task.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_consumer_task.c 1708 2010-05-24 17:03:25Z achaloyan $ */ #include @@ -54,7 +56,7 @@ APT_DECLARE(apt_consumer_task_t*) apt_consumer_task_create( return consumer_task; } -APT_DECLARE(apt_task_t*) apt_consumer_task_base_get(apt_consumer_task_t *task) +APT_DECLARE(apt_task_t*) apt_consumer_task_base_get(const apt_consumer_task_t *task) { return task->base; } @@ -64,7 +66,7 @@ APT_DECLARE(apt_task_vtable_t*) apt_consumer_task_vtable_get(apt_consumer_task_t return apt_task_vtable_get(task->base); } -APT_DECLARE(void*) apt_consumer_task_object_get(apt_consumer_task_t *task) +APT_DECLARE(void*) apt_consumer_task_object_get(const apt_consumer_task_t *task) { return task->obj; } @@ -79,22 +81,25 @@ static apt_bool_t apt_consumer_task_run(apt_task_t *task) { apr_status_t rv; void *msg; - apt_bool_t running = TRUE; + apt_bool_t *running; apt_consumer_task_t *consumer_task; consumer_task = apt_task_object_get(task); if(!consumer_task) { return FALSE; } - while(running) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Wait for Task Messages [%s]",apt_task_name_get(task)); + running = apt_task_running_flag_get(task); + if(!running) { + return FALSE; + } + + while(*running) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Wait for Messages [%s]",apt_task_name_get(task)); rv = apr_queue_pop(consumer_task->msg_queue,&msg); if(rv == APR_SUCCESS) { if(msg) { apt_task_msg_t *task_msg = msg; - if(apt_task_msg_process(consumer_task->base,task_msg) == FALSE) { - running = FALSE; - } + apt_task_msg_process(consumer_task->base,task_msg); } } } diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_cyclic_queue.c b/libs/unimrcp/libs/apr-toolkit/src/apt_cyclic_queue.c index fff7de514f..2ac36c4dbb 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_cyclic_queue.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_cyclic_queue.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_cyclic_queue.c 1708 2010-05-24 17:03:25Z achaloyan $ */ #include @@ -78,7 +80,7 @@ APT_DECLARE(void) apt_cyclic_queue_clear(apt_cyclic_queue_t *queue) queue->head = queue->tail = 0; } -APT_DECLARE(apt_bool_t) apt_cyclic_queue_is_empty(apt_cyclic_queue_t *queue) +APT_DECLARE(apt_bool_t) apt_cyclic_queue_is_empty(const apt_cyclic_queue_t *queue) { return queue->actual_size ? TRUE : FALSE; } diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_dir_layout.c b/libs/unimrcp/libs/apr-toolkit/src/apt_dir_layout.c index 9a527b63b0..2e651863d8 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_dir_layout.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_dir_layout.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_dir_layout.c 1524 2010-02-15 20:44:16Z achaloyan $ */ #include @@ -72,3 +74,14 @@ APT_DECLARE(char*) apt_datadir_filepath_get(const apt_dir_layout_t *dir_layout, } return NULL; } + +APT_DECLARE(char*) apt_confdir_filepath_get(const apt_dir_layout_t *dir_layout, const char *file_name, apr_pool_t *pool) +{ + if(dir_layout && dir_layout->conf_dir_path && file_name) { + char *file_path = NULL; + if(apr_filepath_merge(&file_path,dir_layout->conf_dir_path,file_name,0,pool) == APR_SUCCESS) { + return file_path; + } + } + return NULL; +} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_header_field.c b/libs/unimrcp/libs/apr-toolkit/src/apt_header_field.c new file mode 100644 index 0000000000..9cf814549f --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_header_field.c @@ -0,0 +1,183 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_header_field.c 1685 2010-05-06 05:34:54Z achaloyan $ + */ + +#include "apt_header_field.h" +#include "apt_text_stream.h" + +#define UNKNOWN_HEADER_FIELD_ID (apr_size_t)-1 + +/** Allocate an empty header field */ +APT_DECLARE(apt_header_field_t*) apt_header_field_alloc(apr_pool_t *pool) +{ + apt_header_field_t *header_field = apr_palloc(pool,sizeof(apt_header_field_t)); + apt_string_reset(&header_field->name); + apt_string_reset(&header_field->value); + header_field->id = UNKNOWN_HEADER_FIELD_ID; + APR_RING_ELEM_INIT(header_field,link); + return header_field; +} + +/** Create a header field using given name and value APT strings */ +APT_DECLARE(apt_header_field_t*) apt_header_field_create(const apt_str_t *name, const apt_str_t *value, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + if(!name || !value) { + return NULL; + } + header_field = apr_palloc(pool,sizeof(apt_header_field_t)); + apt_string_copy(&header_field->name,name,pool); + apt_string_copy(&header_field->value,value,pool); + header_field->id = UNKNOWN_HEADER_FIELD_ID; + APR_RING_ELEM_INIT(header_field,link); + return header_field; +} + +/** Create a header field using given name and value C strings */ +APT_DECLARE(apt_header_field_t*) apt_header_field_create_c(const char *name, const char *value, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + if(!name || !value) { + return NULL; + } + header_field = apr_palloc(pool,sizeof(apt_header_field_t)); + apt_string_assign(&header_field->name,name,pool); + apt_string_assign(&header_field->value,value,pool); + header_field->id = UNKNOWN_HEADER_FIELD_ID; + APR_RING_ELEM_INIT(header_field,link); + return header_field; +} + +/* Create a header field from entire text line consisting of a name and value pair */ +APT_DECLARE(apt_header_field_t*) apt_header_field_create_from_line(const apt_str_t *line, char separator, apr_pool_t *pool) +{ + apt_str_t item; + apt_text_stream_t stream; + apt_header_field_t *header_field; + if(!line) { + return NULL; + } + + header_field = apr_palloc(pool,sizeof(apt_header_field_t)); + stream.text = *line; + apt_text_stream_reset(&stream); + + /* read name */ + if(apt_text_field_read(&stream,separator,TRUE,&item) == FALSE) { + return NULL; + } + apt_string_copy(&header_field->name,&item,pool); + + /* read value */ + apt_text_field_read(&stream,0,TRUE,&item); + apt_string_copy(&header_field->value,&item,pool); + + header_field->id = UNKNOWN_HEADER_FIELD_ID; + APR_RING_ELEM_INIT(header_field,link); + return header_field; +} + +/** Copy specified header field */ +APT_DECLARE(apt_header_field_t*) apt_header_field_copy(const apt_header_field_t *src_header_field, apr_pool_t *pool) +{ + apt_header_field_t *header_field = apr_palloc(pool,sizeof(apt_header_field_t)); + apt_string_copy(&header_field->name,&src_header_field->name,pool); + apt_string_copy(&header_field->value,&src_header_field->value,pool); + header_field->id = src_header_field->id; + APR_RING_ELEM_INIT(header_field,link); + return header_field; +} + +/** Initialize header section (collection of header fields) */ +APT_DECLARE(void) apt_header_section_init(apt_header_section_t *header) +{ + APR_RING_INIT(&header->ring, apt_header_field_t, link); + header->arr = NULL; + header->arr_size = 0; +} + +/** Allocate header section to set/get header fields by numeric identifiers */ +APT_DECLARE(apt_bool_t) apt_header_section_array_alloc(apt_header_section_t *header, apr_size_t max_field_count, apr_pool_t *pool) +{ + if(!max_field_count) { + return FALSE; + } + + header->arr = (apt_header_field_t**)apr_pcalloc(pool,sizeof(apt_header_field_t*) * max_field_count); + header->arr_size = max_field_count; + return TRUE; +} + +/** Add (append) header field to header section */ +APT_DECLARE(apt_bool_t) apt_header_section_field_add(apt_header_section_t *header, apt_header_field_t *header_field) +{ + if(header_field->id < header->arr_size) { + if(header->arr[header_field->id]) { + return FALSE; + } + header->arr[header_field->id] = header_field; + } + APR_RING_INSERT_TAIL(&header->ring,header_field,apt_header_field_t,link); + return TRUE; +} + +/** Insert header field to header section based on numreic identifier if specified */ +APT_DECLARE(apt_bool_t) apt_header_section_field_insert(apt_header_section_t *header, apt_header_field_t *header_field) +{ + apt_header_field_t *it; + if(header_field->id < header->arr_size) { + if(header->arr[header_field->id]) { + return FALSE; + } + header->arr[header_field->id] = header_field; + + for(it = APR_RING_FIRST(&header->ring); + it != APR_RING_SENTINEL(&header->ring, apt_header_field_t, link); + it = APR_RING_NEXT(it, link)) { + if(header_field->id < it->id) { + APR_RING_INSERT_BEFORE(it,header_field,link); + return TRUE; + } + } + } + + APR_RING_INSERT_TAIL(&header->ring,header_field,apt_header_field_t,link); + return TRUE; +} + +/** Set header field in the array of header fields using associated numeric identifier */ +APT_DECLARE(apt_bool_t) apt_header_section_field_set(apt_header_section_t *header, apt_header_field_t *header_field) +{ + if(header_field->id >= header->arr_size) { + return FALSE; + } + if(header->arr[header_field->id]) { + return FALSE; + } + header->arr[header_field->id] = header_field; + return TRUE; +} + +/** Remove header field from header section */ +APT_DECLARE(apt_bool_t) apt_header_section_field_remove(apt_header_section_t *header, apt_header_field_t *header_field) +{ + if(header_field->id < header->arr_size) { + header->arr[header_field->id] = NULL; + } + APR_RING_REMOVE(header_field,link); + return TRUE; +} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_log.c b/libs/unimrcp/libs/apr-toolkit/src/apt_log.c index 4ad91a996b..10b374d957 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_log.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_log.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,14 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_log.c 1792 2011-01-10 21:08:52Z achaloyan $ */ #include #include +#include +#include #include "apt_log.h" #define MAX_LOG_ENTRY_SIZE 4096 @@ -43,6 +47,7 @@ struct apt_log_file_data_t { apr_size_t max_size; apr_size_t cur_file_index; apr_size_t max_file_count; + apt_bool_t append; apr_thread_mutex_t *mutex; apr_pool_t *pool; }; @@ -53,6 +58,7 @@ struct apt_logger_t { int header; apt_log_ext_handler_f ext_handler; apt_log_file_data_t *file_data; + apt_log_masking_e masking; }; static apt_logger_t *apt_logger = NULL; @@ -61,19 +67,83 @@ static apt_bool_t apt_do_log(const char *file, int line, apt_log_priority_e prio static const char* apt_log_file_path_make(apt_log_file_data_t *file_data); static apt_bool_t apt_log_file_dump(apt_log_file_data_t *file_data, const char *log_entry, apr_size_t size); +static apr_xml_doc* apt_log_doc_parse(const char *file_path, apr_pool_t *pool); +static apr_size_t apt_log_file_get_size(apt_log_file_data_t *file_data); +static apr_byte_t apt_log_file_exist(apt_log_file_data_t *file_data); +static apt_logger_t* apt_log_instance_alloc(apr_pool_t *pool) +{ + apt_logger_t *logger = apr_palloc(pool,sizeof(apt_logger_t)); + logger->mode = APT_LOG_OUTPUT_CONSOLE; + logger->priority = APT_PRIO_INFO; + logger->header = APT_LOG_HEADER_DEFAULT; + logger->ext_handler = NULL; + logger->file_data = NULL; + logger->masking = APT_LOG_MASKING_NONE; + return logger; +} APT_DECLARE(apt_bool_t) apt_log_instance_create(apt_log_output_e mode, apt_log_priority_e priority, apr_pool_t *pool) { if(apt_logger) { return FALSE; } - apt_logger = apr_palloc(pool,sizeof(apt_logger_t)); + apt_logger = apt_log_instance_alloc(pool); apt_logger->mode = mode; apt_logger->priority = priority; - apt_logger->header = APT_LOG_HEADER_DEFAULT; - apt_logger->ext_handler = NULL; - apt_logger->file_data = NULL; + return TRUE; +} + +APT_DECLARE(apt_bool_t) apt_log_instance_load(const char *config_file, apr_pool_t *pool) +{ + apr_xml_doc *doc; + const apr_xml_elem *elem; + const apr_xml_elem *root; + char *text; + + if(apt_logger) { + return FALSE; + } + apt_logger = apt_log_instance_alloc(pool); + + /* Parse XML document */ + doc = apt_log_doc_parse(config_file,pool); + if(!doc) { + return FALSE; + } + + root = doc->root; + + /* Match document name */ + if(!root || strcasecmp(root->name,"aptlogger") != 0) { + /* Unknown document */ + return FALSE; + } + + /* Navigate through document */ + for(elem = root->first_child; elem; elem = elem->next) { + if(!elem->first_cdata.first || !elem->first_cdata.first->text) + continue; + + text = apr_pstrdup(pool,elem->first_cdata.first->text); + apr_collapse_spaces(text,text); + + if(strcasecmp(elem->name,"priority") == 0) { + apt_logger->priority = apt_log_priority_translate(text); + } + else if(strcasecmp(elem->name,"output") == 0) { + apt_logger->mode = apt_log_output_mode_translate(text); + } + else if(strcasecmp(elem->name,"headers") == 0) { + apt_logger->header = apt_log_header_translate(text); + } + else if(strcasecmp(elem->name,"masking") == 0) { + apt_logger->masking = apt_log_masking_translate(text); + } + else { + /* Unknown element */ + } + } return TRUE; } @@ -104,7 +174,13 @@ APT_DECLARE(apt_bool_t) apt_log_instance_set(apt_logger_t *logger) return TRUE; } -APT_DECLARE(apt_bool_t) apt_log_file_open(const char *dir_path, const char *file_name, apr_size_t max_file_size, apr_size_t max_file_count, apr_pool_t *pool) +APT_DECLARE(apt_bool_t) apt_log_file_open( + const char *dir_path, + const char *file_name, + apr_size_t max_file_size, + apr_size_t max_file_count, + apt_bool_t append, + apr_pool_t *pool) { const char *log_file_path; apt_log_file_data_t *file_data; @@ -117,29 +193,55 @@ APT_DECLARE(apt_bool_t) apt_log_file_open(const char *dir_path, const char *file } file_data = apr_palloc(pool,sizeof(apt_log_file_data_t)); - file_data->log_dir_path = dir_path; - file_data->log_file_name = file_name; + file_data->log_dir_path = apr_pstrdup(pool,dir_path); + file_data->log_file_name = apr_pstrdup(pool,file_name); file_data->cur_file_index = 0; file_data->cur_size = 0; file_data->max_file_count = max_file_count; file_data->max_size = max_file_size; + file_data->append = append; file_data->mutex = NULL; file_data->pool = pool; if(!file_data->max_size) { - file_data->max_file_count = MAX_LOG_FILE_SIZE; + file_data->max_size = MAX_LOG_FILE_SIZE; } if(!file_data->max_file_count) { file_data->max_file_count = MAX_LOG_FILE_COUNT; } + if(file_data->append == TRUE) { + /* iteratively find the last created file */ + while(file_data->cur_file_indexmax_file_count) + { + if(apt_log_file_exist(file_data) == 0) + { + if(file_data->cur_file_index > 0) + file_data->cur_file_index--; + file_data->cur_size = apt_log_file_get_size(file_data); + break; + } + file_data->cur_file_index++; + } + + /* if all the files have been created start rewriting from beginning */ + if(file_data->cur_file_index>=file_data->max_file_count) + { + file_data->cur_file_index=0; + file_data->cur_size=0; + log_file_path = apt_log_file_path_make(file_data); + file_data->file = fopen(log_file_path,"wb"); /* truncate the first file to zero length */ + fclose(file_data->file); + } + } + /* create mutex */ if(apr_thread_mutex_create(&file_data->mutex,APR_THREAD_MUTEX_DEFAULT,pool) != APR_SUCCESS) { return FALSE; } /* open log file */ log_file_path = apt_log_file_path_make(file_data); - file_data->file = fopen(log_file_path,"wb"); + file_data->file = fopen(log_file_path,file_data->append == TRUE ? "ab" : "wb"); if(!file_data->file) { apr_thread_mutex_destroy(file_data->mutex); return FALSE; @@ -177,6 +279,31 @@ APT_DECLARE(apt_bool_t) apt_log_output_mode_set(apt_log_output_e mode) return TRUE; } +APT_DECLARE(apt_bool_t) apt_log_output_mode_check(apt_log_output_e mode) +{ + if(!apt_logger) { + return FALSE; + } + return (apt_logger->mode | mode) ? TRUE : FALSE; +} + +APT_DECLARE(int) apt_log_output_mode_translate(char *str) +{ + int mode = APT_LOG_OUTPUT_NONE; + char *name; + char *last; + name = apr_strtok(str, ",", &last); + while(name) { + if(strcasecmp(name, "CONSOLE") == 0) + mode |= APT_LOG_OUTPUT_CONSOLE; + else if(strcasecmp(name, "FILE") == 0) + mode |= APT_LOG_OUTPUT_FILE; + + name = apr_strtok(NULL, ",", &last); + } + return mode; +} + APT_DECLARE(apt_bool_t) apt_log_priority_set(apt_log_priority_e priority) { if(!apt_logger || priority >= APT_PRIO_COUNT) { @@ -186,6 +313,28 @@ APT_DECLARE(apt_bool_t) apt_log_priority_set(apt_log_priority_e priority) return TRUE; } +APT_DECLARE(apt_log_priority_e) apt_log_priority_translate(const char *str) +{ + if(strcasecmp(str, "EMERGENCY") == 0) + return APT_PRIO_EMERGENCY; + else if(strcasecmp(str, "ALERT") == 0) + return APT_PRIO_ALERT; + else if(strcasecmp(str, "CRITICAL") == 0) + return APT_PRIO_CRITICAL; + else if(strcasecmp(str, "ERROR") == 0) + return APT_PRIO_ERROR; + else if(strcasecmp(str, "WARNING") == 0) + return APT_PRIO_WARNING; + else if(strcasecmp(str, "NOTICE") == 0) + return APT_PRIO_NOTICE; + else if(strcasecmp(str, "INFO") == 0) + return APT_PRIO_INFO; + else if(strcasecmp(str, "DEBUG") == 0) + return APT_PRIO_DEBUG; + + return APT_PRIO_DEBUG; +} + APT_DECLARE(apt_bool_t) apt_log_header_set(int header) { if(!apt_logger) { @@ -195,6 +344,69 @@ APT_DECLARE(apt_bool_t) apt_log_header_set(int header) return TRUE; } +APT_DECLARE(int) apt_log_header_translate(char *str) +{ + int header = APT_LOG_OUTPUT_NONE; + char *name; + char *last; + name = apr_strtok(str, ",", &last); + while(name) { + if(strcasecmp(name, "DATE") == 0) + header |= APT_LOG_HEADER_DATE; + else if(strcasecmp(name, "TIME") == 0) + header |= APT_LOG_HEADER_TIME; + else if(strcasecmp(name, "PRIORITY") == 0) + header |= APT_LOG_HEADER_PRIORITY; + else if(strcasecmp(name, "MARK") == 0) + header |= APT_LOG_HEADER_MARK; + else if(strcasecmp(name, "THREAD") == 0) + header |= APT_LOG_HEADER_THREAD; + + name = apr_strtok(NULL, ",", &last); + } + return header; +} + +APT_DECLARE(apt_bool_t) apt_log_masking_set(apt_log_masking_e masking) +{ + if(!apt_logger) { + return FALSE; + } + apt_logger->masking = masking; + return TRUE; +} + +APT_DECLARE(apt_log_masking_e) apt_log_masking_get() +{ + if(!apt_logger) { + return APT_LOG_MASKING_NONE; + } + return apt_logger->masking; +} + +APT_DECLARE(apt_log_masking_e) apt_log_masking_translate(const char *str) +{ + if(strcasecmp(str, "COMPLETE") == 0) + return APT_LOG_MASKING_COMPLETE; + else if(strcasecmp(str, "ENCRYPTED") == 0) + return APT_LOG_MASKING_ENCRYPTED; + return APT_LOG_MASKING_NONE; +} + +#define APT_MASKED_CONTENT "*** masked ***" + +APT_DECLARE(const char*) apt_log_data_mask(const char *data_in, apr_size_t *length, apr_pool_t *pool) +{ + if(!apt_logger) { + return NULL; + } + if(apt_logger->masking == APT_LOG_MASKING_COMPLETE) { + *length = sizeof(APT_MASKED_CONTENT) - 1; + return APT_MASKED_CONTENT; + } + return data_in; +} + APT_DECLARE(apt_bool_t) apt_log_ext_handler_set(apt_log_ext_handler_f handler) { if(!apt_logger) { @@ -224,6 +436,35 @@ APT_DECLARE(apt_bool_t) apt_log(const char *file, int line, apt_log_priority_e p return status; } +APT_DECLARE(apt_bool_t) apt_obj_log(const char *file, int line, apt_log_priority_e priority, void *obj, const char *format, ...) +{ + apt_bool_t status = TRUE; + if(!apt_logger) { + return FALSE; + } + if(priority <= apt_logger->priority) { + va_list arg_ptr; + va_start(arg_ptr, format); + if(apt_logger->ext_handler) { + status = apt_logger->ext_handler(file,line,obj,priority,format,arg_ptr); + } + else { + status = apt_do_log(file,line,priority,format,arg_ptr); + } + va_end(arg_ptr); + } + return status; +} + +static APR_INLINE unsigned long apt_thread_id_get() +{ +#ifdef WIN32 + return (unsigned long) GetCurrentThreadId(); +#else + return (unsigned long) apr_os_thread_current(); +#endif +} + static apt_bool_t apt_do_log(const char *file, int line, apt_log_priority_e priority, const char *format, va_list arg_ptr) { char log_entry[MAX_LOG_ENTRY_SIZE]; @@ -249,6 +490,9 @@ static apt_bool_t apt_do_log(const char *file, int line, apt_log_priority_e prio if(apt_logger->header & APT_LOG_HEADER_MARK) { offset += apr_snprintf(log_entry+offset,max_size-offset,"%s:%03d ",file,line); } + if(apt_logger->header & APT_LOG_HEADER_THREAD) { + offset += apr_snprintf(log_entry+offset,max_size-offset,"%05lu ",apt_thread_id_get()); + } if(apt_logger->header & APT_LOG_HEADER_PRIORITY) { memcpy(log_entry+offset,priority_snames[priority],MAX_PRIORITY_NAME_LENGTH); offset += MAX_PRIORITY_NAME_LENGTH; @@ -275,6 +519,40 @@ static const char* apt_log_file_path_make(apt_log_file_data_t *file_data) return log_file_path; } +static apr_size_t apt_log_file_get_size(apt_log_file_data_t *file_data) +{ + FILE* fp; + const char *log_file_path; + apr_size_t ret; + + log_file_path = apt_log_file_path_make(file_data); + fp = fopen(log_file_path,"rb"); + + if(!fp) return 0; + + fseek(fp,0,SEEK_END); + ret = ftell(fp); + + fclose(fp); + + return ret; +} + +static apr_byte_t apt_log_file_exist(apt_log_file_data_t *file_data) +{ + FILE* fp; + const char *log_file_path; + + log_file_path = apt_log_file_path_make(file_data); + fp = fopen(log_file_path,"rb"); + + if(!fp) return 0; + + fclose(fp); + + return 1; +} + static apt_bool_t apt_log_file_dump(apt_log_file_data_t *file_data, const char *log_entry, apr_size_t size) { apr_thread_mutex_lock(file_data->mutex); @@ -303,3 +581,24 @@ static apt_bool_t apt_log_file_dump(apt_log_file_data_t *file_data, const char * apr_thread_mutex_unlock(file_data->mutex); return TRUE; } + +static apr_xml_doc* apt_log_doc_parse(const char *file_path, apr_pool_t *pool) +{ + apr_xml_parser *parser = NULL; + apr_xml_doc *xml_doc = NULL; + apr_file_t *fd = NULL; + apr_status_t rv; + + rv = apr_file_open(&fd,file_path,APR_READ|APR_BINARY,0,pool); + if(rv != APR_SUCCESS) { + return NULL; + } + + rv = apr_xml_parse_file(pool,&parser,&xml_doc,fd,2000); + if(rv != APR_SUCCESS) { + xml_doc = NULL; + } + + apr_file_close(fd); + return xml_doc; +} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_multipart_content.c b/libs/unimrcp/libs/apr-toolkit/src/apt_multipart_content.c new file mode 100644 index 0000000000..3f3690ff7a --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_multipart_content.c @@ -0,0 +1,312 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_multipart_content.c 1673 2010-04-28 20:45:47Z achaloyan $ + */ + +#include +#include "apt_multipart_content.h" +#include "apt_text_stream.h" +#include "apt_text_message.h" + +#define CONTENT_LENGTH_HEADER "Content-Length" +#define CONTENT_TYPE_HEADER "Content-Type" +#define CONTENT_ID_HEADER "Content-Id" + +#define DEFAULT_BOUNDARY "break" +#define DEFAULT_HYPHENS "--" + +#define DEFAULT_MULTIPART_CONTENT_SIZE 4096 + +/** Multipart content */ +struct apt_multipart_content_t { + apr_pool_t *pool; + apt_text_stream_t stream; + + apt_str_t boundary; + apt_str_t hyphens; +}; + +/** Create an empty multipart content */ +APT_DECLARE(apt_multipart_content_t*) apt_multipart_content_create(apr_size_t max_content_size, const apt_str_t *boundary, apr_pool_t *pool) +{ + char *buffer; + apt_multipart_content_t *multipart_content = apr_palloc(pool,sizeof(apt_multipart_content_t)); + multipart_content->pool = pool; + + if(max_content_size == 0) { + max_content_size = DEFAULT_MULTIPART_CONTENT_SIZE; + } + + if(boundary) { + multipart_content->boundary = *boundary; + } + else { + multipart_content->boundary.buf = DEFAULT_BOUNDARY; + multipart_content->boundary.length = sizeof(DEFAULT_BOUNDARY)-1; + } + + multipart_content->hyphens.buf = DEFAULT_HYPHENS; + multipart_content->hyphens.length = sizeof(DEFAULT_HYPHENS)-1; + + buffer = apr_palloc(pool,max_content_size+1); + apt_text_stream_init(&multipart_content->stream,buffer,max_content_size); + return multipart_content; +} + +/** Initialize content part generation */ +static apt_bool_t apt_multipart_content_initialize(apt_multipart_content_t *multipart_content) +{ + /* insert preceding end-of-line */ + if(apt_text_eol_insert(&multipart_content->stream) == FALSE) { + return FALSE; + } + /* insert hyphens */ + if(apt_text_string_insert(&multipart_content->stream,&multipart_content->hyphens) == FALSE) { + return FALSE; + } + /* insert boundary */ + if(apt_text_string_insert(&multipart_content->stream,&multipart_content->boundary) == FALSE) { + return FALSE; + } + return apt_text_eol_insert(&multipart_content->stream); +} + +/** Add content part to multipart content */ +APT_DECLARE(apt_bool_t) apt_multipart_content_add(apt_multipart_content_t *multipart_content, const apt_content_part_t *content_part) +{ + if(!content_part) { + return FALSE; + } + + /* insert preceding eol, hyppens and boudnary */ + if(apt_multipart_content_initialize(multipart_content) == FALSE) { + return FALSE; + } + + /* insert header fields */ + if(apt_header_section_generate(&content_part->header,&multipart_content->stream) == FALSE) { + return FALSE; + } + + /* insert body */ + return apt_text_string_insert(&multipart_content->stream,&content_part->body); +} + +/** Add content part to multipart content by specified header fields and body */ +APT_DECLARE(apt_bool_t) apt_multipart_content_add2(apt_multipart_content_t *multipart_content, const apt_str_t *content_type, const apt_str_t *content_id, const apt_str_t *body) +{ + /* insert preceding eol, hyppens and boudnary */ + if(apt_multipart_content_initialize(multipart_content) == FALSE) { + return FALSE; + } + + /* insert content-type */ + if(content_type) { + apt_str_t name = {CONTENT_TYPE_HEADER,sizeof(CONTENT_TYPE_HEADER)-1}; + if(apt_text_name_value_insert(&multipart_content->stream,&name,content_type) == FALSE) { + return FALSE; + } + } + + /* insert content-id */ + if(content_id) { + apt_str_t name = {CONTENT_ID_HEADER,sizeof(CONTENT_ID_HEADER)-1}; + if(apt_text_name_value_insert(&multipart_content->stream,&name,content_id) == FALSE) { + return FALSE; + } + } + + /* insert content-length */ + if(body) { + apt_str_t name = {CONTENT_LENGTH_HEADER,sizeof(CONTENT_LENGTH_HEADER)-1}; + if(apt_text_header_name_insert(&multipart_content->stream,&name) == FALSE) { + return FALSE; + } + if(apt_text_size_value_insert(&multipart_content->stream,body->length) == FALSE) { + return FALSE; + } + if(apt_text_eol_insert(&multipart_content->stream) == FALSE) { + return FALSE; + } + } + + /* insert empty line */ + if(apt_text_eol_insert(&multipart_content->stream) == FALSE) { + return FALSE; + } + + /* insert body */ + if(body) { + if(apt_text_string_insert(&multipart_content->stream,body) == FALSE) { + return FALSE; + } + } + return TRUE; +} + +/** Finalize multipart content generation */ +APT_DECLARE(apt_str_t*) apt_multipart_content_finalize(apt_multipart_content_t *multipart_content) +{ + apt_text_stream_t *stream = &multipart_content->stream; + /* insert preceding end-of-line */ + if(apt_text_eol_insert(&multipart_content->stream) == FALSE) { + return NULL; + } + /* insert hyphens */ + if(apt_text_string_insert(&multipart_content->stream,&multipart_content->hyphens) == FALSE) { + return NULL; + } + /* insert boundary */ + if(apt_text_string_insert(&multipart_content->stream,&multipart_content->boundary) == FALSE) { + return NULL; + } + /* insert final hyphens */ + if(apt_text_string_insert(&multipart_content->stream,&multipart_content->hyphens) == FALSE) { + return NULL; + } + if(apt_text_eol_insert(&multipart_content->stream) == FALSE) { + return NULL; + } + + stream->text.length = stream->pos - stream->text.buf; + stream->text.buf[stream->text.length] = '\0'; + return &stream->text; +} + + +/** Assign body to multipart content to get (parse) each content part from */ +APT_DECLARE(apt_multipart_content_t*) apt_multipart_content_assign(const apt_str_t *body, const apt_str_t *boundary, apr_pool_t *pool) +{ + apt_multipart_content_t *multipart_content = apr_palloc(pool,sizeof(apt_multipart_content_t)); + multipart_content->pool = pool; + + if(!body) { + return FALSE; + } + + if(boundary) { + multipart_content->boundary = *boundary; + } + else { + apt_string_reset(&multipart_content->boundary); + } + + apt_string_reset(&multipart_content->hyphens); + apt_text_stream_init(&multipart_content->stream,body->buf,body->length); + return multipart_content; +} + +static APR_INLINE void apt_content_part_reset(apt_content_part_t *content_part) +{ + apt_header_section_init(&content_part->header); + apt_string_reset(&content_part->body); + content_part->type = NULL; + content_part->id = NULL; + content_part->length = NULL; +} + +/** Get the next content part */ +APT_DECLARE(apt_bool_t) apt_multipart_content_get(apt_multipart_content_t *multipart_content, apt_content_part_t *content_part, apt_bool_t *is_final) +{ + apt_str_t boundary; + apt_header_field_t *header_field; + apt_text_stream_t *stream = &multipart_content->stream; + + if(!content_part || !is_final) { + return FALSE; + } + *is_final = FALSE; + apt_content_part_reset(content_part); + + /* skip preamble */ + apt_text_skip_to_char(stream,'-'); + if(apt_text_is_eos(stream) == TRUE) { + return FALSE; + } + + /* skip initial hyphens */ + apt_text_chars_skip(stream,'-'); + if(apt_text_is_eos(stream) == TRUE) { + return FALSE; + } + + /* read line and the boundary */ + if(apt_text_line_read(stream,&boundary) == FALSE) { + return FALSE; + } + + /* remove optional trailing spaces */ + while(boundary.length && boundary.buf[boundary.length-1] == APT_TOKEN_SP) boundary.length--; + + /* check whether this is the final boundary */ + if(boundary.length >= 2) { + if(boundary.buf[boundary.length-1] == '-' && boundary.buf[boundary.length-2] == '-') { + /* final boundary */ + boundary.length -= 2; + *is_final = TRUE; + } + } + + /* compare boundaries */ + if(apt_string_is_empty(&multipart_content->boundary) == TRUE) { + /* no boundary was specified from user space, + learn boundary from the content */ + multipart_content->boundary = boundary; + } + else { + if(apt_string_compare(&multipart_content->boundary,&boundary) == FALSE) { + /* invalid boundary */ + return FALSE; + } + } + + if(*is_final == TRUE) { + /* final boundary => return TRUE, content remains empty */ + return TRUE; + } + + /* read header fields */ + if(apt_header_section_parse(&content_part->header,stream,multipart_content->pool) == FALSE) { + return FALSE; + } + + for(header_field = APR_RING_FIRST(&content_part->header.ring); + header_field != APR_RING_SENTINEL(&content_part->header.ring, apt_header_field_t, link); + header_field = APR_RING_NEXT(header_field, link)) { + if(strncmp(header_field->name.buf,CONTENT_LENGTH_HEADER,header_field->name.length) == 0) { + content_part->length = &header_field->value; + } + else if(strncmp(header_field->name.buf,CONTENT_TYPE_HEADER,header_field->name.length) == 0) { + content_part->type = &header_field->value; + } + else if(strncmp(header_field->name.buf,CONTENT_ID_HEADER,header_field->name.length) == 0) { + content_part->id = &header_field->value; + } + } + + if(content_part->length && apt_string_is_empty(content_part->length) == FALSE) { + apr_size_t length = atoi(content_part->length->buf); + if(length + stream->pos > stream->end) { + return FALSE; + } + + /* read content */ + apt_string_assign_n(&content_part->body,stream->pos,length,multipart_content->pool); + stream->pos += length; + } + + return TRUE; +} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_net.c b/libs/unimrcp/libs/apr-toolkit/src/apt_net.c index 733f0e20bc..e8da32a5b4 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_net.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_net.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_net.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_net_client_task.c b/libs/unimrcp/libs/apr-toolkit/src/apt_net_client_task.c deleted file mode 100644 index 6effe42f3c..0000000000 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_net_client_task.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright 2008 Arsen Chaloyan - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apt_net_client_task.h" -#include "apt_task.h" -#include "apt_pool.h" -#include "apt_pollset.h" -#include "apt_cyclic_queue.h" -#include "apt_log.h" - - -/** Network client task */ -struct apt_net_client_task_t { - apr_pool_t *pool; - apt_task_t *base; - void *obj; - - apr_size_t max_connection_count; - - apr_thread_mutex_t *guard; - apt_cyclic_queue_t *msg_queue; - apt_pollset_t *pollset; - - const apt_net_client_vtable_t *client_vtable; -}; - -static apt_bool_t apt_net_client_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg); -static apt_bool_t apt_net_client_task_run(apt_task_t *task); -static apt_bool_t apt_net_client_task_on_destroy(apt_task_t *task); - -/** Create connection task */ -APT_DECLARE(apt_net_client_task_t*) apt_net_client_task_create( - apr_size_t max_connection_count, - void *obj, - const apt_net_client_vtable_t *client_vtable, - apt_task_msg_pool_t *msg_pool, - apr_pool_t *pool) -{ - apt_task_vtable_t *vtable; - apt_net_client_task_t *task; - - task = apr_palloc(pool,sizeof(apt_net_client_task_t)); - task->pool = pool; - task->obj = obj; - task->pollset = NULL; - task->max_connection_count = max_connection_count; - - if(!client_vtable || !client_vtable->on_receive) { - return NULL; - } - task->client_vtable = client_vtable; - - task->base = apt_task_create(task,msg_pool,pool); - if(!task->base) { - return NULL; - } - - vtable = apt_task_vtable_get(task->base); - if(vtable) { - vtable->run = apt_net_client_task_run; - vtable->destroy = apt_net_client_task_on_destroy; - vtable->signal_msg = apt_net_client_task_msg_signal; - } - apt_task_auto_ready_set(task->base,FALSE); - - task->msg_queue = apt_cyclic_queue_create(CYCLIC_QUEUE_DEFAULT_SIZE); - apr_thread_mutex_create(&task->guard,APR_THREAD_MUTEX_UNNESTED,pool); - return task; -} - -/** Virtual destroy handler */ -static apt_bool_t apt_net_client_task_on_destroy(apt_task_t *base) -{ - apt_net_client_task_t *task = apt_task_object_get(base); - if(task->guard) { - apr_thread_mutex_destroy(task->guard); - task->guard = NULL; - } - if(task->msg_queue) { - apt_cyclic_queue_destroy(task->msg_queue); - task->msg_queue = NULL; - } - return TRUE; -} - -/** Destroy connection task. */ -APT_DECLARE(apt_bool_t) apt_net_client_task_destroy(apt_net_client_task_t *task) -{ - return apt_task_destroy(task->base); -} - -/** Start connection task. */ -APT_DECLARE(apt_bool_t) apt_net_client_task_start(apt_net_client_task_t *task) -{ - return apt_task_start(task->base); -} - -/** Terminate connection task. */ -APT_DECLARE(apt_bool_t) apt_net_client_task_terminate(apt_net_client_task_t *task) -{ - return apt_task_terminate(task->base,TRUE); -} - -/** Get task */ -APT_DECLARE(apt_task_t*) apt_net_client_task_base_get(apt_net_client_task_t *task) -{ - return task->base; -} - -/** Get task vtable */ -APT_DECLARE(apt_task_vtable_t*) apt_net_client_task_vtable_get(apt_net_client_task_t *task) -{ - return apt_task_vtable_get(task->base); -} - -/** Get external object */ -APT_DECLARE(void*) apt_net_client_task_object_get(apt_net_client_task_t *task) -{ - return task->obj; -} - -/** Create connection */ -APT_DECLARE(apt_net_client_connection_t*) apt_net_client_connect(apt_net_client_task_t *task, const char *ip, apr_port_t port) -{ - char *local_ip = NULL; - char *remote_ip = NULL; - apr_sockaddr_t *l_sockaddr = NULL; - apr_sockaddr_t *r_sockaddr = NULL; - apt_net_client_connection_t *connection; - apr_pool_t *pool = apt_pool_create(); - if(!pool) { - return NULL; - } - - connection = apr_palloc(pool,sizeof(apt_net_client_connection_t)); - connection->pool = pool; - connection->obj = NULL; - connection->sock = NULL; - - if(apr_sockaddr_info_get(&r_sockaddr,ip,APR_INET,port,0,connection->pool) != APR_SUCCESS) { - apr_pool_destroy(pool); - return NULL; - } - - if(apr_socket_create(&connection->sock,r_sockaddr->family,SOCK_STREAM,APR_PROTO_TCP,connection->pool) != APR_SUCCESS) { - apr_pool_destroy(pool); - return NULL; - } - - apr_socket_opt_set(connection->sock, APR_SO_NONBLOCK, 0); - apr_socket_timeout_set(connection->sock, -1); - apr_socket_opt_set(connection->sock, APR_SO_REUSEADDR, 1); - - if(apr_socket_connect(connection->sock,r_sockaddr) != APR_SUCCESS) { - apr_socket_close(connection->sock); - apr_pool_destroy(pool); - return NULL; - } - - if(apr_socket_addr_get(&l_sockaddr,APR_LOCAL,connection->sock) != APR_SUCCESS) { - apr_socket_close(connection->sock); - apr_pool_destroy(pool); - return NULL; - } - - apr_sockaddr_ip_get(&local_ip,l_sockaddr); - apr_sockaddr_ip_get(&remote_ip,r_sockaddr); - connection->id = apr_psprintf(pool,"%s:%hu <-> %s:%hu", - local_ip,l_sockaddr->port, - remote_ip,r_sockaddr->port); - - memset(&connection->sock_pfd,0,sizeof(apr_pollfd_t)); - connection->sock_pfd.desc_type = APR_POLL_SOCKET; - connection->sock_pfd.reqevents = APR_POLLIN; - connection->sock_pfd.desc.s = connection->sock; - connection->sock_pfd.client_data = connection; - if(apt_pollset_add(task->pollset,&connection->sock_pfd) != TRUE) { - apr_socket_close(connection->sock); - apr_pool_destroy(pool); - return NULL; - } - - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Established TCP Connection %s",connection->id); - return connection; -} - -/** Close connection */ -APT_DECLARE(apt_bool_t) apt_net_client_connection_close(apt_net_client_task_t *task, apt_net_client_connection_t *connection) -{ - if(connection->sock) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close TCP Connection %s",connection->id); - apt_pollset_remove(task->pollset,&connection->sock_pfd); - apr_socket_close(connection->sock); - connection->sock = NULL; - } - return TRUE; -} - -/** Close and destroy connection */ -APT_DECLARE(apt_bool_t) apt_net_client_disconnect(apt_net_client_task_t *task, apt_net_client_connection_t *connection) -{ - apt_net_client_connection_close(task,connection); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy TCP Connection %s",connection->id); - apr_pool_destroy(connection->pool); - return TRUE; -} - -/** Create the pollset */ -static apt_bool_t apt_net_client_task_pollset_create(apt_net_client_task_t *task) -{ - /* create pollset */ - task->pollset = apt_pollset_create((apr_uint32_t)task->max_connection_count, task->pool); - if(!task->pollset) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); - return FALSE; - } - - return TRUE; -} - -/** Destroy the pollset */ -static void apt_net_client_task_pollset_destroy(apt_net_client_task_t *task) -{ - if(task->pollset) { - apt_pollset_destroy(task->pollset); - task->pollset = NULL; - } -} - -static apt_bool_t apt_net_client_task_process(apt_net_client_task_t *task) -{ - apt_bool_t status = TRUE; - apt_bool_t running = TRUE; - apt_task_msg_t *msg; - - do { - apr_thread_mutex_lock(task->guard); - msg = apt_cyclic_queue_pop(task->msg_queue); - apr_thread_mutex_unlock(task->guard); - if(msg) { - status = apt_task_msg_process(task->base,msg); - } - else { - running = FALSE; - } - } - while(running == TRUE); - return status; -} - -static apt_bool_t apt_net_client_task_run(apt_task_t *base) -{ - apt_net_client_task_t *task = apt_task_object_get(base); - apt_bool_t running = TRUE; - apr_status_t status; - apr_int32_t num; - const apr_pollfd_t *ret_pfd; - int i; - - if(!task) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Start Network Client Task"); - return FALSE; - } - - if(apt_net_client_task_pollset_create(task) == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); - return FALSE; - } - - /* explicitly indicate task is ready to process messages */ - apt_task_ready(task->base); - - while(running) { - status = apt_pollset_poll(task->pollset, -1, &num, &ret_pfd); - if(status != APR_SUCCESS) { - continue; - } - for(i = 0; i < num; i++) { - if(apt_pollset_is_wakeup(task->pollset,&ret_pfd[i])) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Control Message"); - if(apt_net_client_task_process(task) == FALSE) { - running = FALSE; - break; - } - continue; - } - - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Message"); - task->client_vtable->on_receive(task,ret_pfd[i].client_data); - } - } - - apt_net_client_task_pollset_destroy(task); - return TRUE; -} - -static apt_bool_t apt_net_client_task_msg_signal(apt_task_t *base, apt_task_msg_t *msg) -{ - apt_bool_t status; - apt_net_client_task_t *task = apt_task_object_get(base); - apr_thread_mutex_lock(task->guard); - status = apt_cyclic_queue_push(task->msg_queue,msg); - apr_thread_mutex_unlock(task->guard); - if(apt_pollset_wakeup(task->pollset) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Control Message"); - status = FALSE; - } - return status; -} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_net_server_task.c b/libs/unimrcp/libs/apr-toolkit/src/apt_net_server_task.c deleted file mode 100644 index 93cc9f5d69..0000000000 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_net_server_task.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright 2008 Arsen Chaloyan - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apt_net_server_task.h" -#include "apt_task.h" -#include "apt_pool.h" -#include "apt_pollset.h" -#include "apt_cyclic_queue.h" -#include "apt_log.h" - - -/** Network server task */ -struct apt_net_server_task_t { - apr_pool_t *pool; - apt_task_t *base; - void *obj; - - apr_size_t max_connection_count; - - apr_thread_mutex_t *guard; - apt_cyclic_queue_t *msg_queue; - apt_pollset_t *pollset; - - /* Listening socket descriptor */ - apr_sockaddr_t *sockaddr; - apr_socket_t *listen_sock; - apr_pollfd_t listen_sock_pfd; - - const apt_net_server_vtable_t *server_vtable; -}; - -static apt_bool_t apt_net_server_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg); -static apt_bool_t apt_net_server_task_run(apt_task_t *task); -static apt_bool_t apt_net_server_task_on_destroy(apt_task_t *task); - -/** Create connection task */ -APT_DECLARE(apt_net_server_task_t*) apt_net_server_task_create( - const char *listen_ip, - apr_port_t listen_port, - apr_size_t max_connection_count, - void *obj, - const apt_net_server_vtable_t *server_vtable, - apt_task_msg_pool_t *msg_pool, - apr_pool_t *pool) -{ - apt_task_vtable_t *vtable; - apt_net_server_task_t *task; - - task = apr_palloc(pool,sizeof(apt_net_server_task_t)); - task->pool = pool; - task->obj = obj; - task->sockaddr = NULL; - task->listen_sock = NULL; - task->pollset = NULL; - task->max_connection_count = max_connection_count; - - apr_sockaddr_info_get(&task->sockaddr,listen_ip,APR_INET,listen_port,0,task->pool); - if(!task->sockaddr) { - return NULL; - } - - if(!server_vtable || !server_vtable->on_connect || - !server_vtable->on_disconnect || !server_vtable->on_receive) { - return NULL; - } - task->server_vtable = server_vtable; - - task->base = apt_task_create(task,msg_pool,pool); - if(!task->base) { - return NULL; - } - - vtable = apt_task_vtable_get(task->base); - if(vtable) { - vtable->run = apt_net_server_task_run; - vtable->destroy = apt_net_server_task_on_destroy; - vtable->signal_msg = apt_net_server_task_msg_signal; - } - apt_task_auto_ready_set(task->base,FALSE); - - task->msg_queue = apt_cyclic_queue_create(CYCLIC_QUEUE_DEFAULT_SIZE); - apr_thread_mutex_create(&task->guard,APR_THREAD_MUTEX_UNNESTED,pool); - return task; -} - -/** Virtual destroy handler */ -static apt_bool_t apt_net_server_task_on_destroy(apt_task_t *base) -{ - apt_net_server_task_t *task = apt_task_object_get(base); - if(task->guard) { - apr_thread_mutex_destroy(task->guard); - task->guard = NULL; - } - if(task->msg_queue) { - apt_cyclic_queue_destroy(task->msg_queue); - task->msg_queue = NULL; - } - return TRUE; -} - -/** Destroy connection task. */ -APT_DECLARE(apt_bool_t) apt_net_server_task_destroy(apt_net_server_task_t *task) -{ - return apt_task_destroy(task->base); -} - -/** Start connection task. */ -APT_DECLARE(apt_bool_t) apt_net_server_task_start(apt_net_server_task_t *task) -{ - return apt_task_start(task->base); -} - -/** Terminate connection task. */ -APT_DECLARE(apt_bool_t) apt_net_server_task_terminate(apt_net_server_task_t *task) -{ - return apt_task_terminate(task->base,TRUE); -} - -/** Get task */ -APT_DECLARE(apt_task_t*) apt_net_server_task_base_get(apt_net_server_task_t *task) -{ - return task->base; -} - -/** Get task vtable */ -APT_DECLARE(apt_task_vtable_t*) apt_net_server_task_vtable_get(apt_net_server_task_t *task) -{ - return apt_task_vtable_get(task->base); -} - -/** Get external object */ -APT_DECLARE(void*) apt_net_server_task_object_get(apt_net_server_task_t *task) -{ - return task->obj; -} - - -/** Create listening socket and add to pollset */ -static apt_bool_t apt_net_server_task_listen_socket_create(apt_net_server_task_t *task) -{ - apr_status_t status; - if(!task->sockaddr) { - return FALSE; - } - - /* create listening socket */ - status = apr_socket_create(&task->listen_sock, task->sockaddr->family, SOCK_STREAM, APR_PROTO_TCP, task->pool); - if(status != APR_SUCCESS) { - return FALSE; - } - - apr_socket_opt_set(task->listen_sock, APR_SO_NONBLOCK, 0); - apr_socket_timeout_set(task->listen_sock, -1); - apr_socket_opt_set(task->listen_sock, APR_SO_REUSEADDR, 1); - - status = apr_socket_bind(task->listen_sock, task->sockaddr); - if(status != APR_SUCCESS) { - apr_socket_close(task->listen_sock); - task->listen_sock = NULL; - return FALSE; - } - status = apr_socket_listen(task->listen_sock, SOMAXCONN); - if(status != APR_SUCCESS) { - apr_socket_close(task->listen_sock); - task->listen_sock = NULL; - return FALSE; - } - - memset(&task->listen_sock_pfd,0,sizeof(apr_pollfd_t)); - task->listen_sock_pfd.desc_type = APR_POLL_SOCKET; - task->listen_sock_pfd.reqevents = APR_POLLIN; - task->listen_sock_pfd.desc.s = task->listen_sock; - task->listen_sock_pfd.client_data = task->listen_sock; - if(apt_pollset_add(task->pollset, &task->listen_sock_pfd) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add Listen Socket to Pollset"); - apr_socket_close(task->listen_sock); - task->listen_sock = NULL; - } - - return TRUE; -} - -/** Remove from pollset and destroy listening socket */ -static void apt_net_server_task_listen_socket_destroy(apt_net_server_task_t *task) -{ - apt_pollset_remove(task->pollset,&task->listen_sock_pfd); - - if(task->listen_sock) { - apr_socket_close(task->listen_sock); - task->listen_sock = NULL; - } -} - -/** Create the pollset */ -static apt_bool_t apt_net_server_task_pollset_create(apt_net_server_task_t *task) -{ - /* create pollset */ - task->pollset = apt_pollset_create((apr_uint32_t)task->max_connection_count + 1, task->pool); - if(!task->pollset) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); - return FALSE; - } - - /* create listening socket */ - if(apt_net_server_task_listen_socket_create(task) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Listen Socket"); - } - - return TRUE; -} - -/** Destroy the pollset */ -static void apt_net_server_task_pollset_destroy(apt_net_server_task_t *task) -{ - apt_net_server_task_listen_socket_destroy(task); - if(task->pollset) { - apt_pollset_destroy(task->pollset); - task->pollset = NULL; - } -} - -static apt_bool_t apt_net_server_task_process(apt_net_server_task_t *task) -{ - apt_bool_t status = TRUE; - apt_bool_t running = TRUE; - apt_task_msg_t *msg; - - do { - apr_thread_mutex_lock(task->guard); - msg = apt_cyclic_queue_pop(task->msg_queue); - apr_thread_mutex_unlock(task->guard); - if(msg) { - status = apt_task_msg_process(task->base,msg); - } - else { - running = FALSE; - } - } - while(running == TRUE); - return status; -} - -static apt_bool_t apt_net_server_task_accept(apt_net_server_task_t *task) -{ - char *local_ip = NULL; - char *remote_ip = NULL; - apr_sockaddr_t *l_sockaddr = NULL; - apr_sockaddr_t *r_sockaddr = NULL; - apt_net_server_connection_t *connection; - apr_pool_t *pool = apt_pool_create(); - if(!pool) { - return FALSE; - } - - connection = apr_palloc(pool,sizeof(apt_net_server_connection_t)); - connection->pool = pool; - connection->obj = NULL; - connection->sock = NULL; - connection->client_ip = NULL; - - if(apr_socket_accept(&connection->sock,task->listen_sock,connection->pool) != APR_SUCCESS) { - apr_pool_destroy(pool); - return FALSE; - } - - if(apr_socket_addr_get(&l_sockaddr,APR_LOCAL,connection->sock) != APR_SUCCESS || - apr_socket_addr_get(&r_sockaddr,APR_REMOTE,connection->sock) != APR_SUCCESS) { - apr_pool_destroy(pool); - return FALSE; - } - - apr_sockaddr_ip_get(&local_ip,l_sockaddr); - apr_sockaddr_ip_get(&remote_ip,r_sockaddr); - connection->client_ip = remote_ip; - connection->id = apr_psprintf(pool,"%s:%hu <-> %s:%hu", - local_ip,l_sockaddr->port, - remote_ip,r_sockaddr->port); - - memset(&connection->sock_pfd,0,sizeof(apr_pollfd_t)); - connection->sock_pfd.desc_type = APR_POLL_SOCKET; - connection->sock_pfd.reqevents = APR_POLLIN; - connection->sock_pfd.desc.s = connection->sock; - connection->sock_pfd.client_data = connection; - if(apt_pollset_add(task->pollset,&connection->sock_pfd) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add to Pollset"); - apr_socket_close(connection->sock); - apr_pool_destroy(pool); - return FALSE; - } - - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Accepted TCP Connection %s",connection->id); - task->server_vtable->on_connect(task,connection); - return TRUE; -} - -static apt_bool_t apt_net_server_task_run(apt_task_t *base) -{ - apt_net_server_task_t *task = apt_task_object_get(base); - apt_bool_t running = TRUE; - apr_status_t status; - apr_int32_t num; - const apr_pollfd_t *ret_pfd; - int i; - - if(!task) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Start Network Server Task"); - return FALSE; - } - - if(apt_net_server_task_pollset_create(task) == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); - return FALSE; - } - - /* explicitly indicate task is ready to process messages */ - apt_task_ready(task->base); - - while(running) { - status = apt_pollset_poll(task->pollset, -1, &num, &ret_pfd); - if(status != APR_SUCCESS) { - continue; - } - for(i = 0; i < num; i++) { - if(ret_pfd[i].desc.s == task->listen_sock) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Accept Connection"); - apt_net_server_task_accept(task); - continue; - } - if(apt_pollset_is_wakeup(task->pollset,&ret_pfd[i])) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Control Message"); - if(apt_net_server_task_process(task) == FALSE) { - running = FALSE; - break; - } - continue; - } - - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Message"); - task->server_vtable->on_receive(task,ret_pfd[i].client_data); - } - } - - apt_net_server_task_pollset_destroy(task); - return TRUE; -} - -static apt_bool_t apt_net_server_task_msg_signal(apt_task_t *base, apt_task_msg_t *msg) -{ - apt_bool_t status; - apt_net_server_task_t *task = apt_task_object_get(base); - apr_thread_mutex_lock(task->guard); - status = apt_cyclic_queue_push(task->msg_queue,msg); - apr_thread_mutex_unlock(task->guard); - if(apt_pollset_wakeup(task->pollset) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Control Message"); - status = FALSE; - } - return status; -} - - -/** Close connection */ -APT_DECLARE(apt_bool_t) apt_net_server_connection_close(apt_net_server_task_t *task, apt_net_server_connection_t *connection) -{ - if(connection->sock) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close TCP Connection %s",connection->id); - apt_pollset_remove(task->pollset,&connection->sock_pfd); - apr_socket_close(connection->sock); - connection->sock = NULL; - task->server_vtable->on_disconnect(task,connection); - } - return TRUE; -} - -/** Destroy connection */ -APT_DECLARE(void) apt_net_server_connection_destroy(apt_net_server_connection_t *connection) -{ - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy TCP Connection %s",connection->id); - apr_pool_destroy(connection->pool); -} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_nlsml_doc.c b/libs/unimrcp/libs/apr-toolkit/src/apt_nlsml_doc.c index 4e4ae82124..af46ab7342 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_nlsml_doc.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_nlsml_doc.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,9 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_nlsml_doc.c 1655 2010-04-16 18:36:27Z achaloyan $ */ #include "apt_nlsml_doc.h" +#include "apt_log.h" /** Load NLSML document */ APT_DECLARE(apr_xml_doc*) nlsml_doc_load(const apt_str_t *data, apr_pool_t *pool) @@ -26,21 +29,25 @@ APT_DECLARE(apr_xml_doc*) nlsml_doc_load(const apt_str_t *data, apr_pool_t *pool /* create XML parser */ parser = apr_xml_parser_create(pool); if(apr_xml_parser_feed(parser,data->buf,data->length) != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to feed NLSML input to the parser"); return NULL; } /* done with XML tree creation */ if(apr_xml_parser_done(parser,&doc) != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to terminate NLSML parsing"); return NULL; } if(!doc || !doc->root) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No NLSML root element"); return NULL; } root = doc->root; /* NLSML validity check: root element must be */ if(strcmp(root->name,"result") != 0) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unexpected NLSML root element <%s>",root->name); return NULL; } diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_obj_list.c b/libs/unimrcp/libs/apr-toolkit/src/apt_obj_list.c index a1d320a8aa..69f006adee 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_obj_list.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_obj_list.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_obj_list.c 1708 2010-05-24 17:03:25Z achaloyan $ */ #ifdef WIN32 @@ -65,7 +67,7 @@ APT_DECLARE(void*) apt_list_pop_front(apt_obj_list_t *list) return elem->obj; } -APT_DECLARE(void*) apt_list_head(apt_obj_list_t *list) +APT_DECLARE(void*) apt_list_head(const apt_obj_list_t *list) { apt_list_elem_t *elem; if(APR_RING_EMPTY(&list->head,apt_list_elem_t,link)) { @@ -75,7 +77,7 @@ APT_DECLARE(void*) apt_list_head(apt_obj_list_t *list) return elem->obj; } -APT_DECLARE(void*) apt_obj_list_tail(apt_obj_list_t *list) +APT_DECLARE(void*) apt_obj_list_tail(const apt_obj_list_t *list) { apt_list_elem_t *elem; if(APR_RING_EMPTY(&list->head,apt_list_elem_t,link)) { @@ -85,7 +87,7 @@ APT_DECLARE(void*) apt_obj_list_tail(apt_obj_list_t *list) return elem->obj; } -APT_DECLARE(apt_list_elem_t*) apt_list_first_elem_get(apt_obj_list_t *list) +APT_DECLARE(apt_list_elem_t*) apt_list_first_elem_get(const apt_obj_list_t *list) { if(APR_RING_EMPTY(&list->head,apt_list_elem_t,link)) { return NULL; @@ -93,7 +95,7 @@ APT_DECLARE(apt_list_elem_t*) apt_list_first_elem_get(apt_obj_list_t *list) return APR_RING_FIRST(&list->head); } -APT_DECLARE(apt_list_elem_t*) apt_list_last_elem_get(apt_obj_list_t *list) +APT_DECLARE(apt_list_elem_t*) apt_list_last_elem_get(const apt_obj_list_t *list) { if(APR_RING_EMPTY(&list->head,apt_list_elem_t,link)) { return NULL; @@ -101,7 +103,7 @@ APT_DECLARE(apt_list_elem_t*) apt_list_last_elem_get(apt_obj_list_t *list) return APR_RING_LAST(&list->head); } -APT_DECLARE(apt_list_elem_t*) apt_list_next_elem_get(apt_obj_list_t *list, apt_list_elem_t *elem) +APT_DECLARE(apt_list_elem_t*) apt_list_next_elem_get(const apt_obj_list_t *list, apt_list_elem_t *elem) { apt_list_elem_t *next_elem = APR_RING_NEXT(elem,link); if(next_elem == APR_RING_SENTINEL(&list->head,apt_list_elem_t,link)) { @@ -110,7 +112,7 @@ APT_DECLARE(apt_list_elem_t*) apt_list_next_elem_get(apt_obj_list_t *list, apt_l return next_elem; } -APT_DECLARE(apt_list_elem_t*) apt_list_prev_elem_get(apt_obj_list_t *list, apt_list_elem_t *elem) +APT_DECLARE(apt_list_elem_t*) apt_list_prev_elem_get(const apt_obj_list_t *list, apt_list_elem_t *elem) { apt_list_elem_t *prev_elem = APR_RING_PREV(elem,link); if(prev_elem == APR_RING_SENTINEL(&list->head,apt_list_elem_t,link)) { @@ -137,7 +139,7 @@ APT_DECLARE(apt_list_elem_t*) apt_list_elem_remove(apt_obj_list_t *list, apt_lis return next_elem; } -APT_DECLARE(apt_bool_t) apt_list_is_empty(apt_obj_list_t *list) +APT_DECLARE(apt_bool_t) apt_list_is_empty(const apt_obj_list_t *list) { if(APR_RING_EMPTY(&list->head,apt_list_elem_t,link)) { return TRUE; @@ -145,7 +147,7 @@ APT_DECLARE(apt_bool_t) apt_list_is_empty(apt_obj_list_t *list) return FALSE; } -APT_DECLARE(void*) apt_list_elem_object_get(apt_list_elem_t *elem) +APT_DECLARE(void*) apt_list_elem_object_get(const apt_list_elem_t *elem) { return elem->obj; } diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_pair.c b/libs/unimrcp/libs/apr-toolkit/src/apt_pair.c index 29eb60e4d9..05c05c9e7e 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_pair.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_pair.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_pair.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "apt_pair.h" diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_poller_task.c b/libs/unimrcp/libs/apr-toolkit/src/apt_poller_task.c new file mode 100644 index 0000000000..99a581667b --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_poller_task.c @@ -0,0 +1,271 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_poller_task.c 1708 2010-05-24 17:03:25Z achaloyan $ + */ + +#include "apt_poller_task.h" +#include "apt_task.h" +#include "apt_pool.h" +#include "apt_cyclic_queue.h" +#include "apt_log.h" + + +/** Poller task */ +struct apt_poller_task_t { + apr_pool_t *pool; + apt_task_t *base; + + void *obj; + apt_poll_signal_f signal_handler; + + apr_thread_mutex_t *guard; + apt_cyclic_queue_t *msg_queue; + apt_pollset_t *pollset; + apt_timer_queue_t *timer_queue; +}; + +static apt_bool_t apt_poller_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg); +static apt_bool_t apt_poller_task_run(apt_task_t *task); +static apt_bool_t apt_poller_task_on_destroy(apt_task_t *task); + + +/** Create poller task */ +APT_DECLARE(apt_poller_task_t*) apt_poller_task_create( + apr_size_t max_pollset_size, + apt_poll_signal_f signal_handler, + void *obj, + apt_task_msg_pool_t *msg_pool, + apr_pool_t *pool) +{ + apt_task_vtable_t *vtable; + apt_poller_task_t *task; + + if(!signal_handler) { + return NULL; + } + + task = apr_palloc(pool,sizeof(apt_poller_task_t)); + task->pool = pool; + task->obj = obj; + task->pollset = NULL; + task->signal_handler = signal_handler; + + task->pollset = apt_pollset_create((apr_uint32_t)max_pollset_size,pool); + if(!task->pollset) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); + return NULL; + } + + task->base = apt_task_create(task,msg_pool,pool); + if(!task->base) { + apt_pollset_destroy(task->pollset); + return NULL; + } + + vtable = apt_task_vtable_get(task->base); + if(vtable) { + vtable->run = apt_poller_task_run; + vtable->destroy = apt_poller_task_on_destroy; + vtable->signal_msg = apt_poller_task_msg_signal; + } + apt_task_auto_ready_set(task->base,FALSE); + + task->msg_queue = apt_cyclic_queue_create(CYCLIC_QUEUE_DEFAULT_SIZE); + apr_thread_mutex_create(&task->guard,APR_THREAD_MUTEX_UNNESTED,pool); + + task->timer_queue = apt_timer_queue_create(pool); + return task; +} + +/** Destroy poller task */ +APT_DECLARE(apt_bool_t) apt_poller_task_destroy(apt_poller_task_t *task) +{ + return apt_task_destroy(task->base); +} + +/** Cleanup poller task */ +APT_DECLARE(void) apt_poller_task_cleanup(apt_poller_task_t *task) +{ + if(task->pollset) { + apt_pollset_destroy(task->pollset); + task->pollset = NULL; + } + if(task->guard) { + apr_thread_mutex_destroy(task->guard); + task->guard = NULL; + } + if(task->msg_queue) { + apt_cyclic_queue_destroy(task->msg_queue); + task->msg_queue = NULL; + } +} + +/** Virtual destroy handler */ +static apt_bool_t apt_poller_task_on_destroy(apt_task_t *base) +{ + apt_poller_task_t *task = apt_task_object_get(base); + apt_poller_task_cleanup(task); + return TRUE; +} + + +/** Start poller task */ +APT_DECLARE(apt_bool_t) apt_poller_task_start(apt_poller_task_t *task) +{ + return apt_task_start(task->base); +} + +/** Terminate poller task */ +APT_DECLARE(apt_bool_t) apt_poller_task_terminate(apt_poller_task_t *task) +{ + return apt_task_terminate(task->base,TRUE); +} + +/** Get task */ +APT_DECLARE(apt_task_t*) apt_poller_task_base_get(const apt_poller_task_t *task) +{ + return task->base; +} + +/** Get task vtable */ +APT_DECLARE(apt_task_vtable_t*) apt_poller_task_vtable_get(apt_poller_task_t *task) +{ + return apt_task_vtable_get(task->base); +} + +/** Get external object */ +APT_DECLARE(void*) apt_poller_task_object_get(const apt_poller_task_t *task) +{ + return task->obj; +} + +/** Get pollset */ +APT_DECLARE(apt_pollset_t*) apt_poller_task_pollset_get(const apt_poller_task_t *task) +{ + return task->pollset; +} + +/** Create timer */ +APT_DECLARE(apt_timer_t*) apt_poller_task_timer_create( + apt_poller_task_t *task, + apt_timer_proc_f proc, + void *obj, + apr_pool_t *pool) +{ + return apt_timer_create(task->timer_queue,proc,obj,pool); +} + +static apt_bool_t apt_poller_task_wakeup_process(apt_poller_task_t *task) +{ + apt_bool_t running = TRUE; + apt_task_msg_t *msg; + + do { + apr_thread_mutex_lock(task->guard); + msg = apt_cyclic_queue_pop(task->msg_queue); + apr_thread_mutex_unlock(task->guard); + if(msg) { + apt_task_msg_process(task->base,msg); + } + else { + running = FALSE; + } + } + while(running == TRUE); + return TRUE; +} + +static apt_bool_t apt_poller_task_run(apt_task_t *base) +{ + apt_poller_task_t *task = apt_task_object_get(base); + apt_bool_t *running; + apr_status_t status; + apr_int32_t num; + const apr_pollfd_t *ret_pfd; + apr_interval_time_t timeout; + apr_uint32_t queue_timeout; + apr_time_t time_now, time_last = 0; + int i; + const char *task_name; + + if(!task) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Start Poller Task"); + return FALSE; + } + task_name = apt_task_name_get(task->base), + + running = apt_task_running_flag_get(task->base); + if(!running) { + return FALSE; + } + + /* explicitly indicate task is ready to process messages */ + apt_task_ready(task->base); + + while(*running) { + if(apt_timer_queue_timeout_get(task->timer_queue,&queue_timeout) == TRUE) { + timeout = queue_timeout * 1000; + time_last = apr_time_now(); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Wait for Messages [%s] timeout [%u]", + task_name, queue_timeout); + } + else { + timeout = -1; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Wait for Messages [%s]",task_name); + } + status = apt_pollset_poll(task->pollset, timeout, &num, &ret_pfd); + if(status != APR_SUCCESS && status != APR_TIMEUP) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Poll [%s] status: %d",task_name,status); + continue; + } + for(i = 0; i < num; i++) { + if(apt_pollset_is_wakeup(task->pollset,&ret_pfd[i])) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Poller Wakeup [%s]",task_name); + apt_poller_task_wakeup_process(task); + if(*running == FALSE) { + break; + } + continue; + } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Signalled Descriptor [%s]",task_name); + task->signal_handler(task->obj,&ret_pfd[i]); + } + + if(timeout != -1) { + time_now = apr_time_now(); + if(time_now > time_last) { + apt_timer_queue_advance(task->timer_queue,(apr_uint32_t)((time_now - time_last)/1000)); + } + } + } + + return TRUE; +} + +static apt_bool_t apt_poller_task_msg_signal(apt_task_t *base, apt_task_msg_t *msg) +{ + apt_bool_t status; + apt_poller_task_t *task = apt_task_object_get(base); + apr_thread_mutex_lock(task->guard); + status = apt_cyclic_queue_push(task->msg_queue,msg); + apr_thread_mutex_unlock(task->guard); + if(apt_pollset_wakeup(task->pollset) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Control Message"); + status = FALSE; + } + return status; +} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_pollset.c b/libs/unimrcp/libs/apr-toolkit/src/apt_pollset.c index 87db7f8c04..7592aff663 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_pollset.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_pollset.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_pollset.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_pool.c b/libs/unimrcp/libs/apr-toolkit/src/apt_pool.c index 8f75400836..8cbe247b9b 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_pool.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_pool.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_pool.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "apt_pool.h" diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_string_table.c b/libs/unimrcp/libs/apr-toolkit/src/apt_string_table.c index cc0c6be73b..bc96c51c49 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_string_table.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_string_table.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_string_table.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_task.c b/libs/unimrcp/libs/apr-toolkit/src/apt_task.c index 9d7014d592..5ce74e137f 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_task.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_task.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_task.c 1696 2010-05-20 15:44:16Z achaloyan $ */ #include @@ -23,10 +25,10 @@ /** Internal states of the task */ typedef enum { TASK_STATE_IDLE, /**< no task activity */ - TASK_STATE_START_REQUESTED, /**< task start is requested and is in progress */ + TASK_STATE_START_REQUESTED, /**< start of the task has been requested, but it's not running yet */ TASK_STATE_RUNNING, /**< task is running */ - TASK_STATE_TERMINATE_REQUESTED /**< task termination is requested and is in progress */ -} apt_task_state_t; + TASK_STATE_TERMINATE_REQUESTED /**< termination of the task has been requested, but it's still running */ +} apt_task_state_e; struct apt_task_t { void *obj; /* external object associated with the task */ @@ -34,18 +36,22 @@ struct apt_task_t { apt_task_msg_pool_t *msg_pool; /* message pool to allocate task messages from */ apr_thread_mutex_t *data_guard; /* mutex to protect task data */ apr_thread_t *thread_handle; /* thread handle */ - apt_task_state_t state; /* current task state */ + apt_task_state_e state; /* current task state */ apt_task_vtable_t vtable; /* table of virtual methods */ apt_task_t *parent_task; /* parent (master) task */ apt_obj_list_t *child_tasks; /* list of the child (slave) tasks */ apr_size_t pending_start; /* number of pending start requests */ apr_size_t pending_term; /* number of pending terminate requests */ + apt_bool_t running; /* task is running (TRUE if even terminate has already been requested) */ apt_bool_t auto_ready; /* if TRUE, task is implicitly ready to process messages */ const char *name; /* name of the task */ }; static void* APR_THREAD_FUNC apt_task_run(apr_thread_t *thread_handle, void *data); +static APR_INLINE void apt_task_vtable_reset(apt_task_vtable_t *vtable); static apt_bool_t apt_task_terminate_request(apt_task_t *task); +static void apt_task_start_complete_raise(apt_task_t *task); +static void apt_task_terminate_complete_raise(apt_task_t *task); APT_DECLARE(apt_task_t*) apt_task_create( @@ -98,7 +104,7 @@ APT_DECLARE(apt_bool_t) apt_task_destroy(apt_task_t *task) apt_task_wait_till_complete(task); } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Destroy %s",task->name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Destroy Task [%s]",task->name); if(task->vtable.destroy) { task->vtable.destroy(task); } @@ -120,7 +126,7 @@ APT_DECLARE(apt_bool_t) apt_task_start(apt_task_t *task) if(task->state == TASK_STATE_IDLE) { apr_status_t rv; task->state = TASK_STATE_START_REQUESTED; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Start %s",task->name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Start Task [%s]",task->name); if(task->vtable.start) { /* raise virtual start method */ task->vtable.start(task); @@ -152,7 +158,7 @@ APT_DECLARE(apt_bool_t) apt_task_terminate(apt_task_t *task, apt_bool_t wait_til if(task->state == TASK_STATE_TERMINATE_REQUESTED) { /* raise virtual terminate method */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Terminate %s",task->name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Terminate Task [%s]",task->name); if(task->vtable.terminate) { status = task->vtable.terminate(task); } @@ -180,17 +186,17 @@ APT_DECLARE(void) apt_task_delay(apr_size_t msec) apr_sleep(1000*msec); } -APT_DECLARE(apt_task_t*) apt_task_parent_get(apt_task_t *task) +APT_DECLARE(apt_task_t*) apt_task_parent_get(const apt_task_t *task) { return task->parent_task; } -APT_DECLARE(apr_pool_t*) apt_task_pool_get(apt_task_t *task) +APT_DECLARE(apr_pool_t*) apt_task_pool_get(const apt_task_t *task) { return task->pool; } -APT_DECLARE(void*) apt_task_object_get(apt_task_t *task) +APT_DECLARE(void*) apt_task_object_get(const apt_task_t *task) { return task->obj; } @@ -205,7 +211,7 @@ APT_DECLARE(void) apt_task_name_set(apt_task_t *task, const char *name) task->name = name; } -APT_DECLARE(const char*) apt_task_name_get(apt_task_t *task) +APT_DECLARE(const char*) apt_task_name_get(const apt_task_t *task) { return task->name; } @@ -220,6 +226,8 @@ APT_DECLARE(apt_task_msg_t*) apt_task_msg_get(apt_task_t *task) APT_DECLARE(apt_bool_t) apt_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Message to [%s] [%d;%d]", + task->name, msg->type, msg->sub_type); if(task->vtable.signal_msg) { return task->vtable.signal_msg(task,msg); } @@ -238,74 +246,48 @@ APT_DECLARE(apt_bool_t) apt_task_msg_parent_signal(apt_task_t *task, apt_task_ms } -APT_DECLARE(apt_bool_t) apt_core_task_msg_process(apt_task_t *task, apt_task_msg_t *msg) +static apt_bool_t apt_core_task_msg_process(apt_task_t *task, apt_task_msg_t *msg) { - apt_bool_t running = TRUE; switch(msg->sub_type) { - case CORE_TASK_MSG_START_COMPLETE: + case CORE_TASK_MSG_START_COMPLETE: { - if(!task->pending_start) { - /* error case, no pending start */ - break; - } - task->pending_start--; - if(!task->pending_start) { - if(task->vtable.on_start_complete) { - task->vtable.on_start_complete(task); - } - if(task->parent_task) { - /* signal start-complete message */ - apt_task_msg_signal(task->parent_task,msg); - } - } + apt_task_start_request_remove(task); break; } case CORE_TASK_MSG_TERMINATE_REQUEST: { apt_task_child_terminate(task); if(!task->pending_term) { - running = FALSE; + task->running = FALSE; } break; } case CORE_TASK_MSG_TERMINATE_COMPLETE: { - if(!task->pending_term) { - /* error case, no pending terminate */ - break; - } - task->pending_term--; - if(!task->pending_term) { - if(task->vtable.on_terminate_complete) { - task->vtable.on_terminate_complete(task); - } - if(task->parent_task) { - /* signal terminate-complete message */ - apt_task_msg_signal(task->parent_task,msg); - } - running = FALSE; - } + apt_task_terminate_request_remove(task); break; } default: break; } - return running; + return TRUE; } APT_DECLARE(apt_bool_t) apt_task_msg_process(apt_task_t *task, apt_task_msg_t *msg) { - apt_bool_t running = TRUE; + apt_bool_t status = FALSE; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Message [%s] [%d;%d]", + task->name, msg->type, msg->sub_type); if(msg->type == TASK_MSG_CORE) { - running = apt_core_task_msg_process(task,msg); + status = apt_core_task_msg_process(task,msg); } else { if(task->vtable.process_msg) { - task->vtable.process_msg(task,msg); + status = task->vtable.process_msg(task,msg); } } apt_task_msg_release(msg); - return running; + return status; } static apt_bool_t apt_task_terminate_request(apt_task_t *task) @@ -325,6 +307,9 @@ APT_DECLARE(apt_bool_t) apt_task_child_start(apt_task_t *task) apt_task_t *child_task = NULL; apt_list_elem_t *elem = apt_list_first_elem_get(task->child_tasks); task->pending_start = 0; + if(task->vtable.on_start_request) { + task->vtable.on_start_request(task); + } /* walk through the list of the child tasks and start them */ while(elem) { child_task = apt_list_elem_object_get(elem); @@ -338,18 +323,7 @@ APT_DECLARE(apt_bool_t) apt_task_child_start(apt_task_t *task) if(!task->pending_start) { /* no child task to start, just raise start-complete event */ - if(task->vtable.on_start_complete) { - task->vtable.on_start_complete(task); - } - if(task->parent_task) { - if(task->msg_pool) { - apt_task_msg_t *msg = apt_task_msg_acquire(task->msg_pool); - /* signal start-complete message */ - msg->type = TASK_MSG_CORE; - msg->sub_type = CORE_TASK_MSG_START_COMPLETE; - apt_task_msg_signal(task->parent_task,msg); - } - } + apt_task_start_complete_raise(task); } return TRUE; } @@ -359,6 +333,9 @@ APT_DECLARE(apt_bool_t) apt_task_child_terminate(apt_task_t *task) apt_task_t *child_task = NULL; apt_list_elem_t *elem = apt_list_first_elem_get(task->child_tasks); task->pending_term = 0; + if(task->vtable.on_terminate_request) { + task->vtable.on_terminate_request(task); + } /* walk through the list of the child tasks and terminate them */ while(elem) { child_task = apt_list_elem_object_get(elem); @@ -380,20 +357,7 @@ APT_DECLARE(apt_bool_t) apt_task_child_terminate(apt_task_t *task) if(!task->pending_term) { /* no child task to terminate, just raise terminate-complete event */ - if(task->vtable.on_terminate_complete) { - task->vtable.on_terminate_complete(task); - } -#ifdef ENABLE_SIMULT_TASK_TERMINATION - if(task->parent_task) { - if(task->msg_pool) { - apt_task_msg_t *msg = apt_task_msg_acquire(task->msg_pool); - /* signal terminate-complete message */ - msg->type = TASK_MSG_CORE; - msg->sub_type = CORE_TASK_MSG_TERMINATE_COMPLETE; - apt_task_msg_signal(task->parent_task,msg); - } - } -#endif + apt_task_terminate_complete_raise(task); } return TRUE; } @@ -414,6 +378,85 @@ APT_DECLARE(apt_bool_t) apt_task_ready(apt_task_t *task) return TRUE; } +APT_DECLARE(apt_bool_t*) apt_task_running_flag_get(apt_task_t *task) +{ + return &task->running; +} + +APT_DECLARE(apt_bool_t) apt_task_start_request_add(apt_task_t *task) +{ + task->pending_start++; + return TRUE; +} + +APT_DECLARE(apt_bool_t) apt_task_start_request_remove(apt_task_t *task) +{ + if(!task->pending_start) { + /* error case, no pending start */ + return FALSE; + } + task->pending_start--; + if(!task->pending_start) { + apt_task_start_complete_raise(task); + } + return TRUE; +} + +APT_DECLARE(apt_bool_t) apt_task_terminate_request_add(apt_task_t *task) +{ + task->pending_term++; + return TRUE; +} + +APT_DECLARE(apt_bool_t) apt_task_terminate_request_remove(apt_task_t *task) +{ + if(!task->pending_term) { + /* error case, no pending terminate */ + return FALSE; + } + task->pending_term--; + if(!task->pending_term) { + apt_task_terminate_complete_raise(task); + task->running = FALSE; + } + return TRUE; +} + +static void apt_task_start_complete_raise(apt_task_t *task) +{ + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Task Started [%s]",task->name); + if(task->vtable.on_start_complete) { + task->vtable.on_start_complete(task); + } + if(task->parent_task) { + if(task->msg_pool) { + apt_task_msg_t *msg = apt_task_msg_acquire(task->msg_pool); + /* signal start-complete message */ + msg->type = TASK_MSG_CORE; + msg->sub_type = CORE_TASK_MSG_START_COMPLETE; + apt_task_msg_signal(task->parent_task,msg); + } + } +} + +static void apt_task_terminate_complete_raise(apt_task_t *task) +{ + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Task Terminated [%s]",task->name); + if(task->vtable.on_terminate_complete) { + task->vtable.on_terminate_complete(task); + } +#ifdef ENABLE_SIMULT_TASK_TERMINATION + if(task->parent_task) { + if(task->msg_pool) { + apt_task_msg_t *msg = apt_task_msg_acquire(task->msg_pool); + /* signal terminate-complete message */ + msg->type = TASK_MSG_CORE; + msg->sub_type = CORE_TASK_MSG_TERMINATE_COMPLETE; + apt_task_msg_signal(task->parent_task,msg); + } + } +#endif +} static void* APR_THREAD_FUNC apt_task_run(apr_thread_t *thread_handle, void *data) { @@ -425,6 +468,7 @@ static void* APR_THREAD_FUNC apt_task_run(apr_thread_t *thread_handle, void *dat } apr_thread_mutex_lock(task->data_guard); task->state = TASK_STATE_RUNNING; + task->running = TRUE; apr_thread_mutex_unlock(task->data_guard); if(task->auto_ready == TRUE) { @@ -439,6 +483,7 @@ static void* APR_THREAD_FUNC apt_task_run(apr_thread_t *thread_handle, void *dat apr_thread_mutex_lock(task->data_guard); task->state = TASK_STATE_IDLE; + task->running = FALSE; apr_thread_mutex_unlock(task->data_guard); /* raise post-run event */ if(task->vtable.on_post_run) { @@ -448,3 +493,19 @@ static void* APR_THREAD_FUNC apt_task_run(apr_thread_t *thread_handle, void *dat apr_thread_exit(thread_handle,APR_SUCCESS); return NULL; } + +static APR_INLINE void apt_task_vtable_reset(apt_task_vtable_t *vtable) +{ + vtable->destroy = NULL; + vtable->start = NULL; + vtable->terminate = NULL; + vtable->run = NULL; + vtable->signal_msg = NULL; + vtable->process_msg = NULL; + vtable->on_pre_run = NULL; + vtable->on_post_run = NULL; + vtable->on_start_request = NULL; + vtable->on_start_complete = NULL; + vtable->on_terminate_request = NULL; + vtable->on_terminate_complete = NULL; +} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_task_msg.c b/libs/unimrcp/libs/apr-toolkit/src/apt_task_msg.c index fdff519fb1..bb64cea6ef 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_task_msg.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_task_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_task_msg.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_test_suite.c b/libs/unimrcp/libs/apr-toolkit/src/apt_test_suite.c index 6a5d18ad7d..afaf29f0ce 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_test_suite.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_test_suite.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_test_suite.c 1708 2010-05-24 17:03:25Z achaloyan $ */ #include "apt_pool.h" @@ -61,7 +63,7 @@ APT_DECLARE(apt_bool_t) apt_test_framework_suite_add(apt_test_framework_t *frame return (apt_list_push_back(framework->suites,suite,suite->pool) ? TRUE : FALSE); } -APT_DECLARE(apr_pool_t*) apt_test_framework_pool_get(apt_test_framework_t *framework) +APT_DECLARE(apr_pool_t*) apt_test_framework_pool_get(const apt_test_framework_t *framework) { return framework->pool; } diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_text_message.c b/libs/unimrcp/libs/apr-toolkit/src/apt_text_message.c new file mode 100644 index 0000000000..1e0d901b43 --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_text_message.c @@ -0,0 +1,448 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_text_message.c 1671 2010-04-28 19:50:29Z achaloyan $ + */ + +#include "apt_text_message.h" +#include "apt_log.h" + +/** Stage of text message processing (parsing/generation) */ +typedef enum { + APT_MESSAGE_STAGE_START_LINE, + APT_MESSAGE_STAGE_HEADER, + APT_MESSAGE_STAGE_BODY +} apt_message_stage_e; + + +/** Text message parser */ +struct apt_message_parser_t { + const apt_message_parser_vtable_t *vtable; + void *obj; + apr_pool_t *pool; + apt_message_context_t context; + apr_size_t content_length; + apt_message_stage_e stage; + apt_bool_t skip_lf; + apt_bool_t verbose; +}; + +/** Text message generator */ +struct apt_message_generator_t { + const apt_message_generator_vtable_t *vtable; + void *obj; + apr_pool_t *pool; + apt_message_context_t context; + apr_size_t content_length; + apt_message_stage_e stage; + apt_bool_t verbose; +}; + +/** Parse individual header field (name-value pair) */ +APT_DECLARE(apt_header_field_t*) apt_header_field_parse(apt_text_stream_t *stream, apr_pool_t *pool) +{ + apr_size_t folding_length = 0; + apr_array_header_t *folded_lines = NULL; + apt_header_field_t *header_field; + apt_str_t *line; + apt_pair_t pair; + /* read name-value pair */ + if(apt_text_header_read(stream,&pair) == FALSE) { + return NULL; + } + + /* check folding lines (value spanning multiple lines) */ + while(stream->pos < stream->end) { + if(apt_text_is_wsp(*stream->pos) == FALSE) { + break; + } + + stream->pos++; + + /* skip further white spaces (if any) */ + apt_text_white_spaces_skip(stream); + + if(!folded_lines) { + folded_lines = apr_array_make(pool,1,sizeof(apt_str_t)); + } + line = apr_array_push(folded_lines); + apt_text_line_read(stream,line); + folding_length += line->length; + }; + + header_field = apt_header_field_alloc(pool); + /* copy parsed name of the header field */ + header_field->name.length = pair.name.length; + header_field->name.buf = apr_palloc(pool, pair.name.length + 1); + if(pair.name.length) { + memcpy(header_field->name.buf, pair.name.buf, pair.name.length); + } + header_field->name.buf[header_field->name.length] = '\0'; + + /* copy parsed value of the header field */ + header_field->value.length = pair.value.length + folding_length; + header_field->value.buf = apr_palloc(pool, header_field->value.length + 1); + if(pair.value.length) { + memcpy(header_field->value.buf, pair.value.buf, pair.value.length); + } + + if(folding_length) { + int i; + char *pos = header_field->value.buf + pair.value.length; + /* copy parsed folding lines */ + for(i=0; inelts; i++) { + line = &APR_ARRAY_IDX(folded_lines,i,apt_str_t); + + memcpy(pos,line->buf,line->length); + pos += line->length; + } + } + header_field->value.buf[header_field->value.length] = '\0'; + + return header_field; +} + +/** Generate individual header field (name-value pair) */ +APT_DECLARE(apt_bool_t) apt_header_field_generate(const apt_header_field_t *header_field, apt_text_stream_t *stream) +{ + return apt_text_name_value_insert(stream,&header_field->name,&header_field->value); +} + +/** Parse header section */ +APT_DECLARE(apt_bool_t) apt_header_section_parse(apt_header_section_t *header, apt_text_stream_t *stream, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + apt_bool_t result = FALSE; + + do { + header_field = apt_header_field_parse(stream,pool); + if(header_field) { + if(apt_string_is_empty(&header_field->name) == FALSE) { + /* normal header */ + apt_header_section_field_add(header,header_field); + } + else { + /* empty header => exit */ + result = TRUE; + break; + } + } + else { + /* malformed header => skip to the next one */ + } + } + while(apt_text_is_eos(stream) == FALSE); + + return result; +} + +/** Generate header section */ +APT_DECLARE(apt_bool_t) apt_header_section_generate(const apt_header_section_t *header, apt_text_stream_t *stream) +{ + apt_header_field_t *header_field; + for(header_field = APR_RING_FIRST(&header->ring); + header_field != APR_RING_SENTINEL(&header->ring, apt_header_field_t, link); + header_field = APR_RING_NEXT(header_field, link)) { + apt_header_field_generate(header_field,stream); + } + + return apt_text_eol_insert(stream); +} + +static apt_bool_t apt_message_body_read(apt_message_parser_t *parser, apt_text_stream_t *stream) +{ + apt_bool_t status = TRUE; + apt_str_t *body = parser->context.body; + if(body->buf) { + /* stream length available to read */ + apr_size_t stream_length = stream->text.length - (stream->pos - stream->text.buf); + /* required/remaining length to read */ + apr_size_t required_length = parser->content_length - body->length; + if(required_length > stream_length) { + required_length = stream_length; + /* incomplete */ + status = FALSE; + } + memcpy(body->buf + body->length, stream->pos, required_length); + body->length += required_length; + stream->pos += required_length; + if(parser->verbose == TRUE) { + apr_size_t length = required_length; + const char *masked_data = apt_log_data_mask(stream->pos,&length,parser->pool); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Parsed Message Body [%"APR_SIZE_T_FMT" bytes]\n%.*s", + required_length, length, masked_data); + } + } + + return status; +} + +static apt_bool_t apt_message_body_write(apt_message_generator_t *generator, apt_text_stream_t *stream) +{ + apt_bool_t status = TRUE; + apt_str_t *body = generator->context.body; + if(body && body->length < generator->content_length) { + /* stream length available to write */ + apr_size_t stream_length = stream->text.length - (stream->pos - stream->text.buf); + /* required/remaining length to write */ + apr_size_t required_length = generator->content_length - body->length; + if(required_length > stream_length) { + required_length = stream_length; + /* incomplete */ + status = FALSE; + } + + memcpy(stream->pos, body->buf + body->length, required_length); + + if(generator->verbose == TRUE) { + apr_size_t length = required_length; + const char *masked_data = apt_log_data_mask(stream->pos,&length,generator->pool); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Generated Message Body [%"APR_SIZE_T_FMT" bytes]\n%.*s", + required_length, length, masked_data); + } + + body->length += required_length; + stream->pos += required_length; + } + + return status; +} + + +/** Create message parser */ +APT_DECLARE(apt_message_parser_t*) apt_message_parser_create(void *obj, const apt_message_parser_vtable_t *vtable, apr_pool_t *pool) +{ + apt_message_parser_t *parser = apr_palloc(pool,sizeof(apt_message_parser_t)); + parser->obj = obj; + parser->vtable = vtable; + parser->pool = pool; + parser->context.message = NULL; + parser->context.body = NULL; + parser->context.header = NULL; + parser->content_length = 0; + parser->stage = APT_MESSAGE_STAGE_START_LINE; + parser->skip_lf = FALSE; + parser->verbose = FALSE; + return parser; +} + +static APR_INLINE void apt_crlf_segmentation_test(apt_message_parser_t *parser, apt_text_stream_t *stream) +{ + /* in the worst case message segmentation may occur between and */ + if(stream->pos == stream->end && *(stream->pos-1)== APT_TOKEN_CR) { + /* if this is the case be prepared to skip with the next attempt */ + parser->skip_lf = TRUE; + } +} + +/** Parse message by raising corresponding event handlers */ +APT_DECLARE(apt_message_status_e) apt_message_parser_run(apt_message_parser_t *parser, apt_text_stream_t *stream, void **message) +{ + const char *pos; + apt_message_status_e status = APT_MESSAGE_STATUS_INCOMPLETE; + if(parser->skip_lf == TRUE) { + /* skip occurred as a result of message segmentation between and */ + apt_text_char_skip(stream,APT_TOKEN_LF); + parser->skip_lf = FALSE; + } + if(message) { + *message = NULL; + } + + do { + pos = stream->pos; + if(parser->stage == APT_MESSAGE_STAGE_START_LINE) { + if(parser->vtable->on_start(parser,&parser->context,stream,parser->pool) == FALSE) { + if(apt_text_is_eos(stream) == FALSE) { + status = APT_MESSAGE_STATUS_INVALID; + } + break; + } + + apt_crlf_segmentation_test(parser,stream); + + parser->stage = APT_MESSAGE_STAGE_HEADER; + } + + if(parser->stage == APT_MESSAGE_STAGE_HEADER) { + /* read header section */ + apt_bool_t res = apt_header_section_parse(parser->context.header,stream,parser->pool); + if(parser->verbose == TRUE) { + apr_size_t length = stream->pos - pos; + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Parsed Message Header [%"APR_SIZE_T_FMT" bytes]\n%.*s", + length, length, pos); + } + + apt_crlf_segmentation_test(parser,stream); + + if(res == FALSE) { + break; + } + + if(parser->vtable->on_header_complete) { + if(parser->vtable->on_header_complete(parser,&parser->context) == FALSE) { + status = APT_MESSAGE_STATUS_INVALID; + break; + } + } + + if(parser->context.body && parser->context.body->length) { + apt_str_t *body = parser->context.body; + parser->content_length = body->length; + body->buf = apr_palloc(parser->pool,parser->content_length+1); + body->buf[parser->content_length] = '\0'; + body->length = 0; + parser->stage = APT_MESSAGE_STAGE_BODY; + } + else { + status = APT_MESSAGE_STATUS_COMPLETE; + if(message) { + *message = parser->context.message; + } + parser->stage = APT_MESSAGE_STAGE_START_LINE; + break; + } + } + + if(parser->stage == APT_MESSAGE_STAGE_BODY) { + if(apt_message_body_read(parser,stream) == FALSE) { + break; + } + + if(parser->vtable->on_body_complete) { + parser->vtable->on_body_complete(parser,&parser->context); + } + status = APT_MESSAGE_STATUS_COMPLETE; + if(message) { + *message = parser->context.message; + } + parser->stage = APT_MESSAGE_STAGE_START_LINE; + break; + } + } + while(apt_text_is_eos(stream) == FALSE); + + return status; +} + +/** Get external object associated with parser */ +APT_DECLARE(void*) apt_message_parser_object_get(apt_message_parser_t *parser) +{ + return parser->obj; +} + +/** Set verbose mode for the parser */ +APT_DECLARE(void) apt_message_parser_verbose_set(apt_message_parser_t *parser, apt_bool_t verbose) +{ + parser->verbose = verbose; +} + + +/** Create message generator */ +APT_DECLARE(apt_message_generator_t*) apt_message_generator_create(void *obj, const apt_message_generator_vtable_t *vtable, apr_pool_t *pool) +{ + apt_message_generator_t *generator = apr_palloc(pool,sizeof(apt_message_generator_t)); + generator->obj = obj; + generator->vtable = vtable; + generator->pool = pool; + generator->context.message = NULL; + generator->context.header = NULL; + generator->context.body = NULL; + generator->content_length = 0; + generator->stage = APT_MESSAGE_STAGE_START_LINE; + generator->verbose = FALSE; + return generator; +} + +static apt_message_status_e apt_message_generator_break(apt_message_generator_t *generator, apt_text_stream_t *stream) +{ + /* failed to generate message */ + if(apt_text_is_eos(stream) == TRUE) { + /* end of stream reached */ + return APT_MESSAGE_STATUS_INCOMPLETE; + } + + /* error case */ + return APT_MESSAGE_STATUS_INVALID; +} + +/** Generate message */ +APT_DECLARE(apt_message_status_e) apt_message_generator_run(apt_message_generator_t *generator, void *message, apt_text_stream_t *stream) +{ + if(!message) { + return APT_MESSAGE_STATUS_INVALID; + } + + if(message != generator->context.message) { + generator->stage = APT_MESSAGE_STAGE_START_LINE; + generator->context.message = message; + generator->context.header = NULL; + generator->context.body = NULL; + } + + if(generator->stage == APT_MESSAGE_STAGE_START_LINE) { + /* generate start-line */ + if(generator->vtable->on_start(generator,&generator->context,stream) == FALSE) { + return apt_message_generator_break(generator,stream); + } + + if(!generator->context.header || !generator->context.body) { + return APT_MESSAGE_STATUS_INVALID; + } + + /* generate header */ + if(apt_header_section_generate(generator->context.header,stream) == FALSE) { + return apt_message_generator_break(generator,stream); + } + + if(generator->vtable->on_header_complete) { + generator->vtable->on_header_complete(generator,&generator->context,stream); + } + if(generator->verbose == TRUE) { + apr_size_t length = stream->pos - stream->text.buf; + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Generated Message Header [%"APR_SIZE_T_FMT" bytes]\n%.*s", + length, length, stream->text.buf); + } + + generator->stage = APT_MESSAGE_STAGE_START_LINE; + generator->content_length = generator->context.body->length; + if(generator->content_length) { + generator->context.body->length = 0; + generator->stage = APT_MESSAGE_STAGE_BODY; + } + } + + if(generator->stage == APT_MESSAGE_STAGE_BODY) { + if(apt_message_body_write(generator,stream) == FALSE) { + return apt_message_generator_break(generator,stream); + } + + generator->stage = APT_MESSAGE_STAGE_START_LINE; + } + + return APT_MESSAGE_STATUS_COMPLETE; +} + +/** Get external object associated with generator */ +APT_DECLARE(void*) apt_message_generator_object_get(apt_message_generator_t *generator) +{ + return generator->obj; +} + +/** Set verbose mode for the parser */ +APT_DECLARE(void) apt_message_generator_verbose_set(apt_message_generator_t *generator, apt_bool_t verbose) +{ + generator->verbose = verbose; +} diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_text_stream.c b/libs/unimrcp/libs/apr-toolkit/src/apt_text_stream.c index 5617dff6fa..a15bbdb3cf 100644 --- a/libs/unimrcp/libs/apr-toolkit/src/apt_text_stream.c +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_text_stream.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: apt_text_stream.c 1793 2011-01-10 21:46:14Z achaloyan $ */ #include @@ -61,19 +63,20 @@ APT_DECLARE(apt_bool_t) apt_text_line_read(apt_text_stream_t *stream, apt_str_t else { /* end of stream is reached, do not advance stream pos, but set is_eos flag */ stream->is_eos = TRUE; + line->length = pos - line->buf; } return status; } -/** Navigate through the headers (name:value pairs) of the text stream (message) - Valid headers are: +/** To be used to navigate through the header fields (name:value pairs) of the text stream (message) + Valid header fields are: name:value name: value name: value name: value name: (only name, no value) (empty header) - Malformed headers are: + Malformed header fields are: name:value (missing end of line ) name (missing separator ':') */ @@ -109,8 +112,8 @@ APT_DECLARE(apt_bool_t) apt_text_header_read(apt_text_stream_t *stream, apt_pair break; } else if(!pair->name.length) { - /* skip initial spaces and read name */ - if(!pair->name.buf && *pos != APT_TOKEN_SP) { + /* skip preceding white spaces (SHOULD NOT be any WSP, though) and read name */ + if(!pair->name.buf && apt_text_is_wsp(*pos) == FALSE) { pair->name.buf = pos; } if(*pos == ':') { @@ -119,8 +122,8 @@ APT_DECLARE(apt_bool_t) apt_text_header_read(apt_text_stream_t *stream, apt_pair } } else if(!pair->value.length) { - /* skip initial spaces and read value */ - if(!pair->value.buf && *pos != APT_TOKEN_SP) { + /* skip preceding white spaces and read value */ + if(!pair->value.buf && apt_text_is_wsp(*pos) == FALSE) { pair->value.buf = pos; } } @@ -170,14 +173,19 @@ APT_DECLARE(apt_bool_t) apt_text_field_read(apt_text_stream_t *stream, char sepa /** Scroll text stream */ APT_DECLARE(apt_bool_t) apt_text_stream_scroll(apt_text_stream_t *stream) { - apr_size_t remaining_length = stream->text.buf + stream->text.length - stream->pos; - if(!remaining_length || remaining_length == stream->text.length) { + if(stream->pos == stream->end) { + stream->pos = stream->text.buf; + } + else { + apr_size_t remaining_length = stream->text.buf + stream->text.length - stream->pos; + if(!remaining_length || remaining_length == stream->text.length) { + stream->pos = stream->text.buf + remaining_length; + return FALSE; + } + memmove(stream->text.buf,stream->pos,remaining_length); stream->pos = stream->text.buf + remaining_length; - return FALSE; + stream->text.length = remaining_length; } - memmove(stream->text.buf,stream->pos,remaining_length); - stream->pos = stream->text.buf + remaining_length; - stream->text.length = remaining_length; *stream->pos = '\0'; return TRUE; } @@ -216,14 +224,36 @@ APT_DECLARE(apt_bool_t) apt_id_resource_generate(const apt_str_t *id, const apt_ return TRUE; } -/** Generate only the name ("name":) of the header */ -APT_DECLARE(apt_bool_t) apt_text_header_name_generate(const apt_str_t *name, apt_text_stream_t *stream) +/** Generate name-value pair line */ +APT_DECLARE(apt_bool_t) apt_text_name_value_insert(apt_text_stream_t *stream, const apt_str_t *name, const apt_str_t *value) { char *pos = stream->pos; + if(pos + name->length + value->length + 2 >= stream->end) { + return FALSE; + } + memcpy(pos,name->buf,name->length); + pos += name->length; + *pos++ = ':'; + *pos++ = APT_TOKEN_SP; + if(apt_string_is_empty(value) == FALSE) { + memcpy(pos,value->buf,value->length); + pos += value->length; + } + stream->pos = pos; + return apt_text_eol_insert(stream); +} + +/** Generate only the name ("name":) of the header field */ +APT_DECLARE(apt_bool_t) apt_text_header_name_insert(apt_text_stream_t *stream, const apt_str_t *name) +{ + char *pos = stream->pos; + if(pos + name->length + 2 >= stream->end) { + return FALSE; + } memcpy(pos,name->buf,name->length); pos += name->length; *pos++ = ':'; - *pos++ = ' '; + *pos++ = APT_TOKEN_SP; stream->pos = pos; return TRUE; } @@ -269,7 +299,21 @@ APT_DECLARE(apt_bool_t) apt_pair_array_parse(apt_pair_arr_t *arr, const apt_str_ } /** Generate array of name-value pairs */ -APT_DECLARE(apt_bool_t) apt_pair_array_generate(apt_pair_arr_t *arr, apt_text_stream_t *stream) +APT_DECLARE(apt_bool_t) apt_pair_array_generate(const apt_pair_arr_t *arr, apt_str_t *str, apr_pool_t *pool) +{ + char buf[512]; + apt_text_stream_t stream; + apt_text_stream_init(&stream,buf,sizeof(buf)); + if(apt_text_pair_array_insert(&stream,arr) == FALSE) { + return FALSE; + } + apt_string_assign_n(str, stream.text.buf, stream.pos - stream.text.buf, pool); + return TRUE; +} + + +/** Insert array of name-value pairs */ +APT_DECLARE(apt_bool_t) apt_text_pair_array_insert(apt_text_stream_t *stream, const apt_pair_arr_t *arr) { int i; apt_pair_t *pair; @@ -314,30 +358,61 @@ APT_DECLARE(apt_bool_t) apt_boolean_value_parse(const apt_str_t *str, apt_bool_t return FALSE; } +/** Generate apr_size_t value from pool (buffer is allocated from pool) */ +APT_DECLARE(apt_bool_t) apt_boolean_value_generate(apt_bool_t value, apt_str_t *str, apr_pool_t *pool) +{ + if(value == TRUE) { + str->length = TOKEN_TRUE_LENGTH; + str->buf = apr_palloc(pool,str->length); + memcpy(str->buf,TOKEN_TRUE,str->length); + } + else { + str->length = TOKEN_FALSE_LENGTH; + str->buf = apr_palloc(pool,str->length); + memcpy(str->buf,TOKEN_FALSE,str->length); + } + return TRUE; +} + /** Generate boolean-value */ -APT_DECLARE(apt_bool_t) apt_boolean_value_generate(apt_bool_t value, apt_text_stream_t *stream) +APT_DECLARE(apt_bool_t) apt_boolean_value_insert(apt_text_stream_t *stream, apt_bool_t value) { if(value == TRUE) { + if(stream->pos + TOKEN_TRUE_LENGTH >= stream->end) { + return FALSE; + } memcpy(stream->pos,TOKEN_TRUE,TOKEN_TRUE_LENGTH); stream->pos += TOKEN_TRUE_LENGTH; } else { + if(stream->pos + TOKEN_FALSE_LENGTH >= stream->end) { + return FALSE; + } memcpy(stream->pos,TOKEN_FALSE,TOKEN_FALSE_LENGTH); stream->pos += TOKEN_FALSE_LENGTH; } return TRUE; } + /** Parse size_t value */ APT_DECLARE(apr_size_t) apt_size_value_parse(const apt_str_t *str) { return str->buf ? atol(str->buf) : 0; } -/** Generate apr_size_t value */ -APT_DECLARE(apt_bool_t) apt_size_value_generate(apr_size_t value, apt_text_stream_t *stream) +/** Generate apr_size_t value (buffer is allocated from pool) */ +APT_DECLARE(apt_bool_t) apt_size_value_generate(apr_size_t value, apt_str_t *str, apr_pool_t *pool) { - int length = sprintf(stream->pos, "%"APR_SIZE_T_FMT, value); + str->buf = apr_psprintf(pool, "%"APR_SIZE_T_FMT, value); + str->length = strlen(str->buf); + return TRUE; +} + +/** Insert apr_size_t value */ +APT_DECLARE(apt_bool_t) apt_text_size_value_insert(apt_text_stream_t *stream, apr_size_t value) +{ + int length = apr_snprintf(stream->pos, stream->end - stream->pos, "%"APR_SIZE_T_FMT, value); if(length <= 0) { return FALSE; } @@ -345,29 +420,58 @@ APT_DECLARE(apt_bool_t) apt_size_value_generate(apr_size_t value, apt_text_strea return TRUE; } + /** Parse float value */ APT_DECLARE(float) apt_float_value_parse(const apt_str_t *str) { return str->buf ? (float)atof(str->buf) : 0; } +/** Generate float value (buffer is allocated from pool) */ +APT_DECLARE(apt_bool_t) apt_float_value_generate(float value, apt_str_t *str, apr_pool_t *pool) +{ + char *end; + str->buf = apr_psprintf(pool,"%f",value); + str->length = strlen(str->buf); + + /* remove trailing 0s (if any) */ + end = str->buf + str->length - 1; + while(*end == 0x30 && end != str->buf && *(end - 1) != '.') end--; + + str->length = end - str->buf + 1; + return TRUE; +} + /** Generate float value */ -APT_DECLARE(apt_bool_t) apt_float_value_generate(float value, apt_text_stream_t *stream) +APT_DECLARE(apt_bool_t) apt_text_float_value_insert(apt_text_stream_t *stream, float value) { char *end; - int length = sprintf(stream->pos,"%f",value); + int length = apr_snprintf(stream->pos, stream->end - stream->pos, "%f", value); if(length <= 0) { return FALSE; } /* remove trailing 0s (if any) */ end = stream->pos + length - 1; - while(*end == 0x30 && end != stream->pos) end--; + while(*end == 0x30 && end != stream->pos && *(end - 1) != '.') end--; stream->pos = end + 1; return TRUE; } +/** Insert string value */ +APT_DECLARE(apt_bool_t) apt_text_string_insert(apt_text_stream_t *stream, const apt_str_t *str) +{ + if(stream->pos + str->length >= stream->end) { + return FALSE; + } + if(str->length) { + memcpy(stream->pos,str->buf,str->length); + stream->pos += str->length; + } + return TRUE; +} + /** Generate value plus the length (number of digits) of the value itself. */ APT_DECLARE(apt_bool_t) apt_var_length_value_generate(apr_size_t *value, apr_size_t max_count, apt_str_t *str) { @@ -405,6 +509,25 @@ APT_DECLARE(apt_bool_t) apt_var_length_value_generate(apr_size_t *value, apr_siz return TRUE; } +/** Generate completion-cause */ +APT_DECLARE(apt_bool_t) apt_completion_cause_generate(const apt_str_table_item_t table[], apr_size_t size, apr_size_t cause, apt_str_t *str, apr_pool_t *pool) +{ + char buf[256]; + int length; + const apt_str_t *name = apt_string_table_str_get(table,size,cause); + if(!name) { + return FALSE; + } + length = sprintf(buf,"%03"APR_SIZE_T_FMT" ",cause); + if(length <= 0) { + return FALSE; + } + + memcpy(buf+length,name->buf,name->length); + apt_string_assign_n(str,buf,name->length + length,pool); + return TRUE; +} + /** Generate unique identifier (hex string) */ APT_DECLARE(apt_bool_t) apt_unique_id_generate(apt_str_t *id, apr_size_t length, apr_pool_t *pool) diff --git a/libs/unimrcp/libs/apr-toolkit/src/apt_timer_queue.c b/libs/unimrcp/libs/apr-toolkit/src/apt_timer_queue.c new file mode 100644 index 0000000000..8d1b007b8c --- /dev/null +++ b/libs/unimrcp/libs/apr-toolkit/src/apt_timer_queue.c @@ -0,0 +1,211 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: apt_timer_queue.c 1665 2010-04-25 05:03:26Z achaloyan $ + */ + +#ifdef WIN32 +#pragma warning(disable: 4127) +#endif +#include +#include "apt_timer_queue.h" +#include "apt_log.h" + +/** Timer queue */ +struct apt_timer_queue_t { + /** Ring head */ + APR_RING_HEAD(apt_timer_head_t, apt_timer_t) head; + + /** Elapsed time */ + apr_uint32_t elapsed_time; +}; + +/** Timer */ +struct apt_timer_t { + /** Ring entry */ + APR_RING_ENTRY(apt_timer_t) link; + + /** Back pointer to queue */ + apt_timer_queue_t *queue; + /** Time next report is scheduled at */ + apr_uint32_t scheduled_time; + + /** Timer proc */ + apt_timer_proc_f proc; + /** Timer object */ + void *obj; +}; + +static void apt_timers_reschedule(apt_timer_queue_t *timer_queue); + +/** Create timer queue */ +APT_DECLARE(apt_timer_queue_t*) apt_timer_queue_create(apr_pool_t *pool) +{ + apt_timer_queue_t *timer_queue = apr_palloc(pool,sizeof(apt_timer_queue_t)); + APR_RING_INIT(&timer_queue->head, apt_timer_t, link); + timer_queue->elapsed_time = 0; + return timer_queue; +} + +/** Destroy timer queue */ +APT_DECLARE(void) apt_timer_queue_destroy(apt_timer_queue_t *timer_queue) +{ +} + +/** Advance scheduled timers */ +APT_DECLARE(void) apt_timer_queue_advance(apt_timer_queue_t *timer_queue, apr_uint32_t elapsed_time) +{ + apt_timer_t *timer; + + if(APR_RING_EMPTY(&timer_queue->head, apt_timer_t, link)) { + /* just return, nothing to do */ + return; + } + + /* increment elapsed time */ + timer_queue->elapsed_time += elapsed_time; + if(timer_queue->elapsed_time >= 0xFFFF) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Reschedule Timers [%u]",timer_queue->elapsed_time); + apt_timers_reschedule(timer_queue); + } + + /* process timers */ + do { + /* get first node (timer) */ + timer = APR_RING_FIRST(&timer_queue->head); + + if(timer->scheduled_time > timer_queue->elapsed_time) { + /* scheduled time is not elapsed yet */ + break; + } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Timer Elapsed 0x%x [%u]",timer,timer->scheduled_time); + /* remove the elapsed timer from the list */ + APR_RING_REMOVE(timer, link); + timer->scheduled_time = 0; + /* process the elapsed timer */ + timer->proc(timer,timer->obj); + } + while(!APR_RING_EMPTY(&timer_queue->head, apt_timer_t, link)); +} + +/** Is timer queue empty */ +APT_DECLARE(apt_bool_t) apt_timer_queue_is_empty(const apt_timer_queue_t *timer_queue) +{ + return APR_RING_EMPTY(&timer_queue->head, apt_timer_t, link) ? TRUE : FALSE; +} + +/** Get current timeout */ +APT_DECLARE(apt_bool_t) apt_timer_queue_timeout_get(const apt_timer_queue_t *timer_queue, apr_uint32_t *timeout) +{ + apt_timer_t *timer; + /* is queue empty */ + if(APR_RING_EMPTY(&timer_queue->head, apt_timer_t, link)) { + return FALSE; + } + + /* get first node (timer) */ + timer = APR_RING_FIRST(&timer_queue->head); + if(!timer) { + return FALSE; + } + + *timeout = timer->scheduled_time - timer_queue->elapsed_time; + return TRUE; +} + + +/** Create timer */ +APT_DECLARE(apt_timer_t*) apt_timer_create(apt_timer_queue_t *timer_queue, apt_timer_proc_f proc, void *obj, apr_pool_t *pool) +{ + apt_timer_t *timer = apr_palloc(pool,sizeof(apt_timer_t)); + timer->queue = timer_queue; + timer->scheduled_time = 0; + timer->proc = proc; + timer->obj = obj; + return timer; +} + +static APR_INLINE apt_bool_t apt_timer_insert(apt_timer_queue_t *timer_queue, apt_timer_t *timer) +{ + apt_timer_t *it; + for(it = APR_RING_LAST(&timer_queue->head); + it != APR_RING_SENTINEL(&timer_queue->head, apt_timer_t, link); + it = APR_RING_PREV(it, link)) { + + if(it->scheduled_time <= timer->scheduled_time) { + APR_RING_INSERT_AFTER(it,timer,link); + return TRUE; + } + } + APR_RING_INSERT_HEAD(&timer_queue->head,timer,apt_timer_t,link); + return TRUE; +} + +/** Set one-shot timer */ +APT_DECLARE(apt_bool_t) apt_timer_set(apt_timer_t *timer, apr_uint32_t timeout) + +{ + apt_timer_queue_t *queue = timer->queue; + + if(timeout <= 0 || !timer->proc) { + return FALSE; + } + + /* calculate time to elapse */ + timer->scheduled_time = queue->elapsed_time + timeout; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Set Timer 0x%x [%u]",timer,timer->scheduled_time); + + if(APR_RING_EMPTY(&queue->head, apt_timer_t, link)) { + APR_RING_INSERT_TAIL(&queue->head,timer,apt_timer_t,link); + return TRUE; + } + + /* insert new node (timer) to sorted by scheduled time list */ + return apt_timer_insert(queue,timer); +} + +/** Kill timer */ +APT_DECLARE(apt_bool_t) apt_timer_kill(apt_timer_t *timer) +{ + apt_timer_queue_t *queue = timer->queue; + + if(!timer->scheduled_time) { + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Kill Timer 0x%x [%u]",timer,timer->scheduled_time); + /* remove node (timer) from the list */ + APR_RING_REMOVE(timer,link); + timer->scheduled_time = 0; + + if(APR_RING_EMPTY(&queue->head, apt_timer_t, link)) { + /* reset elapsed time if no timers set */ + queue->elapsed_time = 0; + } + return TRUE; +} + +static void apt_timers_reschedule(apt_timer_queue_t *queue) +{ + apt_timer_t *it; + for(it = APR_RING_LAST(&queue->head); + it != APR_RING_SENTINEL(&queue->head, apt_timer_t, link); + it = APR_RING_PREV(it, link)) { + + it->scheduled_time -= queue->elapsed_time; + } + queue->elapsed_time = 0; +} diff --git a/libs/unimrcp/libs/mpf/Makefile.am b/libs/unimrcp/libs/mpf/Makefile.am index d153905278..0e904a46ed 100644 --- a/libs/unimrcp/libs/mpf/Makefile.am +++ b/libs/unimrcp/libs/mpf/Makefile.am @@ -35,7 +35,6 @@ include_HEADERS = codecs/g711/g711.h \ include/mpf_rtp_termination_factory.h \ include/mpf_file_termination_factory.h \ include/mpf_scheduler.h \ - include/mpf_timer_manager.h \ include/mpf_types.h \ include/mpf_encoder.h \ include/mpf_decoder.h \ @@ -72,7 +71,6 @@ libmpf_la_SOURCES = codecs/g711/g711.c \ src/mpf_file_termination_factory.c \ src/mpf_frame_buffer.c \ src/mpf_scheduler.c \ - src/mpf_timer_manager.c \ src/mpf_encoder.c \ src/mpf_decoder.c \ src/mpf_jitter_buffer.c \ diff --git a/libs/unimrcp/libs/mpf/include/mpf.h b/libs/unimrcp/libs/mpf/include/mpf.h index 7edc0da71b..66fbc37460 100644 --- a/libs/unimrcp/libs/mpf/include/mpf.h +++ b/libs/unimrcp/libs/mpf/include/mpf.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_H__ -#define __MPF_H__ +#ifndef MPF_H +#define MPF_H /** * @file mpf.h @@ -39,4 +41,4 @@ #define MPF_DECLARE(type) type #endif -#endif /*__MPF_H__*/ +#endif /* MPF_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_activity_detector.h b/libs/unimrcp/libs/mpf/include/mpf_activity_detector.h index 1b90b558d5..3bb17f64f9 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_activity_detector.h +++ b/libs/unimrcp/libs/mpf/include/mpf_activity_detector.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_activity_detector.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_ACTIVITY_DETECTOR_H__ -#define __MPF_ACTIVITY_DETECTOR_H__ +#ifndef MPF_ACTIVITY_DETECTOR_H +#define MPF_ACTIVITY_DETECTOR_H /** * @file mpf_activity_detector.h @@ -63,4 +65,4 @@ MPF_DECLARE(mpf_detector_event_e) mpf_activity_detector_process(mpf_activity_det APT_END_EXTERN_C -#endif /*__MPF_ACTIVITY_DETECTOR_H__*/ +#endif /* MPF_ACTIVITY_DETECTOR_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_audio_file_descriptor.h b/libs/unimrcp/libs/mpf/include/mpf_audio_file_descriptor.h index 0d9c439c4c..df1aa1fbcb 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_audio_file_descriptor.h +++ b/libs/unimrcp/libs/mpf/include/mpf_audio_file_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_audio_file_descriptor.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_AUDIO_FILE_DESCRIPTOR_H__ -#define __MPF_AUDIO_FILE_DESCRIPTOR_H__ +#ifndef MPF_AUDIO_FILE_DESCRIPTOR_H +#define MPF_AUDIO_FILE_DESCRIPTOR_H /** * @file mpf_audio_file_descriptor.h @@ -51,4 +53,4 @@ struct mpf_audio_file_descriptor_t { APT_END_EXTERN_C -#endif /*__MPF_AUDIO_FILE_DESCRIPTOR_H__*/ +#endif /* MPF_AUDIO_FILE_DESCRIPTOR_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_audio_file_stream.h b/libs/unimrcp/libs/mpf/include/mpf_audio_file_stream.h index f117fbfbb6..0f936baddd 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_audio_file_stream.h +++ b/libs/unimrcp/libs/mpf/include/mpf_audio_file_stream.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_audio_file_stream.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_AUDIO_FILE_STREAM_H__ -#define __MPF_AUDIO_FILE_STREAM_H__ +#ifndef MPF_AUDIO_FILE_STREAM_H +#define MPF_AUDIO_FILE_STREAM_H /** * @file mpf_audio_file_stream.h @@ -43,4 +45,4 @@ MPF_DECLARE(apt_bool_t) mpf_file_stream_modify(mpf_audio_stream_t *stream, mpf_a APT_END_EXTERN_C -#endif /*__MPF_AUDIO_FILE_STREAM_H__*/ +#endif /* MPF_AUDIO_FILE_STREAM_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_bridge.h b/libs/unimrcp/libs/mpf/include/mpf_bridge.h index 395aaa966a..3988e0bf3e 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_bridge.h +++ b/libs/unimrcp/libs/mpf/include/mpf_bridge.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_bridge.h 1693 2010-05-16 18:33:07Z achaloyan $ */ -#ifndef __MPF_BRIDGE_H__ -#define __MPF_BRIDGE_H__ +#ifndef MPF_BRIDGE_H +#define MPF_BRIDGE_H /** * @file mpf_bridge.h @@ -31,15 +33,17 @@ APT_BEGIN_EXTERN_C * @param source the source audio stream * @param sink the sink audio stream * @param codec_manager the codec manager + * @param name the informative name used for debugging * @param pool the pool to allocate memory from */ MPF_DECLARE(mpf_object_t*) mpf_bridge_create( mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, + const char *name, apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__MPF_BRIDGE_H__*/ +#endif /* MPF_BRIDGE_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_buffer.h b/libs/unimrcp/libs/mpf/include/mpf_buffer.h index 6dd22f3f42..ee0cc0121c 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_buffer.h +++ b/libs/unimrcp/libs/mpf/include/mpf_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_buffer.h 1709 2010-05-24 17:12:11Z achaloyan $ */ -#ifndef __MPF_BUFFER_H__ -#define __MPF_BUFFER_H__ +#ifndef MPF_BUFFER_H +#define MPF_BUFFER_H /** * @file mpf_buffer.h @@ -49,8 +51,8 @@ apt_bool_t mpf_buffer_event_write(mpf_buffer_t *buffer, mpf_frame_type_e event_t apt_bool_t mpf_buffer_frame_read(mpf_buffer_t *buffer, mpf_frame_t *media_frame); /** Get size of buffer **/ -apr_size_t mpf_buffer_get_size(mpf_buffer_t *buffer); +apr_size_t mpf_buffer_get_size(const mpf_buffer_t *buffer); APT_END_EXTERN_C -#endif /*__MPF_BUFFER_H__*/ +#endif /* MPF_BUFFER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_codec.h b/libs/unimrcp/libs/mpf/include/mpf_codec.h index 04d9b27079..817e1540ce 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_codec.h +++ b/libs/unimrcp/libs/mpf/include/mpf_codec.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_codec.h 1686 2010-05-08 18:46:08Z achaloyan $ */ -#ifndef __MPF_CODEC_H__ -#define __MPF_CODEC_H__ +#ifndef MPF_CODEC_H +#define MPF_CODEC_H /** * @file mpf_codec.h @@ -55,6 +57,9 @@ struct mpf_codec_vtable_t { /** Virtual dissect method */ apt_bool_t (*dissect)(mpf_codec_t *codec, void **buffer, apr_size_t *size, mpf_codec_frame_t *frame); + + /** Virtual initialize method */ + apt_bool_t (*initialize)(mpf_codec_t *codec, mpf_codec_frame_t *frame_out); }; /** @@ -154,6 +159,19 @@ static APR_INLINE apt_bool_t mpf_codec_dissect(mpf_codec_t *codec, void **buffer return rv; } +/** Initialize (fill) codec frame with silence */ +static APR_INLINE apt_bool_t mpf_codec_initialize(mpf_codec_t *codec, mpf_codec_frame_t *frame_out) +{ + apt_bool_t rv = TRUE; + if(codec->vtable->initialize) { + rv = codec->vtable->initialize(codec,frame_out); + } + else { + memset(frame_out->buffer,0,frame_out->size); + } + return rv; +} + APT_END_EXTERN_C -#endif /*__MPF_CODEC_H__*/ +#endif /* MPF_CODEC_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_codec_descriptor.h b/libs/unimrcp/libs/mpf/include/mpf_codec_descriptor.h index 9f3a6ea1d7..4958cada57 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_codec_descriptor.h +++ b/libs/unimrcp/libs/mpf/include/mpf_codec_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_codec_descriptor.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_CODEC_DESCRIPTOR_H__ -#define __MPF_CODEC_DESCRIPTOR_H__ +#ifndef MPF_CODEC_DESCRIPTOR_H +#define MPF_CODEC_DESCRIPTOR_H /** * @file mpf_codec_descriptor.h @@ -278,4 +280,4 @@ MPF_DECLARE(int) mpf_sample_rate_mask_get(apr_uint16_t sampling_rate); APT_END_EXTERN_C -#endif /*__MPF_CODEC_DESCRIPTOR_H__*/ +#endif /* MPF_CODEC_DESCRIPTOR_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_codec_manager.h b/libs/unimrcp/libs/mpf/include/mpf_codec_manager.h index 2b14070b52..44aaf2cfca 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_codec_manager.h +++ b/libs/unimrcp/libs/mpf/include/mpf_codec_manager.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_codec_manager.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_CODEC_MANAGER_H__ -#define __MPF_CODEC_MANAGER_H__ +#ifndef MPF_CODEC_MANAGER_H +#define MPF_CODEC_MANAGER_H /** * @file mpf_codec_manager.h @@ -50,4 +52,4 @@ MPF_DECLARE(const mpf_codec_t*) mpf_codec_manager_codec_find(const mpf_codec_man APT_END_EXTERN_C -#endif /*__MPF_CODEC_MANAGER_H__*/ +#endif /* MPF_CODEC_MANAGER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_context.h b/libs/unimrcp/libs/mpf/include/mpf_context.h index d9a20bf9ad..9190970a39 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_context.h +++ b/libs/unimrcp/libs/mpf/include/mpf_context.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_context.h 1709 2010-05-24 17:12:11Z achaloyan $ */ -#ifndef __MPF_CONTEXT_H__ -#define __MPF_CONTEXT_H__ +#ifndef MPF_CONTEXT_H +#define MPF_CONTEXT_H /** * @file mpf_context.h @@ -47,12 +49,14 @@ MPF_DECLARE(apt_bool_t) mpf_context_factory_process(mpf_context_factory_t *facto /** * Create MPF context. * @param factory the factory context belongs to + * @param name the informative name of the context * @param obj the external object associated with context * @param max_termination_count the max number of terminations in context * @param pool the pool to allocate memory from */ MPF_DECLARE(mpf_context_t*) mpf_context_create( mpf_context_factory_t *factory, + const char *name, void *obj, apr_size_t max_termination_count, apr_pool_t *pool); @@ -67,7 +71,7 @@ MPF_DECLARE(apt_bool_t) mpf_context_destroy(mpf_context_t *context); * Get external object associated with MPF context. * @param context the context to get object from */ -MPF_DECLARE(void*) mpf_context_object_get(mpf_context_t *context); +MPF_DECLARE(void*) mpf_context_object_get(const mpf_context_t *context); /** * Add termination to context. @@ -126,4 +130,4 @@ MPF_DECLARE(apt_bool_t) mpf_context_process(mpf_context_t *context); APT_END_EXTERN_C -#endif /*__MPF_CONTEXT_H__*/ +#endif /* MPF_CONTEXT_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_decoder.h b/libs/unimrcp/libs/mpf/include/mpf_decoder.h index ea99db8ad1..25402de6db 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_decoder.h +++ b/libs/unimrcp/libs/mpf/include/mpf_decoder.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_decoder.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_DECODER_H__ -#define __MPF_DECODER_H__ +#ifndef MPF_DECODER_H +#define MPF_DECODER_H /** * @file mpf_decoder.h @@ -37,4 +39,4 @@ MPF_DECLARE(mpf_audio_stream_t*) mpf_decoder_create(mpf_audio_stream_t *source, APT_END_EXTERN_C -#endif /*__MPF_ENCODER_H__*/ +#endif /* MPF_ENCODER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_dtmf_detector.h b/libs/unimrcp/libs/mpf/include/mpf_dtmf_detector.h index 6c6d95768d..4108e3bd9b 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_dtmf_detector.h +++ b/libs/unimrcp/libs/mpf/include/mpf_dtmf_detector.h @@ -1,5 +1,5 @@ /* - * Copyright 2009 Tomas Valenta, Arsen Chaloyan + * Copyright 2009-2010 Tomas Valenta, Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,12 +12,14 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_dtmf_detector.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_DTMF_DETECTOR_H__ -#define __MPF_DTMF_DETECTOR_H__ +#ifndef MPF_DTMF_DETECTOR_H +#define MPF_DTMF_DETECTOR_H -/* +/** * @file mpf_dtmf_detector.h * @brief DTMF detector * @@ -118,4 +120,4 @@ MPF_DECLARE(void) mpf_dtmf_detector_destroy(struct mpf_dtmf_detector_t *detector APT_END_EXTERN_C -#endif /*__MPF_DTMF_DETECTOR_H__*/ +#endif /* MPF_DTMF_DETECTOR_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_dtmf_generator.h b/libs/unimrcp/libs/mpf/include/mpf_dtmf_generator.h index 21953c2b5a..ea28bba432 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_dtmf_generator.h +++ b/libs/unimrcp/libs/mpf/include/mpf_dtmf_generator.h @@ -1,5 +1,5 @@ /* - * Copyright 2009 Tomas Valenta, Arsen Chaloyan + * Copyright 2009-2010 Tomas Valenta, Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,11 +14,11 @@ * limitations under the License. */ -#ifndef __MPF_DTMF_GENERATOR_H__ -#define __MPF_DTMF_GENERATOR_H__ +#ifndef MPF_DTMF_GENERATOR_H +#define MPF_DTMF_GENERATOR_H -/* - * @file mpf_named_event.h +/** + * @file mpf_dtmf_generator.h * @brief DTMF generator * * Generator used to send DTMF tones. Capable to send digits @@ -128,4 +128,4 @@ MPF_DECLARE(void) mpf_dtmf_generator_destroy(struct mpf_dtmf_generator_t *genera APT_END_EXTERN_C -#endif /*__MPF_DTMF_GENERATOR_H__*/ +#endif /* MPF_DTMF_GENERATOR_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_encoder.h b/libs/unimrcp/libs/mpf/include/mpf_encoder.h index 529f9a0b7e..5ef8366393 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_encoder.h +++ b/libs/unimrcp/libs/mpf/include/mpf_encoder.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_encoder.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_ENCODER_H__ -#define __MPF_ENCODER_H__ +#ifndef MPF_ENCODER_H +#define MPF_ENCODER_H /** * @file mpf_encoder.h @@ -37,4 +39,4 @@ MPF_DECLARE(mpf_audio_stream_t*) mpf_encoder_create(mpf_audio_stream_t *sink, mp APT_END_EXTERN_C -#endif /*__MPF_ENCODER_H__*/ +#endif /* MPF_ENCODER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_engine.h b/libs/unimrcp/libs/mpf/include/mpf_engine.h index 149de69ce4..0810c70700 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_engine.h +++ b/libs/unimrcp/libs/mpf/include/mpf_engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_engine.h 1709 2010-05-24 17:12:11Z achaloyan $ */ -#ifndef __MPF_ENGINE_H__ -#define __MPF_ENGINE_H__ +#ifndef MPF_ENGINE_H +#define MPF_ENGINE_H /** * @file mpf_engine.h @@ -32,9 +34,10 @@ typedef apt_task_msg_t mpf_task_msg_t; /** * Create MPF engine. + * @param id the identifier of the engine * @param pool the pool to allocate memory from */ -MPF_DECLARE(mpf_engine_t*) mpf_engine_create(apr_pool_t *pool); +MPF_DECLARE(mpf_engine_t*) mpf_engine_create(const char *id, apr_pool_t *pool); /** * Create MPF codec manager. @@ -52,12 +55,14 @@ MPF_DECLARE(apt_bool_t) mpf_engine_codec_manager_register(mpf_engine_t *engine, /** * Create MPF context. * @param engine the engine to create context for + * @param name the informative name of the context * @param obj the external object associated with context * @param max_termination_count the max number of terminations in context * @param pool the pool to allocate memory from */ MPF_DECLARE(mpf_context_t*) mpf_engine_context_create( - mpf_engine_t *engine, + mpf_engine_t *engine, + const char *name, void *obj, apr_size_t max_termination_count, apr_pool_t *pool); @@ -72,13 +77,13 @@ MPF_DECLARE(apt_bool_t) mpf_engine_context_destroy(mpf_context_t *context); * Get external object associated with MPF context. * @param context the context to get object from */ -MPF_DECLARE(void*) mpf_engine_context_object_get(mpf_context_t *context); +MPF_DECLARE(void*) mpf_engine_context_object_get(const mpf_context_t *context); /** * Get task. * @param engine the engine to get task from */ -MPF_DECLARE(apt_task_t*) mpf_task_get(mpf_engine_t *engine); +MPF_DECLARE(apt_task_t*) mpf_task_get(const mpf_engine_t *engine); /** * Set task msg type to send responses and events with. @@ -148,7 +153,13 @@ MPF_DECLARE(apt_bool_t) mpf_engine_message_send(mpf_engine_t *engine, mpf_task_m */ MPF_DECLARE(apt_bool_t) mpf_engine_scheduler_rate_set(mpf_engine_t *engine, unsigned long rate); +/** + * Get the identifier of the engine . + * @param engine the engine to get name of + */ +MPF_DECLARE(const char*) mpf_engine_id_get(const mpf_engine_t *engine); + APT_END_EXTERN_C -#endif /*__MPF_ENGINE_H__*/ +#endif /* MPF_ENGINE_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_file_termination_factory.h b/libs/unimrcp/libs/mpf/include/mpf_file_termination_factory.h index df8a05abd7..de5bc30686 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_file_termination_factory.h +++ b/libs/unimrcp/libs/mpf/include/mpf_file_termination_factory.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_file_termination_factory.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_FILE_TERMINATION_FACTORY_H__ -#define __MPF_FILE_TERMINATION_FACTORY_H__ +#ifndef MPF_FILE_TERMINATION_FACTORY_H +#define MPF_FILE_TERMINATION_FACTORY_H /** * @file mpf_file_termination_factory.h @@ -34,4 +36,4 @@ MPF_DECLARE(mpf_termination_factory_t*) mpf_file_termination_factory_create(apr_ APT_END_EXTERN_C -#endif /*__MPF_RTP_TERMINATION_FACTORY_H__*/ +#endif /* MPF_RTP_TERMINATION_FACTORY_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_frame.h b/libs/unimrcp/libs/mpf/include/mpf_frame.h index c5b45a6e61..f490f8b9ba 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_frame.h +++ b/libs/unimrcp/libs/mpf/include/mpf_frame.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_frame.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_FRAME_H__ -#define __MPF_FRAME_H__ +#ifndef MPF_FRAME_H +#define MPF_FRAME_H /** * @file mpf_frame.h @@ -61,4 +63,4 @@ struct mpf_frame_t { APT_END_EXTERN_C -#endif /*__MPF_FRAME_H__*/ +#endif /* MPF_FRAME_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_frame_buffer.h b/libs/unimrcp/libs/mpf/include/mpf_frame_buffer.h index 8573963c6f..97d48d3dcb 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_frame_buffer.h +++ b/libs/unimrcp/libs/mpf/include/mpf_frame_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_frame_buffer.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_FRAME_BUFFER_H__ -#define __MPF_FRAME_BUFFER_H__ +#ifndef MPF_FRAME_BUFFER_H +#define MPF_FRAME_BUFFER_H /** * @file mpf_frame_buffer.h @@ -47,4 +49,4 @@ apt_bool_t mpf_frame_buffer_read(mpf_frame_buffer_t *buffer, mpf_frame_t *frame) APT_END_EXTERN_C -#endif /*__MPF_FRAME_BUFFER_H__*/ +#endif /* MPF_FRAME_BUFFER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_jitter_buffer.h b/libs/unimrcp/libs/mpf/include/mpf_jitter_buffer.h index a4cb4c8ba2..5bf142df43 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_jitter_buffer.h +++ b/libs/unimrcp/libs/mpf/include/mpf_jitter_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_jitter_buffer.h 1802 2011-05-13 02:43:12Z achaloyan $ */ -#ifndef __MPF_JITTER_BUFFER_H__ -#define __MPF_JITTER_BUFFER_H__ +#ifndef MPF_JITTER_BUFFER_H +#define MPF_JITTER_BUFFER_H /** * @file mpf_jitter_buffer.h @@ -50,7 +52,7 @@ void mpf_jitter_buffer_destroy(mpf_jitter_buffer_t *jb); apt_bool_t mpf_jitter_buffer_restart(mpf_jitter_buffer_t *jb); /** Write audio data to jitter buffer */ -jb_result_t mpf_jitter_buffer_write(mpf_jitter_buffer_t *jb, void *buffer, apr_size_t size, apr_uint32_t ts); +jb_result_t mpf_jitter_buffer_write(mpf_jitter_buffer_t *jb, void *buffer, apr_size_t size, apr_uint32_t ts, apr_byte_t marker); /** Write named event to jitter buffer */ jb_result_t mpf_jitter_buffer_event_write(mpf_jitter_buffer_t *jb, const mpf_named_event_frame_t *named_event, apr_uint32_t ts, apr_byte_t marker); @@ -60,4 +62,4 @@ apt_bool_t mpf_jitter_buffer_read(mpf_jitter_buffer_t *jb, mpf_frame_t *media_fr APT_END_EXTERN_C -#endif /*__MPF_JITTER_BUFFER_H__*/ +#endif /* MPF_JITTER_BUFFER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_message.h b/libs/unimrcp/libs/mpf/include/mpf_message.h index 601b306a9e..95f4092df7 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_message.h +++ b/libs/unimrcp/libs/mpf/include/mpf_message.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_message.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_MESSAGE_H__ -#define __MPF_MESSAGE_H__ +#ifndef MPF_MESSAGE_H +#define MPF_MESSAGE_H /** * @file mpf_message.h @@ -89,4 +91,4 @@ struct mpf_message_container_t { APT_END_EXTERN_C -#endif /*__MPF_MESSAGE_H__*/ +#endif /* MPF_MESSAGE_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_mixer.h b/libs/unimrcp/libs/mpf/include/mpf_mixer.h index fa48f5b9a9..a552634aa8 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_mixer.h +++ b/libs/unimrcp/libs/mpf/include/mpf_mixer.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_mixer.h 1693 2010-05-16 18:33:07Z achaloyan $ */ -#ifndef __MPF_MIXER_H__ -#define __MPF_MIXER_H__ +#ifndef MPF_MIXER_H +#define MPF_MIXER_H /** * @file mpf_mixer.h @@ -32,6 +34,7 @@ APT_BEGIN_EXTERN_C * @param source_count the number of audio sources * @param sink the audio sink * @param codec_manager the codec manager + * @param name the informative name used for debugging * @param pool the pool to allocate memory from */ MPF_DECLARE(mpf_object_t*) mpf_mixer_create( @@ -39,9 +42,10 @@ MPF_DECLARE(mpf_object_t*) mpf_mixer_create( apr_size_t source_count, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, + const char *name, apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__MPF_MIXER_H__*/ +#endif /* MPF_MIXER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_multiplier.h b/libs/unimrcp/libs/mpf/include/mpf_multiplier.h index 380d5b5f16..6e27e8b037 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_multiplier.h +++ b/libs/unimrcp/libs/mpf/include/mpf_multiplier.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_multiplier.h 1693 2010-05-16 18:33:07Z achaloyan $ */ -#ifndef __MPF_MULTIPLIER_H__ -#define __MPF_MULTIPLIER_H__ +#ifndef MPF_MULTIPLIER_H +#define MPF_MULTIPLIER_H /** * @file mpf_multiplier.h @@ -32,6 +34,7 @@ APT_BEGIN_EXTERN_C * @param sink_arr the array of audio sinks * @param sink_count the number of audio sinks * @param codec_manager the codec manager + * @param name the informative name used for debugging * @param pool the pool to allocate memory from */ MPF_DECLARE(mpf_object_t*) mpf_multiplier_create( @@ -39,9 +42,10 @@ MPF_DECLARE(mpf_object_t*) mpf_multiplier_create( mpf_audio_stream_t **sink_arr, apr_size_t sink_count, const mpf_codec_manager_t *codec_manager, + const char *name, apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__MPF_MULTIPLIER_H__*/ +#endif /* MPF_MULTIPLIER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_named_event.h b/libs/unimrcp/libs/mpf/include/mpf_named_event.h index d8d4dc6750..1e4f04fdab 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_named_event.h +++ b/libs/unimrcp/libs/mpf/include/mpf_named_event.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_named_event.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_NAMED_EVENT_H__ -#define __MPF_NAMED_EVENT_H__ +#ifndef MPF_NAMED_EVENT_H +#define MPF_NAMED_EVENT_H /** * @file mpf_named_event.h @@ -68,4 +70,4 @@ MPF_DECLARE(char) mpf_event_id_to_dtmf_char(const apr_uint32_t event_id); APT_END_EXTERN_C -#endif /*__MPF_NAMED_EVENT_H__*/ +#endif /* MPF_NAMED_EVENT_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_object.h b/libs/unimrcp/libs/mpf/include/mpf_object.h index 8e3e4eee95..cc48f4f879 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_object.h +++ b/libs/unimrcp/libs/mpf/include/mpf_object.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_object.h 1693 2010-05-16 18:33:07Z achaloyan $ */ -#ifndef __MPF_OBJECT_H__ -#define __MPF_OBJECT_H__ +#ifndef MPF_OBJECT_H +#define MPF_OBJECT_H /** * @file mpf_object.h @@ -31,6 +33,8 @@ typedef struct mpf_object_t mpf_object_t; /** Media processing objects base */ struct mpf_object_t { + /** Informative name used for debugging */ + const char *name; /** Virtual destroy */ apt_bool_t (*destroy)(mpf_object_t *object); /** Virtual process */ @@ -40,8 +44,9 @@ struct mpf_object_t { }; /** Initialize object */ -static APR_INLINE void mpf_object_init(mpf_object_t *object) +static APR_INLINE void mpf_object_init(mpf_object_t *object, const char *name) { + object->name = name; object->destroy = NULL; object->process = NULL; object->trace = NULL; @@ -71,4 +76,4 @@ static APR_INLINE void mpf_object_trace(mpf_object_t *object) APT_END_EXTERN_C -#endif /*__MPF_OBJECT_H__*/ +#endif /* MPF_OBJECT_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_resampler.h b/libs/unimrcp/libs/mpf/include/mpf_resampler.h index d674336139..eeac10aaee 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_resampler.h +++ b/libs/unimrcp/libs/mpf/include/mpf_resampler.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_resampler.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RESAMPLER_H__ -#define __MPF_RESAMPLER_H__ +#ifndef MPF_RESAMPLER_H +#define MPF_RESAMPLER_H /** * @file mpf_resampler.h @@ -37,4 +39,4 @@ MPF_DECLARE(mpf_audio_stream_t*) mpf_resampler_create(mpf_audio_stream_t *source APT_END_EXTERN_C -#endif /*__MPF_RESAMPLER_H__*/ +#endif /* MPF_RESAMPLER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtcp_packet.h b/libs/unimrcp/libs/mpf/include/mpf_rtcp_packet.h index 6773807fcd..ba65d3f695 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtcp_packet.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtcp_packet.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtcp_packet.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTCP_PACKET_H__ -#define __MPF_RTCP_PACKET_H__ +#ifndef MPF_RTCP_PACKET_H +#define MPF_RTCP_PACKET_H /** * @file mpf_rtcp_packet.h @@ -198,4 +200,4 @@ static APR_INLINE void rtcp_rr_ntoh(rtcp_rr_stat_t *rr_stat) APT_END_EXTERN_C -#endif /*__MPF_RTCP_PACKET_H__*/ +#endif /* MPF_RTCP_PACKET_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_attribs.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_attribs.h index dbce6b706f..c5212d78e8 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_attribs.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_attribs.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_attribs.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_ATTRIBS_H__ -#define __MPF_RTP_ATTRIBS_H__ +#ifndef MPF_RTP_ATTRIBS_H +#define MPF_RTP_ATTRIBS_H /** * @file mpf_rtp_attribs.h @@ -51,4 +53,4 @@ MPF_DECLARE(const apt_str_t*) mpf_rtp_direction_str_get(mpf_stream_direction_e d APT_END_EXTERN_C -#endif /*__MPF_RTP_ATTRIBS_H__*/ +#endif /* MPF_RTP_ATTRIBS_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_defs.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_defs.h index 883a1f5896..7d488db3ee 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_defs.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_defs.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_defs.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_DEFS_H__ -#define __MPF_RTP_DEFS_H__ +#ifndef MPF_RTP_DEFS_H +#define MPF_RTP_DEFS_H /** * @file mpf_rtp_defs.h @@ -178,4 +180,4 @@ static APR_INLINE void rtp_transmitter_init(rtp_transmitter_t *transmitter) APT_END_EXTERN_C -#endif /*__MPF_RTP_DEFS_H__*/ +#endif /* MPF_RTP_DEFS_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_descriptor.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_descriptor.h index 906a3c339c..8412c8fc2a 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_descriptor.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_descriptor.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_DESCRIPTOR_H__ -#define __MPF_RTP_DESCRIPTOR_H__ +#ifndef MPF_RTP_DESCRIPTOR_H +#define MPF_RTP_DESCRIPTOR_H /** * @file mpf_rtp_descriptor.h @@ -36,6 +38,8 @@ typedef struct mpf_rtp_stream_descriptor_t mpf_rtp_stream_descriptor_t; typedef struct mpf_rtp_termination_descriptor_t mpf_rtp_termination_descriptor_t; /** RTP configuration declaration */ typedef struct mpf_rtp_config_t mpf_rtp_config_t; +/** RTP settings declaration */ +typedef struct mpf_rtp_settings_t mpf_rtp_settings_t; /** Jitter buffer configuration declaration */ typedef struct mpf_jb_config_t mpf_jb_config_t; @@ -75,6 +79,8 @@ struct mpf_rtp_stream_descriptor_t { mpf_rtp_media_descriptor_t *local; /** Remote media descriptor */ mpf_rtp_media_descriptor_t *remote; + /** Settings loaded from config */ + mpf_rtp_settings_t *settings; }; /** RTP termination descriptor */ @@ -104,7 +110,7 @@ typedef enum { RTCP_BYE_PER_TALKSPURT /**< transmit RTCP BYE at the end of each talkspurt (input) */ } rtcp_bye_policy_e; -/** RTP config */ +/** RTP factory config */ struct mpf_rtp_config_t { /** Local IP address to bind to */ apt_str_t ip; @@ -116,6 +122,10 @@ struct mpf_rtp_config_t { apr_port_t rtp_port_max; /** Current RTP port */ apr_port_t rtp_port_cur; +}; + +/** RTP settings */ +struct mpf_rtp_settings_t { /** Packetization time */ apr_uint16_t ptime; /** Codec list */ @@ -172,8 +182,8 @@ static APR_INLINE void mpf_jb_config_init(mpf_jb_config_t *jb_config) jb_config->max_playout_delay = 0; } -/** Create/allocate RTP config */ -static APR_INLINE mpf_rtp_config_t* mpf_rtp_config_create(apr_pool_t *pool) +/** Allocate RTP config */ +static APR_INLINE mpf_rtp_config_t* mpf_rtp_config_alloc(apr_pool_t *pool) { mpf_rtp_config_t *rtp_config = (mpf_rtp_config_t*)apr_palloc(pool,sizeof(mpf_rtp_config_t)); apt_string_reset(&rtp_config->ip); @@ -181,18 +191,25 @@ static APR_INLINE mpf_rtp_config_t* mpf_rtp_config_create(apr_pool_t *pool) rtp_config->rtp_port_cur = 0; rtp_config->rtp_port_min = 0; rtp_config->rtp_port_max = 0; - rtp_config->ptime = 0; - mpf_codec_list_init(&rtp_config->codec_list,0,pool); - rtp_config->own_preferrence = FALSE; - rtp_config->rtcp = FALSE; - rtp_config->rtcp_bye_policy = RTCP_BYE_DISABLE; - rtp_config->rtcp_tx_interval = 0; - rtp_config->rtcp_rx_resolution = 0; - mpf_jb_config_init(&rtp_config->jb_config); - return rtp_config; } +/** Allocate RTP settings */ +static APR_INLINE mpf_rtp_settings_t* mpf_rtp_settings_alloc(apr_pool_t *pool) +{ + mpf_rtp_settings_t *rtp_settings = (mpf_rtp_settings_t*)apr_palloc(pool,sizeof(mpf_rtp_settings_t)); + rtp_settings->ptime = 0; + mpf_codec_list_init(&rtp_settings->codec_list,0,pool); + rtp_settings->own_preferrence = FALSE; + rtp_settings->rtcp = FALSE; + rtp_settings->rtcp_bye_policy = RTCP_BYE_DISABLE; + rtp_settings->rtcp_tx_interval = 0; + rtp_settings->rtcp_rx_resolution = 0; + mpf_jb_config_init(&rtp_settings->jb_config); + return rtp_settings; +} + + APT_END_EXTERN_C -#endif /*__MPF_RTP_DESCRIPTOR_H__*/ +#endif /* MPF_RTP_DESCRIPTOR_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_header.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_header.h index 398d844dce..a122cb6cc7 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_header.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_header.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_HEADER_H__ -#define __MPF_RTP_HEADER_H__ +#ifndef MPF_RTP_HEADER_H +#define MPF_RTP_HEADER_H /** * @file mpf_rtp_header.h @@ -83,4 +85,4 @@ struct rtp_extension_header_t { APT_END_EXTERN_C -#endif /*__MPF_RTP_HEADER_H__*/ +#endif /* MPF_RTP_HEADER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_pt.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_pt.h index 27114c5e6e..27f88f1c7c 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_pt.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_pt.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_pt.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_PT_H__ -#define __MPF_RTP_PT_H__ +#ifndef MPF_RTP_PT_H +#define MPF_RTP_PT_H /** * @file mpf_rtp_pt.h @@ -41,4 +43,4 @@ typedef enum { APT_END_EXTERN_C -#endif /*__MPF_RTP_PT_H__*/ +#endif /* MPF_RTP_PT_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_stat.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_stat.h index 2d492ebf4f..e97b58c826 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_stat.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_stat.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_stat.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_STAT_H__ -#define __MPF_RTP_STAT_H__ +#ifndef MPF_RTP_STAT_H +#define MPF_RTP_STAT_H /** * @file mpf_rtp_stat.h @@ -110,4 +112,4 @@ static APR_INLINE void mpf_rtp_rx_stat_reset(rtp_rx_stat_t *rx_stat) APT_END_EXTERN_C -#endif /*__MPF_RTP_STAT_H__*/ +#endif /* MPF_RTP_STAT_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_stream.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_stream.h index 803ab34577..76ef8963a5 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_stream.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_stream.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_stream.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_STREAM_H__ -#define __MPF_RTP_STREAM_H__ +#ifndef MPF_RTP_STREAM_H +#define MPF_RTP_STREAM_H /** * @file mpf_rtp_stream.h @@ -30,10 +32,11 @@ APT_BEGIN_EXTERN_C /** * Create RTP stream. * @param termination the back pointer to hold - * @param config the configuration to use + * @param config the configuration of RTP factory + * @param settings the settings to use * @param pool the pool to allocate memory from */ -MPF_DECLARE(mpf_audio_stream_t*) mpf_rtp_stream_create(mpf_termination_t *termination, mpf_rtp_config_t *config, apr_pool_t *pool); +MPF_DECLARE(mpf_audio_stream_t*) mpf_rtp_stream_create(mpf_termination_t *termination, mpf_rtp_config_t *config, mpf_rtp_settings_t *settings, apr_pool_t *pool); /** * Add/enable RTP stream. @@ -56,4 +59,4 @@ MPF_DECLARE(apt_bool_t) mpf_rtp_stream_modify(mpf_audio_stream_t *stream, mpf_rt APT_END_EXTERN_C -#endif /*__MPF_RTP_STREAM_H__*/ +#endif /* MPF_RTP_STREAM_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_rtp_termination_factory.h b/libs/unimrcp/libs/mpf/include/mpf_rtp_termination_factory.h index f881c445af..d34ffcbc3d 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_rtp_termination_factory.h +++ b/libs/unimrcp/libs/mpf/include/mpf_rtp_termination_factory.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_termination_factory.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_RTP_TERMINATION_FACTORY_H__ -#define __MPF_RTP_TERMINATION_FACTORY_H__ +#ifndef MPF_RTP_TERMINATION_FACTORY_H +#define MPF_RTP_TERMINATION_FACTORY_H /** * @file mpf_rtp_termination_factory.h @@ -37,4 +39,4 @@ MPF_DECLARE(mpf_termination_factory_t*) mpf_rtp_termination_factory_create( APT_END_EXTERN_C -#endif /*__MPF_RTP_TERMINATION_FACTORY_H__*/ +#endif /* MPF_RTP_TERMINATION_FACTORY_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_scheduler.h b/libs/unimrcp/libs/mpf/include/mpf_scheduler.h index 6617511fe7..1e83091b8e 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_scheduler.h +++ b/libs/unimrcp/libs/mpf/include/mpf_scheduler.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_scheduler.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_SCHEDULER_H__ -#define __MPF_SCHEDULER_H__ +#ifndef MPF_SCHEDULER_H +#define MPF_SCHEDULER_H /** * @file mpf_scheduler.h @@ -63,4 +65,4 @@ MPF_DECLARE(apt_bool_t) mpf_scheduler_stop(mpf_scheduler_t *scheduler); APT_END_EXTERN_C -#endif /*__MPF_SCHEDULER_H__*/ +#endif /* MPF_SCHEDULER_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_stream.h b/libs/unimrcp/libs/mpf/include/mpf_stream.h index 4decae5235..93676b7eb0 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_stream.h +++ b/libs/unimrcp/libs/mpf/include/mpf_stream.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_stream.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_STREAM_H__ -#define __MPF_STREAM_H__ +#ifndef MPF_STREAM_H +#define MPF_STREAM_H /** * @file mpf_stream.h @@ -166,4 +168,4 @@ MPF_DECLARE(void) mpf_audio_stream_trace(mpf_audio_stream_t *stream, mpf_stream_ APT_END_EXTERN_C -#endif /*__MPF_STREAM_H__*/ +#endif /* MPF_STREAM_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_stream_descriptor.h b/libs/unimrcp/libs/mpf/include/mpf_stream_descriptor.h index 86b56b1b73..fbdeb5b068 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_stream_descriptor.h +++ b/libs/unimrcp/libs/mpf/include/mpf_stream_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_stream_descriptor.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MPF_STREAM_DESCRIPTOR_H__ -#define __MPF_STREAM_DESCRIPTOR_H__ +#ifndef MPF_STREAM_DESCRIPTOR_H +#define MPF_STREAM_DESCRIPTOR_H /** * @file mpf_stream_descriptor.h @@ -85,4 +87,4 @@ static APR_INLINE mpf_stream_direction_e mpf_stream_reverse_direction_get(mpf_st APT_END_EXTERN_C -#endif /*__MPF_STREAM_DESCRIPTOR_H__*/ +#endif /* MPF_STREAM_DESCRIPTOR_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_termination.h b/libs/unimrcp/libs/mpf/include/mpf_termination.h index 06ede3bfd8..8444f2edff 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_termination.h +++ b/libs/unimrcp/libs/mpf/include/mpf_termination.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_termination.h 1693 2010-05-16 18:33:07Z achaloyan $ */ -#ifndef __MPF_TERMINATION_H__ -#define __MPF_TERMINATION_H__ +#ifndef MPF_TERMINATION_H +#define MPF_TERMINATION_H /** * @file mpf_termination.h @@ -23,6 +25,7 @@ */ #include "mpf_types.h" +#include "apt_timer_queue.h" APT_BEGIN_EXTERN_C @@ -50,6 +53,8 @@ struct mpf_termination_vtable_t { struct mpf_termination_t { /** Pool to allocate memory from */ apr_pool_t *pool; + /** Informative name used for debugging */ + const char *name; /** External object */ void *obj; /** Object to send events to */ @@ -58,8 +63,8 @@ struct mpf_termination_t { mpf_termination_event_handler_f event_handler; /** Codec manager */ const mpf_codec_manager_t *codec_manager; - /** Timer manager */ - mpf_timer_manager_t *timer_manager; + /** Timer queue */ + apt_timer_queue_t *timer_queue; /** Termination factory entire termination created by */ mpf_termination_factory_t *termination_factory; /** Table of virtual methods */ @@ -113,4 +118,4 @@ MPF_DECLARE(apt_bool_t) mpf_termination_subtract(mpf_termination_t *termination) APT_END_EXTERN_C -#endif /*__MPF_TERMINATION_H__*/ +#endif /* MPF_TERMINATION_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_termination_factory.h b/libs/unimrcp/libs/mpf/include/mpf_termination_factory.h index 564518657a..973044b888 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_termination_factory.h +++ b/libs/unimrcp/libs/mpf/include/mpf_termination_factory.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_termination_factory.h 1693 2010-05-16 18:33:07Z achaloyan $ */ -#ifndef __MPF_TERMINATION_FACTORY_H__ -#define __MPF_TERMINATION_FACTORY_H__ +#ifndef MPF_TERMINATION_FACTORY_H +#define MPF_TERMINATION_FACTORY_H /** * @file mpf_termination_factory.h @@ -64,25 +66,31 @@ MPF_DECLARE(mpf_termination_t*) mpf_raw_termination_create( */ MPF_DECLARE(apt_bool_t) mpf_termination_destroy(mpf_termination_t *termination); +/** + * Get termination name. + * @param termination the termination to get name of + */ +MPF_DECLARE(const char*) mpf_termination_name_get(const mpf_termination_t *termination); + /** * Get associated object. * @param termination the termination to get object from */ -MPF_DECLARE(void*) mpf_termination_object_get(mpf_termination_t *termination); +MPF_DECLARE(void*) mpf_termination_object_get(const mpf_termination_t *termination); /** * Get audio stream. * @param termination the termination to get audio stream from */ -MPF_DECLARE(mpf_audio_stream_t*) mpf_termination_audio_stream_get(mpf_termination_t *termination); +MPF_DECLARE(mpf_audio_stream_t*) mpf_termination_audio_stream_get(const mpf_termination_t *termination); /** * Get video stream. * @param termination the termination to get video stream from */ -MPF_DECLARE(mpf_video_stream_t*) mpf_termination_video_stream_get(mpf_termination_t *termination); +MPF_DECLARE(mpf_video_stream_t*) mpf_termination_video_stream_get(const mpf_termination_t *termination); APT_END_EXTERN_C -#endif /*__MPF_TERMINATION_FACTORY_H__*/ +#endif /* MPF_TERMINATION_FACTORY_H */ diff --git a/libs/unimrcp/libs/mpf/include/mpf_timer_manager.h b/libs/unimrcp/libs/mpf/include/mpf_timer_manager.h deleted file mode 100644 index 4de738c4f6..0000000000 --- a/libs/unimrcp/libs/mpf/include/mpf_timer_manager.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2008 Arsen Chaloyan - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPF_TIMER_MANAGER_H__ -#define __MPF_TIMER_MANAGER_H__ - -/** - * @file mpf_timer_manager.h - * @brief MPF Timer Management - */ - -#include "mpf_types.h" - -APT_BEGIN_EXTERN_C - - -/** Prototype of timer callback */ -typedef void (*mpf_timer_proc_f)(mpf_timer_t *timer, void *obj); - - -/** Create timer manager */ -MPF_DECLARE(mpf_timer_manager_t*) mpf_timer_manager_create(mpf_scheduler_t *scheduler, apr_pool_t *pool); - -/** Destroy timer manager */ -MPF_DECLARE(void) mpf_timer_manager_destroy(mpf_timer_manager_t *timer_manager); - - -/** Create timer */ -MPF_DECLARE(mpf_timer_t*) mpf_timer_create(mpf_timer_manager_t *timer_manager, mpf_timer_proc_f proc, void *obj, apr_pool_t *pool); - -/** Set one-shot timer */ -MPF_DECLARE(apt_bool_t) mpf_timer_set(mpf_timer_t *timer, apr_uint32_t timeout); - -/** Kill timer */ -MPF_DECLARE(apt_bool_t) mpf_timer_kill(mpf_timer_t *timer); - - -APT_END_EXTERN_C - -#endif /*__MPF_TIMER_MANAGER_H__*/ diff --git a/libs/unimrcp/libs/mpf/include/mpf_types.h b/libs/unimrcp/libs/mpf/include/mpf_types.h index 0b9814edb5..f3017489f6 100644 --- a/libs/unimrcp/libs/mpf/include/mpf_types.h +++ b/libs/unimrcp/libs/mpf/include/mpf_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_types.h 1543 2010-02-24 21:46:24Z achaloyan $ */ -#ifndef __MPF_TYPES_H__ -#define __MPF_TYPES_H__ +#ifndef MPF_TYPES_H +#define MPF_TYPES_H /** * @file mpf_types.h @@ -35,12 +37,6 @@ typedef struct mpf_scheduler_t mpf_scheduler_t; /** Opaque codec manager declaration */ typedef struct mpf_codec_manager_t mpf_codec_manager_t; -/** Opaque MPF timer manager declaration */ -typedef struct mpf_timer_manager_t mpf_timer_manager_t; - -/** Opaque MPF timer declaration */ -typedef struct mpf_timer_t mpf_timer_t; - /** Opaque MPF context declaration */ typedef struct mpf_context_t mpf_context_t; @@ -59,4 +55,4 @@ typedef struct mpf_video_stream_t mpf_video_stream_t; APT_END_EXTERN_C -#endif /*__MPF_TYPES_H__*/ +#endif /* MPF_TYPES_H */ diff --git a/libs/unimrcp/libs/mpf/mpf.2008.vcproj b/libs/unimrcp/libs/mpf/mpf.2008.vcproj deleted file mode 100644 index 2f02670890..0000000000 --- a/libs/unimrcp/libs/mpf/mpf.2008.vcproj +++ /dev/null @@ -1,567 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/mpf/mpf.2010.vcxproj b/libs/unimrcp/libs/mpf/mpf.2010.vcxproj deleted file mode 100644 index 1b48acef80..0000000000 --- a/libs/unimrcp/libs/mpf/mpf.2010.vcxproj +++ /dev/null @@ -1,193 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mpf - {B5A00BFA-6083-4FAE-A097-71642D6473B5} - mpf - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;%(PreprocessorDefinitions) - false - ProgramDatabase - - - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;%(PreprocessorDefinitions) - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mpf/mpf.2010.vcxproj.filters b/libs/unimrcp/libs/mpf/mpf.2010.vcxproj.filters deleted file mode 100644 index 0e4bc84d13..0000000000 --- a/libs/unimrcp/libs/mpf/mpf.2010.vcxproj.filters +++ /dev/null @@ -1,239 +0,0 @@ - - - - - {3d69fc35-a195-4376-9508-ef77d7b27e71} - - - {81e2eace-c57a-4135-92cd-cc3575dfb088} - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {6fc3533a-b688-477d-914d-e0ffb15aa9a9} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - codecs\g711 - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - src - - - - - codecs\g711 - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mpf/mpf.vcproj b/libs/unimrcp/libs/mpf/mpf.vcproj index bf380d1e31..b3fde36677 100644 --- a/libs/unimrcp/libs/mpf/mpf.vcproj +++ b/libs/unimrcp/libs/mpf/mpf.vcproj @@ -416,10 +416,6 @@ RelativePath=".\include\mpf_termination_factory.h" > - - @@ -541,10 +537,6 @@ RelativePath=".\src\mpf_termination_factory.c" > - - diff --git a/libs/unimrcp/libs/mpf/src/mpf_activity_detector.c b/libs/unimrcp/libs/mpf/src/mpf_activity_detector.c index 6ef66674eb..bf3cd76fc6 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_activity_detector.c +++ b/libs/unimrcp/libs/mpf/src/mpf_activity_detector.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_activity_detector.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_activity_detector.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_audio_file_stream.c b/libs/unimrcp/libs/mpf/src/mpf_audio_file_stream.c index 54010b69b4..c235da38de 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_audio_file_stream.c +++ b/libs/unimrcp/libs/mpf/src/mpf_audio_file_stream.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_audio_file_stream.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_audio_file_stream.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_bridge.c b/libs/unimrcp/libs/mpf/src/mpf_bridge.c index f4028063d3..25c12de2ff 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_bridge.c +++ b/libs/unimrcp/libs/mpf/src/mpf_bridge.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_bridge.c 1693 2010-05-16 18:33:07Z achaloyan $ */ #include "mpf_bridge.h" @@ -31,7 +33,8 @@ struct mpf_bridge_t { mpf_audio_stream_t *source; /** Audio stream sink */ mpf_audio_stream_t *sink; - + /** Codec used in case of null bridge */ + mpf_codec_t *codec; /** Media frame used to read data from source and write it to sink */ mpf_frame_t frame; }; @@ -57,7 +60,14 @@ static apt_bool_t mpf_null_bridge_process(mpf_object_t *object) { mpf_bridge_t *bridge = (mpf_bridge_t*) object; bridge->frame.type = MEDIA_FRAME_TYPE_NONE; + bridge->frame.marker = MPF_MARKER_NONE; bridge->source->vtable->read_frame(bridge->source,&bridge->frame); + + if((bridge->frame.type & MEDIA_FRAME_TYPE_AUDIO) == 0) { + /* generate silence frame */ + mpf_codec_initialize(bridge->codec,&bridge->frame.codec_frame); + } + bridge->sink->vtable->write_frame(bridge->sink,&bridge->frame); return TRUE; } @@ -80,20 +90,20 @@ static void mpf_bridge_trace(mpf_object_t *object) mpf_audio_stream_trace(bridge->sink,STREAM_DIRECTION_SEND,&output); *output.pos = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,output.text.buf); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Media Path %s %s",object->name,output.text.buf); } static apt_bool_t mpf_bridge_destroy(mpf_object_t *object) { mpf_bridge_t *bridge = (mpf_bridge_t*) object; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Audio Bridge"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Audio Bridge %s",object->name); mpf_audio_stream_rx_close(bridge->source); mpf_audio_stream_tx_close(bridge->sink); return TRUE; } -static mpf_bridge_t* mpf_bridge_base_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, apr_pool_t *pool) +static mpf_bridge_t* mpf_bridge_base_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const char *name, apr_pool_t *pool) { mpf_bridge_t *bridge; if(!source || !sink) { @@ -103,20 +113,21 @@ static mpf_bridge_t* mpf_bridge_base_create(mpf_audio_stream_t *source, mpf_audi bridge = apr_palloc(pool,sizeof(mpf_bridge_t)); bridge->source = source; bridge->sink = sink; - mpf_object_init(&bridge->base); + bridge->codec = NULL; + mpf_object_init(&bridge->base,name); bridge->base.destroy = mpf_bridge_destroy; bridge->base.process = mpf_bridge_process; bridge->base.trace = mpf_bridge_trace; return bridge; } -static mpf_object_t* mpf_linear_bridge_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, apr_pool_t *pool) +static mpf_object_t* mpf_linear_bridge_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, const char *name, apr_pool_t *pool) { mpf_codec_descriptor_t *descriptor; apr_size_t frame_size; mpf_bridge_t *bridge; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Linear Audio Bridge"); - bridge = mpf_bridge_base_create(source,sink,pool); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Linear Audio Bridge %s",name); + bridge = mpf_bridge_base_create(source,sink,name,pool); if(!bridge) { return NULL; } @@ -136,13 +147,13 @@ static mpf_object_t* mpf_linear_bridge_create(mpf_audio_stream_t *source, mpf_au return &bridge->base; } -static mpf_object_t* mpf_null_bridge_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, apr_pool_t *pool) +static mpf_object_t* mpf_null_bridge_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, const char *name, apr_pool_t *pool) { mpf_codec_t *codec; apr_size_t frame_size; mpf_bridge_t *bridge; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Null Audio Bridge"); - bridge = mpf_bridge_base_create(source,sink,pool); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Null Audio Bridge %s",name); + bridge = mpf_bridge_base_create(source,sink,name,pool); if(!bridge) { return NULL; } @@ -154,6 +165,7 @@ static mpf_object_t* mpf_null_bridge_create(mpf_audio_stream_t *source, mpf_audi } frame_size = mpf_codec_frame_size_calculate(source->rx_descriptor,codec->attribs); + bridge->codec = codec; bridge->frame.codec_frame.size = frame_size; bridge->frame.codec_frame.buffer = apr_palloc(pool,frame_size); @@ -167,7 +179,12 @@ static mpf_object_t* mpf_null_bridge_create(mpf_audio_stream_t *source, mpf_audi return &bridge->base; } -MPF_DECLARE(mpf_object_t*) mpf_bridge_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, apr_pool_t *pool) +MPF_DECLARE(mpf_object_t*) mpf_bridge_create( + mpf_audio_stream_t *source, + mpf_audio_stream_t *sink, + const mpf_codec_manager_t *codec_manager, + const char *name, + apr_pool_t *pool) { if(!source || !sink) { return NULL; @@ -179,7 +196,7 @@ MPF_DECLARE(mpf_object_t*) mpf_bridge_create(mpf_audio_stream_t *source, mpf_aud } if(mpf_codec_descriptors_match(source->rx_descriptor,sink->tx_descriptor) == TRUE) { - return mpf_null_bridge_create(source,sink,codec_manager,pool); + return mpf_null_bridge_create(source,sink,codec_manager,name,pool); } if(mpf_codec_lpcm_descriptor_match(source->rx_descriptor) == FALSE) { @@ -209,5 +226,5 @@ MPF_DECLARE(mpf_object_t*) mpf_bridge_create(mpf_audio_stream_t *source, mpf_aud source = resampler; } - return mpf_linear_bridge_create(source,sink,codec_manager,pool); + return mpf_linear_bridge_create(source,sink,codec_manager,name,pool); } diff --git a/libs/unimrcp/libs/mpf/src/mpf_buffer.c b/libs/unimrcp/libs/mpf/src/mpf_buffer.c index f128760277..b253d6ae02 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_buffer.c +++ b/libs/unimrcp/libs/mpf/src/mpf_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_buffer.c 1709 2010-05-24 17:12:11Z achaloyan $ */ #ifdef WIN32 @@ -165,7 +167,7 @@ apt_bool_t mpf_buffer_frame_read(mpf_buffer_t *buffer, mpf_frame_t *media_frame) return TRUE; } -apr_size_t mpf_buffer_get_size(mpf_buffer_t *buffer) +apr_size_t mpf_buffer_get_size(const mpf_buffer_t *buffer) { return buffer->size; } diff --git a/libs/unimrcp/libs/mpf/src/mpf_codec_descriptor.c b/libs/unimrcp/libs/mpf/src/mpf_codec_descriptor.c index 2995cf94a5..b493f4959b 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_codec_descriptor.c +++ b/libs/unimrcp/libs/mpf/src/mpf_codec_descriptor.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_codec_descriptor.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_codec_descriptor.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_codec_g711.c b/libs/unimrcp/libs/mpf/src/mpf_codec_g711.c index ab20a278f9..5a4a66de2e 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_codec_g711.c +++ b/libs/unimrcp/libs/mpf/src/mpf_codec_g711.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_codec_g711.c 1686 2010-05-08 18:46:08Z achaloyan $ */ #include "mpf_codec.h" @@ -70,6 +72,17 @@ static apt_bool_t g711u_decode(mpf_codec_t *codec, const mpf_codec_frame_t *fram return TRUE; } +static apt_bool_t g711u_init(mpf_codec_t *codec, mpf_codec_frame_t *frame_out) +{ + apr_size_t i; + unsigned char *encode_buf = frame_out->buffer; + for(i=0; isize; i++) { + encode_buf[i] = linear_to_ulaw(0); + } + + return TRUE; +} + static apt_bool_t g711a_encode(mpf_codec_t *codec, const mpf_codec_frame_t *frame_in, mpf_codec_frame_t *frame_out) { const apr_int16_t *decode_buf; @@ -106,12 +119,24 @@ static apt_bool_t g711a_decode(mpf_codec_t *codec, const mpf_codec_frame_t *fram return TRUE; } +static apt_bool_t g711a_init(mpf_codec_t *codec, mpf_codec_frame_t *frame_out) +{ + apr_size_t i; + unsigned char *encode_buf = frame_out->buffer; + for(i=0; isize; i++) { + encode_buf[i] = linear_to_alaw(0); + } + + return TRUE; +} + static const mpf_codec_vtable_t g711u_vtable = { g711_open, g711_close, g711u_encode, g711u_decode, - NULL + NULL, + g711u_init }; static const mpf_codec_vtable_t g711a_vtable = { @@ -119,7 +144,8 @@ static const mpf_codec_vtable_t g711a_vtable = { g711_close, g711a_encode, g711a_decode, - NULL + NULL, + g711a_init }; static const mpf_codec_descriptor_t g711u_descriptor = { diff --git a/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c b/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c index 7f342b0a31..7e6b091100 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c +++ b/libs/unimrcp/libs/mpf/src/mpf_codec_linear.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_codec_linear.c 1686 2010-05-08 18:46:08Z achaloyan $ */ #define APR_WANT_BYTEFUNC @@ -71,6 +73,7 @@ static const mpf_codec_vtable_t l16_vtable = { l16_close, l16_encode, l16_decode, + NULL, NULL }; diff --git a/libs/unimrcp/libs/mpf/src/mpf_codec_manager.c b/libs/unimrcp/libs/mpf/src/mpf_codec_manager.c index b83581a25a..fa0482a610 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_codec_manager.c +++ b/libs/unimrcp/libs/mpf/src/mpf_codec_manager.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_codec_manager.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/libs/mpf/src/mpf_context.c b/libs/unimrcp/libs/mpf/src/mpf_context.c index c6978d8e37..bdd0034ecb 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_context.c +++ b/libs/unimrcp/libs/mpf/src/mpf_context.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_context.c 1709 2010-05-24 17:12:11Z achaloyan $ */ #ifdef WIN32 @@ -46,6 +48,8 @@ struct mpf_context_t { mpf_context_factory_t *factory; /** Pool to allocate memory from */ apr_pool_t *pool; + /** Informative name of the context used for debugging */ + const char *name; /** External object */ void *obj; @@ -109,6 +113,7 @@ MPF_DECLARE(apt_bool_t) mpf_context_factory_process(mpf_context_factory_t *facto MPF_DECLARE(mpf_context_t*) mpf_context_create( mpf_context_factory_t *factory, + const char *name, void *obj, apr_size_t max_termination_count, apr_pool_t *pool) @@ -120,6 +125,10 @@ MPF_DECLARE(mpf_context_t*) mpf_context_create( context->factory = factory; context->obj = obj; context->pool = pool; + context->name = name; + if(!context->name) { + context->name = apr_psprintf(pool,"0x%pp",context); + } context->capacity = max_termination_count; context->count = 0; context->mpf_objects = apr_array_make(pool,1,sizeof(mpf_object_t*)); @@ -154,7 +163,7 @@ MPF_DECLARE(apt_bool_t) mpf_context_destroy(mpf_context_t *context) return TRUE; } -MPF_DECLARE(void*) mpf_context_object_get(mpf_context_t *context) +MPF_DECLARE(void*) mpf_context_object_get(const mpf_context_t *context) { return context->obj; } @@ -169,11 +178,10 @@ MPF_DECLARE(apt_bool_t) mpf_context_termination_add(mpf_context_t *context, mpf_ continue; } if(!context->count) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Context"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Media Context %s",context->name); APR_RING_INSERT_TAIL(&context->factory->head,context,mpf_context_t,link); } - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Termination"); header_item->termination = termination; header_item->tx_count = 0; header_item->rx_count = 0; @@ -200,7 +208,6 @@ MPF_DECLARE(apt_bool_t) mpf_context_termination_subtract(mpf_context_t *context, return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract Termination"); for(j=0,k=0; jcapacity && kcount; j++) { header_item2 = &context->header[j]; if(!header_item2->termination) { @@ -227,7 +234,7 @@ MPF_DECLARE(apt_bool_t) mpf_context_termination_subtract(mpf_context_t *context, termination->slot = (apr_size_t)-1; context->count--; if(!context->count) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Remove Context"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Remove Media Context %s",context->name); APR_RING_REMOVE(context,link); } return TRUE; @@ -463,6 +470,7 @@ static mpf_object_t* mpf_context_bridge_create(mpf_context_t *context, apr_size_ header_item1->termination->audio_stream, header_item2->termination->audio_stream, header_item1->termination->codec_manager, + context->name, context->pool); } } @@ -494,6 +502,7 @@ static mpf_object_t* mpf_context_multiplier_create(mpf_context_t *context, apr_s sink_arr, header_item1->tx_count, header_item1->termination->codec_manager, + context->name, context->pool); } @@ -522,6 +531,7 @@ static mpf_object_t* mpf_context_mixer_create(mpf_context_t *context, apr_size_t header_item1->rx_count, header_item1->termination->audio_stream, header_item1->termination->codec_manager, + context->name, context->pool); } diff --git a/libs/unimrcp/libs/mpf/src/mpf_decoder.c b/libs/unimrcp/libs/mpf/src/mpf_decoder.c index 878dbbf459..e01d438803 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_decoder.c +++ b/libs/unimrcp/libs/mpf/src/mpf_decoder.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_decoder.c 1530 2010-02-19 18:40:08Z achaloyan $ */ #include "mpf_decoder.h" @@ -36,12 +38,14 @@ static apt_bool_t mpf_decoder_destroy(mpf_audio_stream_t *stream) static apt_bool_t mpf_decoder_open(mpf_audio_stream_t *stream, mpf_codec_t *codec) { mpf_decoder_t *decoder = stream->obj; + mpf_codec_open(decoder->codec); return mpf_audio_stream_rx_open(decoder->source,decoder->codec); } static apt_bool_t mpf_decoder_close(mpf_audio_stream_t *stream) { mpf_decoder_t *decoder = stream->obj; + mpf_codec_close(decoder->codec); return mpf_audio_stream_rx_close(decoder->source); } diff --git a/libs/unimrcp/libs/mpf/src/mpf_dtmf_detector.c b/libs/unimrcp/libs/mpf/src/mpf_dtmf_detector.c index e40096a2ed..f22da57a8d 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_dtmf_detector.c +++ b/libs/unimrcp/libs/mpf/src/mpf_dtmf_detector.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Tomas Valenta, Arsen Chaloyan + * Copyright 2009-2010 Tomas Valenta, Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_dtmf_detector.c 1788 2010-11-22 19:45:38Z tomas.valenta@speechtech.cz $ */ #include "mpf_dtmf_detector.h" @@ -217,8 +219,8 @@ static void goertzel_energies_digit(struct mpf_dtmf_detector_t *detector) } } - if ((reng < 8.0e8 * detector->wsamples / GOERTZEL_SAMPLES_8K) || - (ceng < 8.0e8 * detector->wsamples / GOERTZEL_SAMPLES_8K)) + if ((reng < 8.0e10 * detector->wsamples / GOERTZEL_SAMPLES_8K) || + (ceng < 8.0e10 * detector->wsamples / GOERTZEL_SAMPLES_8K)) { /* energy not high enough */ } else if ((ceng > reng) && (reng < ceng * 0.398)) { /* twist > 4dB, error */ @@ -233,7 +235,7 @@ static void goertzel_energies_digit(struct mpf_dtmf_detector_t *detector) */ } else if ((ceng < reng) && (ceng < reng * 0.158)) { /* twist > 8db, error */ /* Reverse twist check failed */ - } else if (0.025 * detector->totenergy > (reng + ceng)) { /* 16db */ + } else if (0.25 * detector->totenergy > (reng + ceng)) { /* 16db */ /* Signal energy to total energy ratio test failed */ } else { digit = freq2digits[rmax][cmax - DTMF_FREQUENCIES/2]; diff --git a/libs/unimrcp/libs/mpf/src/mpf_dtmf_generator.c b/libs/unimrcp/libs/mpf/src/mpf_dtmf_generator.c index 836561db01..a31240be4a 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_dtmf_generator.c +++ b/libs/unimrcp/libs/mpf/src/mpf_dtmf_generator.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Tomas Valenta, Arsen Chaloyan + * Copyright 2009-2010 Tomas Valenta, Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_dtmf_generator.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_dtmf_generator.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_encoder.c b/libs/unimrcp/libs/mpf/src/mpf_encoder.c index 797600192f..c80d98fb45 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_encoder.c +++ b/libs/unimrcp/libs/mpf/src/mpf_encoder.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_encoder.c 1530 2010-02-19 18:40:08Z achaloyan $ */ #include "mpf_encoder.h" @@ -36,12 +38,14 @@ static apt_bool_t mpf_encoder_destroy(mpf_audio_stream_t *stream) static apt_bool_t mpf_encoder_open(mpf_audio_stream_t *stream, mpf_codec_t *codec) { mpf_encoder_t *encoder = stream->obj; + mpf_codec_open(encoder->codec); return mpf_audio_stream_tx_open(encoder->sink,encoder->codec); } static apt_bool_t mpf_encoder_close(mpf_audio_stream_t *stream) { mpf_encoder_t *encoder = stream->obj; + mpf_codec_close(encoder->codec); return mpf_audio_stream_tx_close(encoder->sink); } diff --git a/libs/unimrcp/libs/mpf/src/mpf_engine.c b/libs/unimrcp/libs/mpf/src/mpf_engine.c index 087b248884..06ef5db33f 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_engine.c +++ b/libs/unimrcp/libs/mpf/src/mpf_engine.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_engine.c 1709 2010-05-24 17:12:11Z achaloyan $ */ #include "mpf_engine.h" @@ -21,12 +23,11 @@ #include "mpf_scheduler.h" #include "mpf_codec_descriptor.h" #include "mpf_codec_manager.h" -#include "mpf_timer_manager.h" #include "apt_obj_list.h" #include "apt_cyclic_queue.h" #include "apt_log.h" -#define MPF_TASK_NAME "Media Processing Engine" +#define MPF_TIMER_RESOLUTION 100 /* 100 ms */ struct mpf_engine_t { apr_pool_t *pool; @@ -36,11 +37,12 @@ struct mpf_engine_t { apt_cyclic_queue_t *request_queue; mpf_context_factory_t *context_factory; mpf_scheduler_t *scheduler; - mpf_timer_manager_t *timer_manager; + apt_timer_queue_t *timer_queue; const mpf_codec_manager_t *codec_manager; }; -static void mpf_engine_main(mpf_scheduler_t *scheduler, void *data); +static void mpf_engine_main(mpf_scheduler_t *scheduler, void *obj); +static void mpf_engine_timer_proc(mpf_scheduler_t *scheduler, void *obj); static apt_bool_t mpf_engine_destroy(apt_task_t *task); static apt_bool_t mpf_engine_start(apt_task_t *task); static apt_bool_t mpf_engine_terminate(apt_task_t *task); @@ -52,7 +54,7 @@ mpf_codec_t* mpf_codec_l16_create(apr_pool_t *pool); mpf_codec_t* mpf_codec_g711u_create(apr_pool_t *pool); mpf_codec_t* mpf_codec_g711a_create(apr_pool_t *pool); -MPF_DECLARE(mpf_engine_t*) mpf_engine_create(apr_pool_t *pool) +MPF_DECLARE(mpf_engine_t*) mpf_engine_create(const char *id, apr_pool_t *pool) { apt_task_vtable_t *vtable; apt_task_msg_pool_t *msg_pool; @@ -64,13 +66,13 @@ MPF_DECLARE(mpf_engine_t*) mpf_engine_create(apr_pool_t *pool) msg_pool = apt_task_msg_pool_create_dynamic(sizeof(mpf_message_container_t),pool); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create "MPF_TASK_NAME); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create Media Engine [%s]",id); engine->task = apt_task_create(engine,msg_pool,pool); if(!engine->task) { return NULL; } - apt_task_name_set(engine->task,MPF_TASK_NAME); + apt_task_name_set(engine->task,id); vtable = apt_task_vtable_get(engine->task); if(vtable) { @@ -90,17 +92,19 @@ MPF_DECLARE(mpf_engine_t*) mpf_engine_create(apr_pool_t *pool) engine->scheduler = mpf_scheduler_create(engine->pool); mpf_scheduler_media_clock_set(engine->scheduler,CODEC_FRAME_TIME_BASE,mpf_engine_main,engine); - engine->timer_manager = mpf_timer_manager_create(engine->scheduler,engine->pool); + engine->timer_queue = apt_timer_queue_create(engine->pool); + mpf_scheduler_timer_clock_set(engine->scheduler,MPF_TIMER_RESOLUTION,mpf_engine_timer_proc,engine); return engine; } MPF_DECLARE(mpf_context_t*) mpf_engine_context_create( - mpf_engine_t *engine, - void *obj, - apr_size_t max_termination_count, + mpf_engine_t *engine, + const char *name, + void *obj, + apr_size_t max_termination_count, apr_pool_t *pool) { - return mpf_context_create(engine->context_factory,obj,max_termination_count,pool); + return mpf_context_create(engine->context_factory,name,obj,max_termination_count,pool); } MPF_DECLARE(apt_bool_t) mpf_engine_context_destroy(mpf_context_t *context) @@ -108,12 +112,12 @@ MPF_DECLARE(apt_bool_t) mpf_engine_context_destroy(mpf_context_t *context) return mpf_context_destroy(context); } -MPF_DECLARE(void*) mpf_engine_context_object_get(mpf_context_t *context) +MPF_DECLARE(void*) mpf_engine_context_object_get(const mpf_context_t *context) { return mpf_context_object_get(context); } -MPF_DECLARE(apt_task_t*) mpf_task_get(mpf_engine_t *engine) +MPF_DECLARE(apt_task_t*) mpf_task_get(const mpf_engine_t *engine) { return engine->task; } @@ -223,7 +227,7 @@ static apt_bool_t mpf_engine_destroy(apt_task_t *task) { mpf_engine_t *engine = apt_task_object_get(task); - mpf_timer_manager_destroy(engine->timer_manager); + apt_timer_queue_destroy(engine->timer_queue); mpf_scheduler_destroy(engine->scheduler); mpf_context_factory_destroy(engine->context_factory); apt_cyclic_queue_destroy(engine->request_queue); @@ -282,7 +286,7 @@ static apt_bool_t mpf_engine_msg_signal(apt_task_t *task, apt_task_msg_t *msg) apr_thread_mutex_lock(engine->request_queue_guard); if(apt_cyclic_queue_push(engine->request_queue,msg) == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_ERROR,"MPF Request Queue is Full"); + apt_log(APT_LOG_MARK,APT_PRIO_ERROR,"MPF Request Queue is Full [%s]",apt_task_name_get(task)); } apr_thread_mutex_unlock(engine->request_queue_guard); return TRUE; @@ -299,7 +303,6 @@ static apt_bool_t mpf_engine_msg_process(apt_task_t *task, apt_task_msg_t *msg) mpf_termination_t *termination; const mpf_message_t *mpf_request; const mpf_message_container_t *request = (const mpf_message_container_t*) msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process MPF Message"); response_msg = apt_task_msg_get(engine->task); response_msg->type = engine->task_msg_type; @@ -324,7 +327,7 @@ static apt_bool_t mpf_engine_msg_process(apt_task_t *task, apt_task_msg_t *msg) termination->event_handler_obj = engine; termination->event_handler = mpf_engine_event_raise; termination->codec_manager = engine->codec_manager; - termination->timer_manager = engine->timer_manager; + termination->timer_queue = engine->timer_queue; mpf_termination_add(termination,mpf_request->descriptor); if(mpf_context_termination_add(context,termination) == FALSE) { @@ -383,9 +386,9 @@ static apt_bool_t mpf_engine_msg_process(apt_task_t *task, apt_task_msg_t *msg) return apt_task_msg_parent_signal(engine->task,response_msg); } -static void mpf_engine_main(mpf_scheduler_t *scheduler, void *data) +static void mpf_engine_main(mpf_scheduler_t *scheduler, void *obj) { - mpf_engine_t *engine = data; + mpf_engine_t *engine = obj; apt_task_msg_t *msg; /* process request queue */ @@ -403,6 +406,12 @@ static void mpf_engine_main(mpf_scheduler_t *scheduler, void *data) mpf_context_factory_process(engine->context_factory); } +static void mpf_engine_timer_proc(mpf_scheduler_t *scheduler, void *obj) +{ + mpf_engine_t *engine = obj; + apt_timer_queue_advance(engine->timer_queue,MPF_TIMER_RESOLUTION); +} + MPF_DECLARE(mpf_codec_manager_t*) mpf_engine_codec_manager_create(apr_pool_t *pool) { mpf_codec_manager_t *codec_manager = mpf_codec_manager_create(4,pool); @@ -431,3 +440,8 @@ MPF_DECLARE(apt_bool_t) mpf_engine_scheduler_rate_set(mpf_engine_t *engine, unsi { return mpf_scheduler_rate_set(engine->scheduler,rate); } + +MPF_DECLARE(const char*) mpf_engine_id_get(const mpf_engine_t *engine) +{ + return apt_task_name_get(engine->task); +} diff --git a/libs/unimrcp/libs/mpf/src/mpf_file_termination_factory.c b/libs/unimrcp/libs/mpf/src/mpf_file_termination_factory.c index dd1bc6e280..5da0815fe3 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_file_termination_factory.c +++ b/libs/unimrcp/libs/mpf/src/mpf_file_termination_factory.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_file_termination_factory.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_termination.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_frame_buffer.c b/libs/unimrcp/libs/mpf/src/mpf_frame_buffer.c index d93e5c56aa..6f1d568377 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_frame_buffer.c +++ b/libs/unimrcp/libs/mpf/src/mpf_frame_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_frame_buffer.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_frame_buffer.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_jitter_buffer.c b/libs/unimrcp/libs/mpf/src/mpf_jitter_buffer.c index 0235e762c4..5ddfb2e7be 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_jitter_buffer.c +++ b/libs/unimrcp/libs/mpf/src/mpf_jitter_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_jitter_buffer.c 1802 2011-05-13 02:43:12Z achaloyan $ */ #include "mpf_jitter_buffer.h" @@ -102,6 +104,10 @@ mpf_jitter_buffer_t* mpf_jitter_buffer_create(mpf_jb_config_t *jb_config, mpf_co frame->codec_frame.buffer = jb->raw_data + i*jb->frame_size; } + if(jb->config->initial_playout_delay % CODEC_FRAME_TIME_BASE != 0) { + jb->config->initial_playout_delay += CODEC_FRAME_TIME_BASE - jb->config->initial_playout_delay % CODEC_FRAME_TIME_BASE; + } + jb->playout_delay_ts = (apr_uint32_t)(jb->config->initial_playout_delay * descriptor->channel_count * descriptor->sampling_rate / 1000); @@ -149,17 +155,28 @@ static APR_INLINE jb_result_t mpf_jitter_buffer_write_prepare(mpf_jitter_buffer_ *write_ts = ts - jb->write_ts_offset + jb->playout_delay_ts; if(*write_ts % jb->frame_ts != 0) { /* not frame alligned */ + JB_TRACE("JB write ts=%"APR_SIZE_T_FMT" not alligned -> discard\n",write_ts); return JB_DISCARD_NOT_ALLIGNED; } return JB_OK; } -jb_result_t mpf_jitter_buffer_write(mpf_jitter_buffer_t *jb, void *buffer, apr_size_t size, apr_uint32_t ts) +jb_result_t mpf_jitter_buffer_write(mpf_jitter_buffer_t *jb, void *buffer, apr_size_t size, apr_uint32_t ts, apr_byte_t marker) { mpf_frame_t *media_frame; apr_uint32_t write_ts; apr_size_t available_frame_count; - jb_result_t result = mpf_jitter_buffer_write_prepare(jb,ts,&write_ts); + jb_result_t result; + + if(marker) { + /* new talkspurt */ + if(jb->write_ts <= jb->read_ts) { + /* buffer is empty => it's safe to restart */ + mpf_jitter_buffer_restart(jb); + } + } + + result = mpf_jitter_buffer_write_prepare(jb,ts,&write_ts); if(result != JB_OK) { return result; } diff --git a/libs/unimrcp/libs/mpf/src/mpf_mixer.c b/libs/unimrcp/libs/mpf/src/mpf_mixer.c index 9d46990c30..3c36dd449d 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_mixer.c +++ b/libs/unimrcp/libs/mpf/src/mpf_mixer.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_mixer.c 1693 2010-05-16 18:33:07Z achaloyan $ */ #include "mpf_mixer.h" @@ -90,6 +92,7 @@ static apt_bool_t mpf_mixer_destroy(mpf_object_t *object) mpf_audio_stream_t *source; mpf_mixer_t *mixer = (mpf_mixer_t*) object; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Mixer %s",object->name); for(i=0; isource_count; i++) { source = mixer->source_arr[i]; if(source) { @@ -126,7 +129,9 @@ static void mpf_mixer_trace(mpf_object_t *object) mpf_audio_stream_trace(mixer->sink,STREAM_DIRECTION_SEND,&output); *output.pos = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,output.text.buf); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Media Path %s %s", + object->name, + output.text.buf); } MPF_DECLARE(mpf_object_t*) mpf_mixer_create( @@ -134,6 +139,7 @@ MPF_DECLARE(mpf_object_t*) mpf_mixer_create( apr_size_t source_count, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, + const char *name, apr_pool_t *pool) { apr_size_t i; @@ -145,11 +151,12 @@ MPF_DECLARE(mpf_object_t*) mpf_mixer_create( return NULL; } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Mixer %s",name); mixer = apr_palloc(pool,sizeof(mpf_mixer_t)); mixer->source_arr = NULL; mixer->source_count = 0; mixer->sink = NULL; - mpf_object_init(&mixer->base); + mpf_object_init(&mixer->base,name); mixer->base.process = mpf_mixer_process; mixer->base.destroy = mpf_mixer_destroy; mixer->base.trace = mpf_mixer_trace; diff --git a/libs/unimrcp/libs/mpf/src/mpf_multiplier.c b/libs/unimrcp/libs/mpf/src/mpf_multiplier.c index 7ea9b88690..2014932841 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_multiplier.c +++ b/libs/unimrcp/libs/mpf/src/mpf_multiplier.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_multiplier.c 1693 2010-05-16 18:33:07Z achaloyan $ */ #include "mpf_multiplier.h" @@ -69,6 +71,7 @@ static apt_bool_t mpf_multiplier_destroy(mpf_object_t *object) mpf_audio_stream_t *sink; mpf_multiplier_t *multiplier = (mpf_multiplier_t*) object; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Multiplier %s",object->name); mpf_audio_stream_rx_close(multiplier->source); for(i=0; isink_count; i++) { sink = multiplier->sink_arr[i]; @@ -105,7 +108,9 @@ static void mpf_multiplier_trace(mpf_object_t *object) } *output.pos = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,output.text.buf); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Media Path %s %s", + object->name, + output.text.buf); } MPF_DECLARE(mpf_object_t*) mpf_multiplier_create( @@ -113,6 +118,7 @@ MPF_DECLARE(mpf_object_t*) mpf_multiplier_create( mpf_audio_stream_t **sink_arr, apr_size_t sink_count, const mpf_codec_manager_t *codec_manager, + const char *name, apr_pool_t *pool) { apr_size_t i; @@ -124,11 +130,12 @@ MPF_DECLARE(mpf_object_t*) mpf_multiplier_create( return NULL; } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Multiplier %s",name); multiplier = apr_palloc(pool,sizeof(mpf_multiplier_t)); multiplier->source = NULL; multiplier->sink_arr = NULL; multiplier->sink_count = 0; - mpf_object_init(&multiplier->base); + mpf_object_init(&multiplier->base,name); multiplier->base.process = mpf_multiplier_process; multiplier->base.destroy = mpf_multiplier_destroy; multiplier->base.trace = mpf_multiplier_trace; diff --git a/libs/unimrcp/libs/mpf/src/mpf_named_event.c b/libs/unimrcp/libs/mpf/src/mpf_named_event.c index f8bc75363f..22c319dae4 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_named_event.c +++ b/libs/unimrcp/libs/mpf/src/mpf_named_event.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_named_event.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_named_event.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_resampler.c b/libs/unimrcp/libs/mpf/src/mpf_resampler.c index 113ffac8fb..fe4a45c9fc 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_resampler.c +++ b/libs/unimrcp/libs/mpf/src/mpf_resampler.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_resampler.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_resampler.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_rtp_attribs.c b/libs/unimrcp/libs/mpf/src/mpf_rtp_attribs.c index a34f05fc93..5e9e184f0f 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_rtp_attribs.c +++ b/libs/unimrcp/libs/mpf/src/mpf_rtp_attribs.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_attribs.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "apt_string_table.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_rtp_stream.c b/libs/unimrcp/libs/mpf/src/mpf_rtp_stream.c index 0e8ac028a9..f94b3295c2 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_rtp_stream.c +++ b/libs/unimrcp/libs/mpf/src/mpf_rtp_stream.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,14 +12,16 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_stream.c 1802 2011-05-13 02:43:12Z achaloyan $ */ #include #include "apt_net.h" +#include "apt_timer_queue.h" #include "mpf_rtp_stream.h" #include "mpf_termination.h" #include "mpf_codec_manager.h" -#include "mpf_timer_manager.h" #include "mpf_rtp_header.h" #include "mpf_rtcp_packet.h" #include "mpf_rtp_defs.h" @@ -55,6 +57,7 @@ struct mpf_rtp_stream_t { rtp_receiver_t receiver; mpf_rtp_config_t *config; + mpf_rtp_settings_t *settings; apr_socket_t *rtp_socket; apr_socket_t *rtcp_socket; @@ -63,8 +66,8 @@ struct mpf_rtp_stream_t { apr_sockaddr_t *rtcp_l_sockaddr; apr_sockaddr_t *rtcp_r_sockaddr; - mpf_timer_t *rtcp_tx_timer; - mpf_timer_t *rtcp_rx_timer; + apt_timer_t *rtcp_tx_timer; + apt_timer_t *rtcp_rx_timer; apr_pool_t *pool; }; @@ -92,11 +95,11 @@ static void mpf_rtp_socket_pair_close(mpf_rtp_stream_t *stream); static apt_bool_t mpf_rtcp_report_send(mpf_rtp_stream_t *stream); static apt_bool_t mpf_rtcp_bye_send(mpf_rtp_stream_t *stream, apt_str_t *reason); -static void mpf_rtcp_tx_timer_proc(mpf_timer_t *timer, void *obj); -static void mpf_rtcp_rx_timer_proc(mpf_timer_t *timer, void *obj); +static void mpf_rtcp_tx_timer_proc(apt_timer_t *timer, void *obj); +static void mpf_rtcp_rx_timer_proc(apt_timer_t *timer, void *obj); -MPF_DECLARE(mpf_audio_stream_t*) mpf_rtp_stream_create(mpf_termination_t *termination, mpf_rtp_config_t *config, apr_pool_t *pool) +MPF_DECLARE(mpf_audio_stream_t*) mpf_rtp_stream_create(mpf_termination_t *termination, mpf_rtp_config_t *config, mpf_rtp_settings_t *settings, apr_pool_t *pool) { mpf_rtp_stream_t *rtp_stream = apr_palloc(pool,sizeof(mpf_rtp_stream_t)); mpf_stream_capabilities_t *capabilities = mpf_stream_capabilities_create(STREAM_DIRECTION_DUPLEX,pool); @@ -111,6 +114,7 @@ MPF_DECLARE(mpf_audio_stream_t*) mpf_rtp_stream_create(mpf_termination_t *termin rtp_stream->base = audio_stream; rtp_stream->pool = pool; rtp_stream->config = config; + rtp_stream->settings = settings; rtp_stream->local_media = NULL; rtp_stream->remote_media = NULL; rtp_stream->rtp_socket = NULL; @@ -126,16 +130,16 @@ MPF_DECLARE(mpf_audio_stream_t*) mpf_rtp_stream_create(mpf_termination_t *termin rtp_transmitter_init(&rtp_stream->transmitter); rtp_stream->transmitter.sr_stat.ssrc = (apr_uint32_t)apr_time_now(); - if(config->rtcp == TRUE) { - if(config->rtcp_tx_interval) { - rtp_stream->rtcp_tx_timer = mpf_timer_create( - termination->timer_manager, + if(settings->rtcp == TRUE) { + if(settings->rtcp_tx_interval) { + rtp_stream->rtcp_tx_timer = apt_timer_create( + termination->timer_queue, mpf_rtcp_tx_timer_proc, rtp_stream, pool); } - if(config->rtcp_rx_resolution) { - rtp_stream->rtcp_rx_timer = mpf_timer_create( - termination->timer_manager, + if(settings->rtcp_rx_resolution) { + rtp_stream->rtcp_rx_timer = apt_timer_create( + termination->timer_queue, mpf_rtcp_rx_timer_proc, rtp_stream, pool); } @@ -163,21 +167,25 @@ static apt_bool_t mpf_rtp_stream_local_media_create(mpf_rtp_stream_t *rtp_stream } if(local_media->port == 0) { /* RTP port management */ - apr_port_t first_port_in_search = rtp_stream->config->rtp_port_cur; + mpf_rtp_config_t *rtp_config = rtp_stream->config; + apr_port_t first_port_in_search = rtp_config->rtp_port_cur; apt_bool_t is_port_ok = FALSE; do { - local_media->port = rtp_stream->config->rtp_port_cur; - rtp_stream->config->rtp_port_cur += 2; - if(rtp_stream->config->rtp_port_cur == rtp_stream->config->rtp_port_max) { - rtp_stream->config->rtp_port_cur = rtp_stream->config->rtp_port_min; + local_media->port = rtp_config->rtp_port_cur; + rtp_config->rtp_port_cur += 2; + if(rtp_config->rtp_port_cur == rtp_config->rtp_port_max) { + rtp_config->rtp_port_cur = rtp_config->rtp_port_min; } if(mpf_rtp_socket_pair_create(rtp_stream,local_media) == TRUE) { is_port_ok = TRUE; } - } while((is_port_ok == FALSE) && (first_port_in_search != rtp_stream->config->rtp_port_cur)); + } while((is_port_ok == FALSE) && (first_port_in_search != rtp_config->rtp_port_cur)); if(is_port_ok == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find Free RTP Port"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find Free RTP Port %s:[%hu,%hu]", + rtp_config->ip.buf, + rtp_config->rtp_port_min, + rtp_config->rtp_port_max); local_media->state = MPF_MEDIA_DISABLED; status = FALSE; } @@ -187,12 +195,12 @@ static apt_bool_t mpf_rtp_stream_local_media_create(mpf_rtp_stream_t *rtp_stream status = FALSE; } - if(rtp_stream->config->ptime) { - local_media->ptime = rtp_stream->config->ptime; + if(rtp_stream->settings->ptime) { + local_media->ptime = rtp_stream->settings->ptime; } if(mpf_codec_list_is_empty(&local_media->codec_list) == TRUE) { - if(mpf_codec_list_is_empty(&rtp_stream->config->codec_list) == TRUE) { + if(mpf_codec_list_is_empty(&rtp_stream->settings->codec_list) == TRUE) { mpf_codec_manager_codec_list_get( rtp_stream->base->termination->codec_manager, &local_media->codec_list, @@ -200,7 +208,7 @@ static apt_bool_t mpf_rtp_stream_local_media_create(mpf_rtp_stream_t *rtp_stream } else { mpf_codec_list_copy(&local_media->codec_list, - &rtp_stream->config->codec_list, + &rtp_stream->settings->codec_list, rtp_stream->pool); } @@ -297,10 +305,10 @@ static apt_bool_t mpf_rtp_stream_media_negotiate(mpf_rtp_stream_t *rtp_stream) } if(rtp_stream->rtcp_tx_timer) { - mpf_timer_set(rtp_stream->rtcp_tx_timer,rtp_stream->config->rtcp_tx_interval); + apt_timer_set(rtp_stream->rtcp_tx_timer,rtp_stream->settings->rtcp_tx_interval); } if(rtp_stream->rtcp_rx_timer) { - mpf_timer_set(rtp_stream->rtcp_rx_timer,rtp_stream->config->rtcp_rx_resolution); + apt_timer_set(rtp_stream->rtcp_rx_timer,rtp_stream->settings->rtcp_rx_resolution); } } else if(rtp_stream->state == MPF_MEDIA_ENABLED && remote_media->state == MPF_MEDIA_DISABLED) { @@ -313,12 +321,12 @@ static apt_bool_t mpf_rtp_stream_media_negotiate(mpf_rtp_stream_t *rtp_stream) } if(rtp_stream->rtcp_tx_timer) { - mpf_timer_kill(rtp_stream->rtcp_tx_timer); + apt_timer_kill(rtp_stream->rtcp_tx_timer); } if(rtp_stream->rtcp_rx_timer) { - mpf_timer_kill(rtp_stream->rtcp_rx_timer); + apt_timer_kill(rtp_stream->rtcp_rx_timer); } - if(rtp_stream->config->rtcp == TRUE && rtp_stream->config->rtcp_bye_policy != RTCP_BYE_DISABLE) { + if(rtp_stream->settings->rtcp == TRUE && rtp_stream->settings->rtcp_bye_policy != RTCP_BYE_DISABLE) { apt_str_t reason = {RTCP_BYE_SESSION_ENDED, sizeof(RTCP_BYE_SESSION_ENDED)-1}; mpf_rtcp_bye_send(rtp_stream,&reason); } @@ -337,7 +345,7 @@ static apt_bool_t mpf_rtp_stream_media_negotiate(mpf_rtp_stream_t *rtp_stream) } /* intersect local and remote codecs */ - if(rtp_stream->config->own_preferrence == TRUE) { + if(rtp_stream->settings->own_preferrence == TRUE) { mpf_codec_lists_intersect( &local_media->codec_list, &remote_media->codec_list); @@ -371,12 +379,12 @@ MPF_DECLARE(apt_bool_t) mpf_rtp_stream_remove(mpf_audio_stream_t *stream) } if(rtp_stream->rtcp_tx_timer) { - mpf_timer_kill(rtp_stream->rtcp_tx_timer); + apt_timer_kill(rtp_stream->rtcp_tx_timer); } if(rtp_stream->rtcp_rx_timer) { - mpf_timer_kill(rtp_stream->rtcp_rx_timer); + apt_timer_kill(rtp_stream->rtcp_rx_timer); } - if(rtp_stream->config->rtcp == TRUE && rtp_stream->config->rtcp_bye_policy != RTCP_BYE_DISABLE) { + if(rtp_stream->settings->rtcp == TRUE && rtp_stream->settings->rtcp_bye_policy != RTCP_BYE_DISABLE) { apt_str_t reason = {RTCP_BYE_SESSION_ENDED, sizeof(RTCP_BYE_SESSION_ENDED)-1}; mpf_rtcp_bye_send(rtp_stream,&reason); } @@ -451,7 +459,7 @@ static apt_bool_t mpf_rtp_rx_stream_open(mpf_audio_stream_t *stream, mpf_codec_t } receiver->jb = mpf_jitter_buffer_create( - &rtp_stream->config->jb_config, + &rtp_stream->settings->jb_config, stream->rx_descriptor, codec, rtp_stream->pool); @@ -461,7 +469,7 @@ static apt_bool_t mpf_rtp_rx_stream_open(mpf_audio_stream_t *stream, mpf_codec_t rtp_stream->rtp_l_sockaddr->port, rtp_stream->rtp_r_sockaddr->hostname, rtp_stream->rtp_r_sockaddr->port, - rtp_stream->config->jb_config.initial_playout_delay); + rtp_stream->settings->jb_config.initial_playout_delay); return TRUE; } @@ -484,14 +492,16 @@ static apt_bool_t mpf_rtp_rx_stream_close(mpf_audio_stream_t *stream) } mpf_jitter_buffer_destroy(receiver->jb); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close RTP Receiver %s:%hu <- %s:%hu [r:%lu l:%lu j:%lu]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close RTP Receiver %s:%hu <- %s:%hu [r:%u l:%u j:%u d:%u i:%u]", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port, rtp_stream->rtp_r_sockaddr->hostname, rtp_stream->rtp_r_sockaddr->port, receiver->stat.received_packets, receiver->stat.lost_packets, - receiver->rr_stat.jitter); + receiver->rr_stat.jitter, + receiver->stat.discarded_packets, + receiver->stat.ignored_packets); return TRUE; } @@ -557,8 +567,13 @@ static APR_INLINE void rtp_periodic_history_update(rtp_receiver_t *receiver) apr_uint32_t lost_interval; /* calculate expected packets */ - expected_packets = receiver->history.seq_cycles + - receiver->history.seq_num_max - receiver->history.seq_num_base + 1; + if(receiver->stat.received_packets) { + expected_packets = receiver->history.seq_cycles + + receiver->history.seq_num_max - receiver->history.seq_num_base + 1; + } + else { + expected_packets = 0; + } /* calculate expected interval */ expected_interval = expected_packets - receiver->periodic_history.expected_prior; @@ -709,7 +724,7 @@ static APR_INLINE void rtp_rx_failure_threshold_check(rtp_receiver_t *receiver) discarded = receiver->stat.discarded_packets - receiver->periodic_history.discarded_prior; if(discarded * 100 > received * DISCARDED_TO_RECEIVED_RATIO_THRESHOLD) { - /* failure threshold hired, restart */ + /* failure threshold reached -> restart */ rtp_rx_restart(receiver); } } @@ -733,7 +748,7 @@ static apt_bool_t rtp_rx_packet_receive(mpf_rtp_stream_t *rtp_stream, void *buff time = apr_time_now(); - RTP_TRACE("RTP time=%6lu ssrc=%8lx pt=%3u %cts=%9lu seq=%5u size=%lu\n", + RTP_TRACE("RTP time=%6u ssrc=%8x pt=%3u %cts=%9u seq=%5u size=%"APR_SIZE_T_FMT"\n", (apr_uint32_t)apr_time_usec(time), header->ssrc, header->type, (header->marker == 1) ? '*' : ' ', header->timestamp, header->sequence, size); @@ -761,7 +776,7 @@ static apt_bool_t rtp_rx_packet_receive(mpf_rtp_stream_t *rtp_stream, void *buff return FALSE; } - if(mpf_jitter_buffer_write(receiver->jb,buffer,size,header->timestamp) != JB_OK) { + if(mpf_jitter_buffer_write(receiver->jb,buffer,size,header->timestamp,(apr_byte_t)header->marker) != JB_OK) { receiver->stat.discarded_packets++; rtp_rx_failure_threshold_check(receiver); } @@ -825,8 +840,8 @@ static apt_bool_t mpf_rtp_tx_stream_open(mpf_audio_stream_t *stream, mpf_codec_t } if(!transmitter->ptime) { - if(rtp_stream->config && rtp_stream->config->ptime) { - transmitter->ptime = rtp_stream->config->ptime; + if(rtp_stream->settings && rtp_stream->settings->ptime) { + transmitter->ptime = rtp_stream->settings->ptime; } else { transmitter->ptime = 20; @@ -857,10 +872,10 @@ static apt_bool_t mpf_rtp_tx_stream_close(mpf_audio_stream_t *stream) if(!rtp_stream->rtp_l_sockaddr || !rtp_stream->rtp_r_sockaddr) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close RTP Transmitter %s:%hu -> %s:%hu [s:%lu o:%lu]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close RTP Transmitter %s:%hu -> %s:%hu [s:%u o:%u]", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port, - rtp_stream->rtp_l_sockaddr->hostname, + rtp_stream->rtp_r_sockaddr->hostname, rtp_stream->rtp_r_sockaddr->port, rtp_stream->transmitter.sr_stat.sent_packets, rtp_stream->transmitter.sr_stat.sent_octets); @@ -973,7 +988,7 @@ static apt_bool_t mpf_rtp_stream_transmit(mpf_audio_stream_t *stream, const mpf_ if(transmitter->current_frames == 0) { /* set inactivity (ptime alligned) */ transmitter->inactivity = 1; - if(rtp_stream->config->rtcp == TRUE && rtp_stream->config->rtcp_bye_policy == RTCP_BYE_PER_TALKSPURT) { + if(rtp_stream->settings->rtcp == TRUE && rtp_stream->settings->rtcp_bye_policy == RTCP_BYE_PER_TALKSPURT) { apt_str_t reason = {RTCP_BYE_TALKSPURT_ENDED, sizeof(RTCP_BYE_TALKSPURT_ENDED)-1}; mpf_rtcp_bye_send(rtp_stream,&reason); } @@ -1089,7 +1104,7 @@ static APR_INLINE void rtcp_sr_generate(mpf_rtp_stream_t *rtp_stream, rtcp_sr_st apt_ntp_time_get(&sr_stat->ntp_sec, &sr_stat->ntp_frac); sr_stat->rtp_ts = rtp_stream->transmitter.timestamp; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Generate RTCP SR [ssrc:%lu s:%lu o:%lu ts:%lu]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Generate RTCP SR [ssrc:%u s:%u o:%u ts:%u]", sr_stat->ssrc, sr_stat->sent_packets, sr_stat->sent_octets, @@ -1102,7 +1117,7 @@ static APR_INLINE void rtcp_rr_generate(mpf_rtp_stream_t *rtp_stream, rtcp_rr_st *rr_stat = rtp_stream->receiver.rr_stat; rr_stat->last_seq = rtp_stream->receiver.history.seq_num_max; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Generate RTCP RR [ssrc:%lu last_seq:%lu j:%lu lost:%lu frac:%d]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Generate RTCP RR [ssrc:%u last_seq:%u j:%u lost:%u frac:%d]", rr_stat->ssrc, rr_stat->last_seq, rr_stat->jitter, @@ -1302,7 +1317,7 @@ static apt_bool_t mpf_rtcp_bye_send(mpf_rtp_stream_t *rtp_stream, apt_str_t *rea static APR_INLINE void rtcp_sr_get(mpf_rtp_stream_t *rtp_stream, rtcp_sr_stat_t *sr_stat) { rtcp_sr_ntoh(sr_stat); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Get RTCP SR [ssrc:%lu s:%lu o:%lu ts:%lu]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Get RTCP SR [ssrc:%u s:%u o:%u ts:%u]", sr_stat->ssrc, sr_stat->sent_packets, sr_stat->sent_octets, @@ -1312,7 +1327,7 @@ static APR_INLINE void rtcp_sr_get(mpf_rtp_stream_t *rtp_stream, rtcp_sr_stat_t static APR_INLINE void rtcp_rr_get(mpf_rtp_stream_t *rtp_stream, rtcp_rr_stat_t *rr_stat) { rtcp_rr_ntoh(rr_stat); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Get RTCP RR [ssrc:%lu last_seq:%lu j:%lu lost:%lu frac:%d]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Get RTCP RR [ssrc:%u last_seq:%u j:%u lost:%u frac:%d]", rr_stat->ssrc, rr_stat->last_seq, rr_stat->jitter, @@ -1366,7 +1381,7 @@ static apt_bool_t mpf_rtcp_compound_packet_receive(mpf_rtp_stream_t *rtp_stream, return TRUE; } -static void mpf_rtcp_tx_timer_proc(mpf_timer_t *timer, void *obj) +static void mpf_rtcp_tx_timer_proc(apt_timer_t *timer, void *obj) { mpf_rtp_stream_t *rtp_stream = obj; @@ -1374,10 +1389,10 @@ static void mpf_rtcp_tx_timer_proc(mpf_timer_t *timer, void *obj) mpf_rtcp_report_send(rtp_stream); /* re-schedule timer */ - mpf_timer_set(timer,rtp_stream->config->rtcp_tx_interval); + apt_timer_set(timer,rtp_stream->settings->rtcp_tx_interval); } -static void mpf_rtcp_rx_timer_proc(mpf_timer_t *timer, void *obj) +static void mpf_rtcp_rx_timer_proc(apt_timer_t *timer, void *obj) { mpf_rtp_stream_t *rtp_stream = obj; if(rtp_stream->rtcp_socket && rtp_stream->rtcp_l_sockaddr && rtp_stream->rtcp_r_sockaddr) { @@ -1396,5 +1411,5 @@ static void mpf_rtcp_rx_timer_proc(mpf_timer_t *timer, void *obj) } /* re-schedule timer */ - mpf_timer_set(timer,rtp_stream->config->rtcp_rx_resolution); + apt_timer_set(timer,rtp_stream->settings->rtcp_rx_resolution); } diff --git a/libs/unimrcp/libs/mpf/src/mpf_rtp_termination_factory.c b/libs/unimrcp/libs/mpf/src/mpf_rtp_termination_factory.c index 0202e2e498..7b3cfa144f 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_rtp_termination_factory.c +++ b/libs/unimrcp/libs/mpf/src/mpf_rtp_termination_factory.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_rtp_termination_factory.c 1693 2010-05-16 18:33:07Z achaloyan $ */ #include "mpf_termination.h" @@ -37,7 +39,11 @@ static apt_bool_t mpf_rtp_termination_add(mpf_termination_t *termination, void * mpf_audio_stream_t *audio_stream = termination->audio_stream; if(!audio_stream) { rtp_termination_factory_t *termination_factory = (rtp_termination_factory_t*)termination->termination_factory; - audio_stream = mpf_rtp_stream_create(termination,termination_factory->config,termination->pool); + audio_stream = mpf_rtp_stream_create( + termination, + termination_factory->config, + rtp_descriptor->audio.settings, + termination->pool); if(!audio_stream) { return FALSE; } @@ -85,7 +91,11 @@ static const mpf_termination_vtable_t rtp_vtable = { static mpf_termination_t* mpf_rtp_termination_create(mpf_termination_factory_t *termination_factory, void *obj, apr_pool_t *pool) { - return mpf_termination_base_create(termination_factory,obj,&rtp_vtable,NULL,NULL,pool); + mpf_termination_t *termination = mpf_termination_base_create(termination_factory,obj,&rtp_vtable,NULL,NULL,pool); + if(termination) { + termination->name = "rtp-tm"; + } + return termination; } MPF_DECLARE(mpf_termination_factory_t*) mpf_rtp_termination_factory_create( diff --git a/libs/unimrcp/libs/mpf/src/mpf_scheduler.c b/libs/unimrcp/libs/mpf/src/mpf_scheduler.c index 24a4c8adf2..452799cbf9 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_scheduler.c +++ b/libs/unimrcp/libs/mpf/src/mpf_scheduler.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_scheduler.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_scheduler.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_stream.c b/libs/unimrcp/libs/mpf/src/mpf_stream.c index 1135e46e01..fa474c39c4 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_stream.c +++ b/libs/unimrcp/libs/mpf/src/mpf_stream.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_stream.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mpf_stream.h" diff --git a/libs/unimrcp/libs/mpf/src/mpf_termination.c b/libs/unimrcp/libs/mpf/src/mpf_termination.c index 05eff5c419..e32589eed5 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_termination.c +++ b/libs/unimrcp/libs/mpf/src/mpf_termination.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_termination.c 1693 2010-05-16 18:33:07Z achaloyan $ */ #include "mpf_termination.h" @@ -28,11 +30,12 @@ MPF_DECLARE(mpf_termination_t*) mpf_termination_base_create( { mpf_termination_t *termination = apr_palloc(pool,sizeof(mpf_termination_t)); termination->pool = pool; + termination->name = "media-tm"; termination->obj = obj; termination->event_handler_obj = NULL; termination->event_handler = NULL; termination->codec_manager = NULL; - termination->timer_manager = NULL; + termination->timer_queue = NULL; termination->termination_factory = termination_factory; termination->vtable = vtable; termination->slot = 0; diff --git a/libs/unimrcp/libs/mpf/src/mpf_termination_factory.c b/libs/unimrcp/libs/mpf/src/mpf_termination_factory.c index ba89f51064..1823fd826a 100644 --- a/libs/unimrcp/libs/mpf/src/mpf_termination_factory.c +++ b/libs/unimrcp/libs/mpf/src/mpf_termination_factory.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mpf_termination_factory.c 1693 2010-05-16 18:33:07Z achaloyan $ */ #include "mpf_termination_factory.h" @@ -47,20 +49,26 @@ MPF_DECLARE(apt_bool_t) mpf_termination_destroy(mpf_termination_t *termination) return TRUE; } +/** Get termination name */ +MPF_DECLARE(const char*) mpf_termination_name_get(const mpf_termination_t *termination) +{ + return termination->name; +} + /** Get associated object. */ -MPF_DECLARE(void*) mpf_termination_object_get(mpf_termination_t *termination) +MPF_DECLARE(void*) mpf_termination_object_get(const mpf_termination_t *termination) { return termination->obj; } /** Get audio stream. */ -MPF_DECLARE(mpf_audio_stream_t*) mpf_termination_audio_stream_get(mpf_termination_t *termination) +MPF_DECLARE(mpf_audio_stream_t*) mpf_termination_audio_stream_get(const mpf_termination_t *termination) { return termination->audio_stream; } /** Get video stream. */ -MPF_DECLARE(mpf_video_stream_t*) mpf_termination_video_stream_get(mpf_termination_t *termination) +MPF_DECLARE(mpf_video_stream_t*) mpf_termination_video_stream_get(const mpf_termination_t *termination) { return termination->video_stream; } diff --git a/libs/unimrcp/libs/mpf/src/mpf_timer_manager.c b/libs/unimrcp/libs/mpf/src/mpf_timer_manager.c deleted file mode 100644 index a3c8735869..0000000000 --- a/libs/unimrcp/libs/mpf/src/mpf_timer_manager.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2008 Arsen Chaloyan - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef WIN32 -#pragma warning(disable: 4127) -#endif -#include -#include "mpf_timer_manager.h" -#include "mpf_scheduler.h" -#include "apt_log.h" - -/** MPF timer manager */ -struct mpf_timer_manager_t { - /** Ring head */ - APR_RING_HEAD(mpf_timer_head_t, mpf_timer_t) head; - - /** Clock resolution */ - apr_uint32_t resolution; - /** Elapsed time */ - apr_uint32_t elapsed_time; -}; - -/** MPF timer */ -struct mpf_timer_t { - /** Ring entry */ - APR_RING_ENTRY(mpf_timer_t) link; - - /** Back pointer to manager */ - mpf_timer_manager_t *manager; - /** Time next report is scheduled at */ - apr_uint32_t scheduled_time; - - /** Timer proc */ - mpf_timer_proc_f proc; - /** Timer object */ - void *obj; -}; - -static void mpf_scheduler_proc(mpf_scheduler_t *scheduler, void *obj); - -/** Create timer manager */ -MPF_DECLARE(mpf_timer_manager_t*) mpf_timer_manager_create(mpf_scheduler_t *scheduler, apr_pool_t *pool) -{ - mpf_timer_manager_t *timer_manager = apr_palloc(pool,sizeof(mpf_timer_manager_t)); - APR_RING_INIT(&timer_manager->head, mpf_timer_t, link); - timer_manager->elapsed_time = 0; - timer_manager->resolution = 100; /* 100 ms */ - - mpf_scheduler_timer_clock_set(scheduler,timer_manager->resolution,mpf_scheduler_proc,timer_manager); - return timer_manager; -} - -/** Destroy timer manager */ -MPF_DECLARE(void) mpf_timer_manager_destroy(mpf_timer_manager_t *timer_manager) -{ -} - - -/** Create timer */ -MPF_DECLARE(mpf_timer_t*) mpf_timer_create(mpf_timer_manager_t *timer_manager, mpf_timer_proc_f proc, void *obj, apr_pool_t *pool) -{ - mpf_timer_t *timer = apr_palloc(pool,sizeof(mpf_timer_t)); - timer->manager = timer_manager; - timer->scheduled_time = 0; - timer->proc = proc; - timer->obj = obj; - return timer; -} - -static APR_INLINE apt_bool_t mpf_timer_insert(mpf_timer_manager_t *manager, mpf_timer_t *timer) -{ - mpf_timer_t *it; - for(it = APR_RING_LAST(&manager->head); - it != APR_RING_SENTINEL(&manager->head, mpf_timer_t, link); - it = APR_RING_PREV(it, link)) { - - if(it->scheduled_time <= timer->scheduled_time) { - APR_RING_INSERT_AFTER(it,timer,link); - return TRUE; - } - } - APR_RING_INSERT_HEAD(&manager->head,timer,mpf_timer_t,link); - return TRUE; -} - -/** Set one-shot timer */ -MPF_DECLARE(apt_bool_t) mpf_timer_set(mpf_timer_t *timer, apr_uint32_t timeout) - -{ - mpf_timer_manager_t *manager = timer->manager; - - if(timeout <= 0 || !timer->proc) { - return FALSE; - } - - /* calculate time to elapse */ - timer->scheduled_time = manager->elapsed_time + timeout; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Set Timer 0x%x [%lu]",timer,timer->scheduled_time); - - if(APR_RING_EMPTY(&timer->manager->head, mpf_timer_t, link)) { - APR_RING_INSERT_TAIL(&manager->head,timer,mpf_timer_t,link); - return TRUE; - } - - /* insert new node (timer) to sorted by scheduled time list */ - return mpf_timer_insert(manager,timer); -} - -/** Kill timer */ -MPF_DECLARE(apt_bool_t) mpf_timer_kill(mpf_timer_t *timer) -{ - if(!timer->scheduled_time) { - return FALSE; - } - - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Kill Timer 0x%x [%lu]",timer,timer->scheduled_time); - /* remove node (timer) from the list */ - APR_RING_REMOVE(timer,link); - timer->scheduled_time = 0; - - if(APR_RING_EMPTY(&timer->manager->head, mpf_timer_t, link)) { - /* reset elapsed time if no timers set */ - timer->manager->elapsed_time = 0; - } - return TRUE; -} - -static void mpf_timers_reschedule(mpf_timer_manager_t *manager) -{ - mpf_timer_t *it; - for(it = APR_RING_LAST(&manager->head); - it != APR_RING_SENTINEL(&manager->head, mpf_timer_t, link); - it = APR_RING_PREV(it, link)) { - - it->scheduled_time -= manager->elapsed_time; - } - manager->elapsed_time = 0; -} - -static void mpf_scheduler_proc(mpf_scheduler_t *scheduler, void *obj) -{ - mpf_timer_manager_t *manager = obj; - mpf_timer_t *timer; - - if(APR_RING_EMPTY(&manager->head, mpf_timer_t, link)) { - /* just return, nothing to do */ - return; - } - - /* increment elapsed time */ - manager->elapsed_time += manager->resolution; - if(manager->elapsed_time >= 0xFFFF) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Reschedule Timers [%lu]",manager->elapsed_time); - mpf_timers_reschedule(manager); - } - - /* process timers */ - do { - /* get first node (timer) */ - timer = APR_RING_FIRST(&manager->head); - - if(timer->scheduled_time > manager->elapsed_time) { - /* scheduled time is not elapsed yet */ - break; - } - - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Timer Elapsed 0x%x [%lu]",timer,timer->scheduled_time); - /* remove the elapsed timer from the list */ - APR_RING_REMOVE(timer, link); - timer->scheduled_time = 0; - /* process the elapsed timer */ - timer->proc(timer,timer->obj); - } - while(!APR_RING_EMPTY(&manager->head, mpf_timer_t, link)); -} diff --git a/libs/unimrcp/libs/mrcp-client/Makefile.am b/libs/unimrcp/libs/mrcp-client/Makefile.am index ec749369be..f2d306fb96 100644 --- a/libs/unimrcp/libs/mrcp-client/Makefile.am +++ b/libs/unimrcp/libs/mrcp-client/Makefile.am @@ -19,4 +19,5 @@ include_HEADERS = include/mrcp_client_types.h \ include/mrcp_application.h libmrcpclient_la_SOURCES = src/mrcp_client.c \ - src/mrcp_client_session.c + src/mrcp_client_session.c \ + src/mrcp_application.c diff --git a/libs/unimrcp/libs/mrcp-client/include/mrcp_application.h b/libs/unimrcp/libs/mrcp-client/include/mrcp_application.h index 629c445526..66b097b962 100644 --- a/libs/unimrcp/libs/mrcp-client/include/mrcp_application.h +++ b/libs/unimrcp/libs/mrcp-client/include/mrcp_application.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_application.h 1779 2010-09-01 05:54:34Z achaloyan $ */ -#ifndef __MRCP_APPLICATION_H__ -#define __MRCP_APPLICATION_H__ +#ifndef MRCP_APPLICATION_H +#define MRCP_APPLICATION_H /** * @file mrcp_application.h @@ -152,13 +154,13 @@ MRCP_DECLARE(apt_bool_t) mrcp_application_destroy(mrcp_application_t *applicatio * Get external object associated with the application. * @param application the application to get object from */ -MRCP_DECLARE(void*) mrcp_application_object_get(mrcp_application_t *application); +MRCP_DECLARE(void*) mrcp_application_object_get(const mrcp_application_t *application); /** * Get dir layout structure. * @param application the application to get dir layout from */ -MRCP_DECLARE(const apt_dir_layout_t*) mrcp_application_dir_layout_get(mrcp_application_t *application); +MRCP_DECLARE(const apt_dir_layout_t*) mrcp_application_dir_layout_get(const mrcp_application_t *application); /** * Create session. @@ -173,19 +175,19 @@ MRCP_DECLARE(mrcp_session_t*) mrcp_application_session_create(mrcp_application_t * Get memory pool the session object is created out of. * @param session the session to get pool from */ -MRCP_DECLARE(apr_pool_t*) mrcp_application_session_pool_get(mrcp_session_t *session); +MRCP_DECLARE(apr_pool_t*) mrcp_application_session_pool_get(const mrcp_session_t *session); /** * Get session identifier. * @param session the session to get identifier of */ -MRCP_DECLARE(const apt_str_t*) mrcp_application_session_id_get(mrcp_session_t *session); +MRCP_DECLARE(const apt_str_t*) mrcp_application_session_id_get(const mrcp_session_t *session); /** * Get external object associated with the session. * @param session the session to get object from */ -MRCP_DECLARE(void*) mrcp_application_session_object_get(mrcp_session_t *session); +MRCP_DECLARE(void*) mrcp_application_session_object_get(const mrcp_session_t *session); /** * Set (associate) external object to the session. @@ -194,6 +196,13 @@ MRCP_DECLARE(void*) mrcp_application_session_object_get(mrcp_session_t *session) */ MRCP_DECLARE(void) mrcp_application_session_object_set(mrcp_session_t *session, void *obj); +/** + * Set name of the session (informative only used for debugging). + * @param session the session to set name for + * @param name the name to set + */ +MRCP_DECLARE(void) mrcp_application_session_name_set(mrcp_session_t *session, const char *name); + /** * Send session update request. * @param session the session to update @@ -232,25 +241,31 @@ MRCP_DECLARE(mrcp_channel_t*) mrcp_application_channel_create( * Get external object associated with the channel. * @param channel the channel to get object from */ -MRCP_DECLARE(void*) mrcp_application_channel_object_get(mrcp_channel_t *channel); +MRCP_DECLARE(void*) mrcp_application_channel_object_get(const mrcp_channel_t *channel); /** * Get RTP termination descriptor. * @param channel the channel to get descriptor from */ -MRCP_DECLARE(mpf_rtp_termination_descriptor_t*) mrcp_application_rtp_descriptor_get(mrcp_channel_t *channel); +MRCP_DECLARE(mpf_rtp_termination_descriptor_t*) mrcp_application_rtp_descriptor_get(const mrcp_channel_t *channel); /** * Get codec descriptor of source stream. * @param channel the channel to get descriptor from */ -MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_source_descriptor_get(mrcp_channel_t *channel); +MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_source_descriptor_get(const mrcp_channel_t *channel); /** * Get codec descriptor of sink stream. * @param channel the channel to get descriptor from */ -MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_sink_descriptor_get(mrcp_channel_t *channel); +MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_sink_descriptor_get(const mrcp_channel_t *channel); + +/** + * Get associated audio stream. + * @param channel the channel to get associated stream from + */ +MRCP_DECLARE(const mpf_audio_stream_t*) mrcp_application_audio_stream_get(const mrcp_channel_t *channel); /** * Send channel add request. @@ -336,4 +351,4 @@ MRCP_DECLARE(mpf_termination_t*) mrcp_application_sink_termination_create( APT_END_EXTERN_C -#endif /*__MRCP_APPLICATION_H__*/ +#endif /* MRCP_APPLICATION_H */ diff --git a/libs/unimrcp/libs/mrcp-client/include/mrcp_client.h b/libs/unimrcp/libs/mrcp-client/include/mrcp_client.h index c62f0e8baf..9ddd5643bf 100644 --- a/libs/unimrcp/libs/mrcp-client/include/mrcp_client.h +++ b/libs/unimrcp/libs/mrcp-client/include/mrcp_client.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_client.h 1733 2010-06-07 17:26:49Z achaloyan $ */ -#ifndef __MRCP_CLIENT_H__ -#define __MRCP_CLIENT_H__ +#ifndef MRCP_CLIENT_H +#define MRCP_CLIENT_H /** * @file mrcp_client.h @@ -23,6 +25,7 @@ */ #include "mrcp_client_types.h" +#include "mpf_rtp_descriptor.h" #include "apt_task.h" APT_BEGIN_EXTERN_C @@ -82,15 +85,14 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_codec_manager_register(mrcp_client_t *clien * Get registered codec manager. * @param client the MRCP client to get codec manager from */ -MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_client_codec_manager_get(mrcp_client_t *client); +MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_client_codec_manager_get(const mrcp_client_t *client); /** * Register media engine. * @param client the MRCP client to set media engine for * @param media_engine the media engine to set - * @param name the name of the media engine */ -MRCP_DECLARE(apt_bool_t) mrcp_client_media_engine_register(mrcp_client_t *client, mpf_engine_t *media_engine, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_client_media_engine_register(mrcp_client_t *client, mpf_engine_t *media_engine); /** * Register RTP termination factory. @@ -100,21 +102,35 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_media_engine_register(mrcp_client_t *client */ MRCP_DECLARE(apt_bool_t) mrcp_client_rtp_factory_register(mrcp_client_t *client, mpf_termination_factory_t *rtp_termination_factory, const char *name); +/** + * Register RTP settings. + * @param client the MRCP client to set RTP settings for + * @param rtp_settings the settings to set + * @param name the name of the settings + */ +MRCP_DECLARE(apt_bool_t) mrcp_client_rtp_settings_register(mrcp_client_t *client, mpf_rtp_settings_t *rtp_settings, const char *name); + /** * Register MRCP signaling agent. * @param client the MRCP client to set signaling agent for * @param signaling_agent the signaling agent to set + */ +MRCP_DECLARE(apt_bool_t) mrcp_client_signaling_agent_register(mrcp_client_t *client, mrcp_sig_agent_t *signaling_agent); + +/** + * Register MRCP signaling settings. + * @param client the MRCP client to set signaling settings for + * @param signaling_settings the signaling settings to set * @param name the name of the agent */ -MRCP_DECLARE(apt_bool_t) mrcp_client_signaling_agent_register(mrcp_client_t *client, mrcp_sig_agent_t *signaling_agent, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_client_signaling_settings_register(mrcp_client_t *client, mrcp_sig_settings_t *signaling_settings, const char *name); /** * Register MRCP connection agent (MRCPv2 only). * @param client the MRCP client to set connection agent for * @param connection_agent the connection agent to set - * @param name the name of the agent */ -MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_register(mrcp_client_t *client, mrcp_connection_agent_t *connection_agent, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_register(mrcp_client_t *client, mrcp_connection_agent_t *connection_agent); /** Create MRCP profile */ MRCP_DECLARE(mrcp_profile_t*) mrcp_client_profile_create( @@ -123,6 +139,8 @@ MRCP_DECLARE(mrcp_profile_t*) mrcp_client_profile_create( mrcp_connection_agent_t *connection_agent, mpf_engine_t *media_engine, mpf_termination_factory_t *rtp_factory, + mpf_rtp_settings_t *rtp_settings, + mrcp_sig_settings_t *signaling_settings, apr_pool_t *pool); /** @@ -145,43 +163,63 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_application_register(mrcp_client_t *client, * Get memory pool. * @param client the MRCP client to get memory pool from */ -MRCP_DECLARE(apr_pool_t*) mrcp_client_memory_pool_get(mrcp_client_t *client); +MRCP_DECLARE(apr_pool_t*) mrcp_client_memory_pool_get(const mrcp_client_t *client); /** * Get media engine by name. * @param client the MRCP client to get media engine from * @param name the name of the media engine to lookup */ -MRCP_DECLARE(mpf_engine_t*) mrcp_client_media_engine_get(mrcp_client_t *client, const char *name); +MRCP_DECLARE(mpf_engine_t*) mrcp_client_media_engine_get(const mrcp_client_t *client, const char *name); /** * Get RTP termination factory by name. * @param client the MRCP client to get from * @param name the name to lookup */ -MRCP_DECLARE(mpf_termination_factory_t*) mrcp_client_rtp_factory_get(mrcp_client_t *client, const char *name); +MRCP_DECLARE(mpf_termination_factory_t*) mrcp_client_rtp_factory_get(const mrcp_client_t *client, const char *name); + +/** + * Get RTP settings by name + * @param client the MRCP client to get from + * @param name the name to lookup + */ +MRCP_DECLARE(mpf_rtp_settings_t*) mrcp_client_rtp_settings_get(const mrcp_client_t *client, const char *name); /** * Get signaling agent by name. * @param client the MRCP client to get from * @param name the name to lookup */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_client_signaling_agent_get(mrcp_client_t *client, const char *name); +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_client_signaling_agent_get(const mrcp_client_t *client, const char *name); + +/** + * Get signaling settings by name. + * @param client the MRCP client to get from + * @param name the name to lookup + */ +MRCP_DECLARE(mrcp_sig_settings_t*) mrcp_client_signaling_settings_get(const mrcp_client_t *client, const char *name); /** * Get connection agent by name. * @param client the MRCP client to get from * @param name the name to lookup */ -MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_client_connection_agent_get(mrcp_client_t *client, const char *name); +MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_client_connection_agent_get(const mrcp_client_t *client, const char *name); /** * Get profile by name. * @param client the MRCP client to get from * @param name the name to lookup */ -MRCP_DECLARE(mrcp_profile_t*) mrcp_client_profile_get(mrcp_client_t *client, const char *name); +MRCP_DECLARE(mrcp_profile_t*) mrcp_client_profile_get(const mrcp_client_t *client, const char *name); + +/** + * Get directory layout. + * @param client the MRCP client to get from + */ +MRCP_DECLARE(apt_dir_layout_t*) mrcp_client_dir_layout_get(const mrcp_client_t *client); APT_END_EXTERN_C -#endif /*__MRCP_CLIENT_H__*/ +#endif /* MRCP_CLIENT_H */ diff --git a/libs/unimrcp/libs/mrcp-client/include/mrcp_client_session.h b/libs/unimrcp/libs/mrcp-client/include/mrcp_client_session.h index 40a444a825..8944e122a9 100644 --- a/libs/unimrcp/libs/mrcp-client/include/mrcp_client_session.h +++ b/libs/unimrcp/libs/mrcp-client/include/mrcp_client_session.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_client_session.h 1733 2010-06-07 17:26:49Z achaloyan $ */ -#ifndef __MRCP_CLIENT_SESSION_H__ -#define __MRCP_CLIENT_SESSION_H__ +#ifndef MRCP_CLIENT_SESSION_H +#define MRCP_CLIENT_SESSION_H /** * @file mrcp_client_session.h @@ -142,6 +144,11 @@ struct mrcp_profile_t { mrcp_sig_agent_t *signaling_agent; /** Connection agent */ mrcp_connection_agent_t *connection_agent; + + /** Signaling settings */ + mrcp_sig_settings_t *signaling_settings; + /** RTP settings */ + mpf_rtp_settings_t *rtp_settings; }; /** MRCP application */ @@ -156,14 +163,12 @@ struct mrcp_application_t { apt_task_msg_pool_t *msg_pool; }; -/** Create client session */ -mrcp_client_session_t* mrcp_client_session_create(mrcp_application_t *application, void *obj); /** Create channel */ mrcp_channel_t* mrcp_client_channel_create( - mrcp_session_t *session, - mrcp_resource_t *resource, - mpf_termination_t *termination, - mpf_rtp_termination_descriptor_t *rtp_descriptor, + mrcp_client_session_t *session, + mrcp_resource_t *resource, + mpf_termination_t *termination, + mpf_rtp_termination_descriptor_t *rtp_descriptor, void *obj); /** Create signaling app_message_t request */ @@ -202,4 +207,4 @@ apt_bool_t mrcp_client_on_disconnect(mrcp_channel_t *channel); APT_END_EXTERN_C -#endif /*__MRCP_CLIENT_SESSION_H__*/ +#endif /* MRCP_CLIENT_SESSION_H */ diff --git a/libs/unimrcp/libs/mrcp-client/include/mrcp_client_types.h b/libs/unimrcp/libs/mrcp-client/include/mrcp_client_types.h index 4da19f0081..4e3b783f06 100644 --- a/libs/unimrcp/libs/mrcp-client/include/mrcp_client_types.h +++ b/libs/unimrcp/libs/mrcp-client/include/mrcp_client_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_client_types.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_CLIENT_TYPES_H__ -#define __MRCP_CLIENT_TYPES_H__ +#ifndef MRCP_CLIENT_TYPES_H +#define MRCP_CLIENT_TYPES_H /** * @file mrcp_client_types.h @@ -43,4 +45,4 @@ typedef struct mrcp_channel_t mrcp_channel_t; APT_END_EXTERN_C -#endif /*__MRCP_CLIENT_TYPES_H__*/ +#endif /* MRCP_CLIENT_TYPES_H */ diff --git a/libs/unimrcp/libs/mrcp-client/mrcpclient.2008.vcproj b/libs/unimrcp/libs/mrcp-client/mrcpclient.2008.vcproj deleted file mode 100644 index ee8c9b4375..0000000000 --- a/libs/unimrcp/libs/mrcp-client/mrcpclient.2008.vcproj +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/mrcp-client/mrcpclient.2010.vcxproj b/libs/unimrcp/libs/mrcp-client/mrcpclient.2010.vcxproj deleted file mode 100644 index 1c861d58b5..0000000000 --- a/libs/unimrcp/libs/mrcp-client/mrcpclient.2010.vcxproj +++ /dev/null @@ -1,121 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mrcpclient - {72782932-37CC-46AE-8C7F-9A7B1A6EE108} - mrcpclient - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - ProgramDatabase - - - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcp-client/mrcpclient.2010.vcxproj.filters b/libs/unimrcp/libs/mrcp-client/mrcpclient.2010.vcxproj.filters deleted file mode 100644 index 4054110771..0000000000 --- a/libs/unimrcp/libs/mrcp-client/mrcpclient.2010.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {890ddc88-1a65-4b89-996c-625f8ef76b90} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - include - - - include - - - - - src - - - src - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcp-client/mrcpclient.vcproj b/libs/unimrcp/libs/mrcp-client/mrcpclient.vcproj index 1b156212e2..046c3e4695 100644 --- a/libs/unimrcp/libs/mrcp-client/mrcpclient.vcproj +++ b/libs/unimrcp/libs/mrcp-client/mrcpclient.vcproj @@ -261,6 +261,10 @@ Name="src" Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" > + + diff --git a/libs/unimrcp/libs/mrcp-client/src/mrcp_application.c b/libs/unimrcp/libs/mrcp-client/src/mrcp_application.c new file mode 100644 index 0000000000..f3b73af544 --- /dev/null +++ b/libs/unimrcp/libs/mrcp-client/src/mrcp_application.c @@ -0,0 +1,538 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: mrcp_application.c 1792 2011-01-10 21:08:52Z achaloyan $ + */ + +#include "mrcp_application.h" +#include "mrcp_client.h" +#include "mrcp_client_session.h" +#include "mrcp_message.h" +#include "mrcp_sig_agent.h" +#include "mrcp_resource_factory.h" +#include "mpf_termination_factory.h" +#include "apt_dir_layout.h" +#include "apt_log.h" + +mrcp_client_session_t* mrcp_client_session_create(mrcp_client_t *client); + +apt_bool_t mrcp_app_signaling_task_msg_signal(mrcp_sig_command_e command_id, mrcp_session_t *session, mrcp_channel_t *channel); +apt_bool_t mrcp_app_control_task_msg_signal(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message); + + +/** Create application instance */ +MRCP_DECLARE(mrcp_application_t*) mrcp_application_create(const mrcp_app_message_handler_f handler, void *obj, apr_pool_t *pool) +{ + mrcp_application_t *application; + if(!handler) { + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create Application"); + application = apr_palloc(pool,sizeof(mrcp_application_t)); + application->obj = obj; + application->handler = handler; + application->client = NULL; + return application; +} + +/** Destroy application instance */ +MRCP_DECLARE(apt_bool_t) mrcp_application_destroy(mrcp_application_t *application) +{ + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy Application"); + return TRUE; +} + +/** Get external object associated with the application */ +MRCP_DECLARE(void*) mrcp_application_object_get(const mrcp_application_t *application) +{ + return application->obj; +} + +/** Get dir layout structure */ +MRCP_DECLARE(const apt_dir_layout_t*) mrcp_application_dir_layout_get(const mrcp_application_t *application) +{ + return mrcp_client_dir_layout_get(application->client); +} + + + +/** Create client session */ +MRCP_DECLARE(mrcp_session_t*) mrcp_application_session_create(mrcp_application_t *application, const char *profile_name, void *obj) +{ + mrcp_profile_t *profile; + mrcp_client_session_t *session; + if(!application || !application->client || !profile_name) { + return NULL; + } + + profile = mrcp_client_profile_get(application->client,profile_name); + if(!profile) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Profile [%s]",profile_name); + return NULL; + } + + session = mrcp_client_session_create(application->client); + if(!session) { + return NULL; + } + session->application = application; + session->app_obj = obj; + session->base.log_obj = obj; + session->profile = profile; + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCP Handle "APT_PTR_FMT" [%s]", + MRCP_SESSION_PTR(session), + profile_name); + return &session->base; +} + +/** Get memory pool the session object is created out of */ +MRCP_DECLARE(apr_pool_t*) mrcp_application_session_pool_get(const mrcp_session_t *session) +{ + if(!session) { + return NULL; + } + return session->pool; +} + +/** Get session identifier */ +MRCP_DECLARE(const apt_str_t*) mrcp_application_session_id_get(const mrcp_session_t *session) +{ + if(!session) { + return NULL; + } + return &session->id; +} + +/** Get external object associated with the session */ +MRCP_DECLARE(void*) mrcp_application_session_object_get(const mrcp_session_t *session) +{ + mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; + if(!client_session) { + return NULL; + } + return client_session->app_obj; +} + +/** Set (associate) external object to the session */ +MRCP_DECLARE(void) mrcp_application_session_object_set(mrcp_session_t *session, void *obj) +{ + mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; + if(client_session) { + client_session->app_obj = obj; + } +} + +/** Set name of the session (informative only used for debugging) */ +MRCP_DECLARE(void) mrcp_application_session_name_set(mrcp_session_t *session, const char *name) +{ + if(session && name) { + session->name = apr_pstrdup(session->pool,name); + } +} + + +/** Send session update request */ +MRCP_DECLARE(apt_bool_t) mrcp_application_session_update(mrcp_session_t *session) +{ + if(!session) { + return FALSE; + } + return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_SESSION_UPDATE,session,NULL); +} + +/** Send session termination request */ +MRCP_DECLARE(apt_bool_t) mrcp_application_session_terminate(mrcp_session_t *session) +{ + if(!session) { + return FALSE; + } + return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_SESSION_TERMINATE,session,NULL); +} + +/** Destroy client session (session must be terminated prior to destroy) */ +MRCP_DECLARE(apt_bool_t) mrcp_application_session_destroy(mrcp_session_t *session) +{ + if(!session) { + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy MRCP Handle %s",session->name); + mrcp_session_destroy(session); + return TRUE; +} + + +/** Create control channel */ +MRCP_DECLARE(mrcp_channel_t*) mrcp_application_channel_create( + mrcp_session_t *session, + mrcp_resource_id resource_id, + mpf_termination_t *termination, + mpf_rtp_termination_descriptor_t *rtp_descriptor, + void *obj) +{ + mrcp_resource_t *resource; + mrcp_profile_t *profile; + mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; + if(!client_session || !client_session->profile) { + /* Invalid params */ + return FALSE; + } + profile = client_session->profile; + + if(!profile->resource_factory) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: invalid profile"); + return FALSE; + } + resource = mrcp_resource_get(profile->resource_factory,resource_id); + if(!resource) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: no such resource"); + return FALSE; + } + + if(termination) { + /* Media engine and RTP factory must be specified in this case */ + if(!profile->media_engine || !profile->rtp_termination_factory) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: invalid profile"); + return FALSE; + } + } + else { + /* Either termination or rtp_descriptor must be specified */ + if(!rtp_descriptor) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: missing both termination and RTP descriptor"); + return FALSE; + } + } + + return mrcp_client_channel_create(client_session,resource,termination,rtp_descriptor,obj); +} + +/** Get external object associated with the channel */ +MRCP_DECLARE(void*) mrcp_application_channel_object_get(const mrcp_channel_t *channel) +{ + if(!channel) { + return FALSE; + } + return channel->obj; +} + +/** Get RTP termination descriptor */ +MRCP_DECLARE(mpf_rtp_termination_descriptor_t*) mrcp_application_rtp_descriptor_get(const mrcp_channel_t *channel) +{ + if(!channel || !channel->rtp_termination_slot) { + return NULL; + } + return channel->rtp_termination_slot->descriptor; +} + +/** Get codec descriptor of source stream */ +MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_source_descriptor_get(const mrcp_channel_t *channel) +{ + mpf_audio_stream_t *audio_stream; + if(!channel || !channel->termination) { + return NULL; + } + audio_stream = mpf_termination_audio_stream_get(channel->termination); + if(!audio_stream) { + return NULL; + } + return audio_stream->rx_descriptor; +} + +/** Get codec descriptor of sink stream */ +MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_sink_descriptor_get(const mrcp_channel_t *channel) +{ + mpf_audio_stream_t *audio_stream; + if(!channel || !channel->termination) { + return NULL; + } + audio_stream = mpf_termination_audio_stream_get(channel->termination); + if(!audio_stream) { + return NULL; + } + return audio_stream->tx_descriptor; +} + +/** Get associated audio stream */ +MRCP_DECLARE(const mpf_audio_stream_t*) mrcp_application_audio_stream_get(const mrcp_channel_t *channel) +{ + if(!channel || !channel->termination) { + return NULL; + } + + return mpf_termination_audio_stream_get(channel->termination); +} + +/** Send channel add request */ +MRCP_DECLARE(apt_bool_t) mrcp_application_channel_add(mrcp_session_t *session, mrcp_channel_t *channel) +{ + if(!session || !channel) { + return FALSE; + } + return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_CHANNEL_ADD,session,channel); +} + +/** Send channel removal request */ +MRCP_DECLARE(apt_bool_t) mrcp_application_channel_remove(mrcp_session_t *session, mrcp_channel_t *channel) +{ + if(!session || !channel) { + return FALSE; + } + return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_CHANNEL_REMOVE,session,channel); +} + +/** Send resource discovery request */ +MRCP_DECLARE(apt_bool_t) mrcp_application_resource_discover(mrcp_session_t *session) +{ + if(!session) { + return FALSE; + } + return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_RESOURCE_DISCOVER,session,NULL); +} + +/** Create MRCP message */ +MRCP_DECLARE(mrcp_message_t*) mrcp_application_message_create(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_method_id method_id) +{ + mrcp_message_t *mrcp_message; + mrcp_profile_t *profile; + mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; + if(!client_session || !channel || !channel->resource) { + return NULL; + } + profile = client_session->profile; + if(!profile || !profile->resource_factory) { + return NULL; + } + mrcp_message = mrcp_request_create( + channel->resource, + profile->signaling_agent->mrcp_version, + method_id, + session->pool); + return mrcp_message; +} + +/** Send MRCP message */ +MRCP_DECLARE(apt_bool_t) mrcp_application_message_send(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message) +{ + if(!session || !channel || !message) { + return FALSE; + } + return mrcp_app_control_task_msg_signal(session,channel,message); +} + +/** Create audio termination */ +MRCP_DECLARE(mpf_termination_t*) mrcp_application_audio_termination_create( + mrcp_session_t *session, + const mpf_audio_stream_vtable_t *stream_vtable, + mpf_stream_capabilities_t *capabilities, + void *obj) +{ + mpf_audio_stream_t *audio_stream; + + if(!capabilities) { + return NULL; + } + + if(mpf_codec_capabilities_validate(&capabilities->codecs) == FALSE) { + return NULL; + } + + /* create audio stream */ + audio_stream = mpf_audio_stream_create( + obj, /* object to associate */ + stream_vtable, /* virtual methods table of audio stream */ + capabilities, /* stream capabilities */ + session->pool); /* memory pool to allocate memory from */ + if(!audio_stream) { + return NULL; + } + + /* create raw termination */ + return mpf_raw_termination_create( + NULL, /* no object to associate */ + audio_stream, /* audio stream */ + NULL, /* no video stream */ + session->pool); /* memory pool to allocate memory from */ +} + +/** Create source media termination */ +MRCP_DECLARE(mpf_termination_t*) mrcp_application_source_termination_create( + mrcp_session_t *session, + const mpf_audio_stream_vtable_t *stream_vtable, + mpf_codec_descriptor_t *codec_descriptor, + void *obj) +{ + mpf_stream_capabilities_t *capabilities; + mpf_audio_stream_t *audio_stream; + + capabilities = mpf_source_stream_capabilities_create(session->pool); + if(codec_descriptor) { + mpf_codec_capabilities_add( + &capabilities->codecs, + mpf_sample_rate_mask_get(codec_descriptor->sampling_rate), + codec_descriptor->name.buf); + } + else { + mpf_codec_default_capabilities_add(&capabilities->codecs); + } + + /* create audio stream */ + audio_stream = mpf_audio_stream_create( + obj, /* object to associate */ + stream_vtable, /* virtual methods table of audio stream */ + capabilities, /* stream capabilities */ + session->pool); /* memory pool to allocate memory from */ + + if(!audio_stream) { + return NULL; + } + + audio_stream->rx_descriptor = codec_descriptor; + + /* create raw termination */ + return mpf_raw_termination_create( + NULL, /* no object to associate */ + audio_stream, /* audio stream */ + NULL, /* no video stream */ + session->pool); /* memory pool to allocate memory from */ +} + +/** Create sink media termination */ +MRCP_DECLARE(mpf_termination_t*) mrcp_application_sink_termination_create( + mrcp_session_t *session, + const mpf_audio_stream_vtable_t *stream_vtable, + mpf_codec_descriptor_t *codec_descriptor, + void *obj) +{ + mpf_stream_capabilities_t *capabilities; + mpf_audio_stream_t *audio_stream; + + capabilities = mpf_sink_stream_capabilities_create(session->pool); + if(codec_descriptor) { + mpf_codec_capabilities_add( + &capabilities->codecs, + mpf_sample_rate_mask_get(codec_descriptor->sampling_rate), + codec_descriptor->name.buf); + } + else { + mpf_codec_default_capabilities_add(&capabilities->codecs); + } + + /* create audio stream */ + audio_stream = mpf_audio_stream_create( + obj, /* object to associate */ + stream_vtable, /* virtual methods table of audio stream */ + capabilities, /* stream capabilities */ + session->pool); /* memory pool to allocate memory from */ + if(!audio_stream) { + return NULL; + } + + audio_stream->tx_descriptor = codec_descriptor; + + /* create raw termination */ + return mpf_raw_termination_create( + NULL, /* no object to associate */ + audio_stream, /* audio stream */ + NULL, /* no video stream */ + session->pool); /* memory pool to allocate memory from */ +} + +/** Dispatch application message */ +MRCP_DECLARE(apt_bool_t) mrcp_application_message_dispatch(const mrcp_app_message_dispatcher_t *dispatcher, const mrcp_app_message_t *app_message) +{ + apt_bool_t status = FALSE; + switch(app_message->message_type) { + case MRCP_APP_MESSAGE_TYPE_SIGNALING: + { + if(app_message->sig_message.message_type == MRCP_SIG_MESSAGE_TYPE_RESPONSE) { + switch(app_message->sig_message.command_id) { + case MRCP_SIG_COMMAND_SESSION_UPDATE: + if(dispatcher->on_session_update) { + status = dispatcher->on_session_update( + app_message->application, + app_message->session, + app_message->sig_message.status); + } + break; + case MRCP_SIG_COMMAND_SESSION_TERMINATE: + if(dispatcher->on_session_terminate) { + status = dispatcher->on_session_terminate( + app_message->application, + app_message->session, + app_message->sig_message.status); + } + break; + case MRCP_SIG_COMMAND_CHANNEL_ADD: + if(dispatcher->on_channel_add) { + status = dispatcher->on_channel_add( + app_message->application, + app_message->session, + app_message->channel, + app_message->sig_message.status); + } + break; + case MRCP_SIG_COMMAND_CHANNEL_REMOVE: + if(dispatcher->on_channel_remove) { + status = dispatcher->on_channel_remove( + app_message->application, + app_message->session, + app_message->channel, + app_message->sig_message.status); + } + break; + case MRCP_SIG_COMMAND_RESOURCE_DISCOVER: + if(dispatcher->on_resource_discover) { + status = dispatcher->on_resource_discover( + app_message->application, + app_message->session, + app_message->descriptor, + app_message->sig_message.status); + } + break; + default: + break; + } + } + else if(app_message->sig_message.message_type == MRCP_SIG_MESSAGE_TYPE_EVENT) { + switch(app_message->sig_message.event_id) { + case MRCP_SIG_EVENT_TERMINATE: + if(dispatcher->on_terminate_event) { + status = dispatcher->on_terminate_event( + app_message->application, + app_message->session, + app_message->channel); + } + break; + default: + break; + } + } + break; + } + case MRCP_APP_MESSAGE_TYPE_CONTROL: + { + if(dispatcher->on_message_receive) { + status = dispatcher->on_message_receive( + app_message->application, + app_message->session, + app_message->channel, + app_message->control_message); + } + break; + } + } + return status; +} diff --git a/libs/unimrcp/libs/mrcp-client/src/mrcp_client.c b/libs/unimrcp/libs/mrcp-client/src/mrcp_client.c index 6fee8c09d7..7689cf37ef 100644 --- a/libs/unimrcp/libs/mrcp-client/src/mrcp_client.c +++ b/libs/unimrcp/libs/mrcp-client/src/mrcp_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,22 +12,18 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_client.c 1733 2010-06-07 17:26:49Z achaloyan $ */ #include #include #include "mrcp_client.h" -#include "mrcp_resource_factory.h" -#include "mrcp_resource.h" #include "mrcp_sig_agent.h" #include "mrcp_client_session.h" #include "mrcp_client_connection.h" -#include "mrcp_message.h" -#include "mpf_engine.h" -#include "mpf_termination_factory.h" -#include "mpf_codec_manager.h" -#include "apt_pool.h" #include "apt_consumer_task.h" +#include "apt_pool.h" #include "apt_log.h" #define CLIENT_TASK_NAME "MRCP Client" @@ -47,8 +43,12 @@ struct mrcp_client_t { apr_hash_t *rtp_factory_table; /** Table of signaling agents (mrcp_sig_agent_t*) */ apr_hash_t *sig_agent_table; + /** Table of signaling settings (mrcp_sig_settings_t*) */ + apr_hash_t *sig_settings_table; /** Table of connection agents (mrcp_connection_agent_t*) */ apr_hash_t *cnt_agent_table; + /** Table of RTP settings (mpf_rtp_settings_t*) */ + apr_hash_t *rtp_settings_table; /** Table of profiles (mrcp_profile_t*) */ apr_hash_t *profile_table; @@ -151,8 +151,6 @@ static const mrcp_connection_event_vtable_t connection_method_vtable = { static void mrcp_client_on_start_complete(apt_task_t *task); static void mrcp_client_on_terminate_complete(apt_task_t *task); static apt_bool_t mrcp_client_msg_process(apt_task_t *task, apt_task_msg_t *msg); -static apt_bool_t mrcp_app_signaling_task_msg_signal(mrcp_sig_command_e command_id, mrcp_session_t *session, mrcp_channel_t *channel); -static apt_bool_t mrcp_app_control_task_msg_signal(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message); /** Create MRCP client instance */ @@ -177,7 +175,9 @@ MRCP_DECLARE(mrcp_client_t*) mrcp_client_create(apt_dir_layout_t *dir_layout) client->media_engine_table = NULL; client->rtp_factory_table = NULL; client->sig_agent_table = NULL; + client->sig_settings_table = NULL; client->cnt_agent_table = NULL; + client->rtp_settings_table = NULL; client->profile_table = NULL; client->app_table = NULL; client->session_table = NULL; @@ -201,7 +201,9 @@ MRCP_DECLARE(mrcp_client_t*) mrcp_client_create(apt_dir_layout_t *dir_layout) client->media_engine_table = apr_hash_make(client->pool); client->rtp_factory_table = apr_hash_make(client->pool); client->sig_agent_table = apr_hash_make(client->pool); + client->sig_settings_table = apr_hash_make(client->pool); client->cnt_agent_table = apr_hash_make(client->pool); + client->rtp_settings_table = apr_hash_make(client->pool); client->profile_table = apr_hash_make(client->pool); client->app_table = apr_hash_make(client->pool); @@ -326,20 +328,25 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_codec_manager_register(mrcp_client_t *clien } /** Get registered codec manager */ -MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_client_codec_manager_get(mrcp_client_t *client) +MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_client_codec_manager_get(const mrcp_client_t *client) { return client->codec_manager; } /** Register media engine */ -MRCP_DECLARE(apt_bool_t) mrcp_client_media_engine_register(mrcp_client_t *client, mpf_engine_t *media_engine, const char *name) +MRCP_DECLARE(apt_bool_t) mrcp_client_media_engine_register(mrcp_client_t *client, mpf_engine_t *media_engine) { - if(!media_engine || !name) { + const char *id; + if(!media_engine) { + return FALSE; + } + id = mpf_engine_id_get(media_engine); + if(!id) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Media Engine [%s]",name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Media Engine [%s]",id); mpf_engine_codec_manager_register(media_engine,client->codec_manager); - apr_hash_set(client->media_engine_table,name,APR_HASH_KEY_STRING,media_engine); + apr_hash_set(client->media_engine_table,id,APR_HASH_KEY_STRING,media_engine); mpf_engine_task_msg_type_set(media_engine,MRCP_CLIENT_MEDIA_TASK_MSG); if(client->task) { apt_task_t *media_task = mpf_task_get(media_engine); @@ -350,7 +357,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_media_engine_register(mrcp_client_t *client } /** Get media engine by name */ -MRCP_DECLARE(mpf_engine_t*) mrcp_client_media_engine_get(mrcp_client_t *client, const char *name) +MRCP_DECLARE(mpf_engine_t*) mrcp_client_media_engine_get(const mrcp_client_t *client, const char *name) { return apr_hash_get(client->media_engine_table,name,APR_HASH_KEY_STRING); } @@ -367,22 +374,39 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_rtp_factory_register(mrcp_client_t *client, } /** Get RTP termination factory by name */ -MRCP_DECLARE(mpf_termination_factory_t*) mrcp_client_rtp_factory_get(mrcp_client_t *client, const char *name) +MRCP_DECLARE(mpf_termination_factory_t*) mrcp_client_rtp_factory_get(const mrcp_client_t *client, const char *name) { return apr_hash_get(client->rtp_factory_table,name,APR_HASH_KEY_STRING); } +/** Register RTP settings */ +MRCP_DECLARE(apt_bool_t) mrcp_client_rtp_settings_register(mrcp_client_t *client, mpf_rtp_settings_t *rtp_settings, const char *name) +{ + if(!rtp_settings || !name) { + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register RTP Settings [%s]",name); + apr_hash_set(client->rtp_settings_table,name,APR_HASH_KEY_STRING,rtp_settings); + return TRUE; +} + +/** Get RTP settings by name */ +MRCP_DECLARE(mpf_rtp_settings_t*) mrcp_client_rtp_settings_get(const mrcp_client_t *client, const char *name) +{ + return apr_hash_get(client->rtp_settings_table,name,APR_HASH_KEY_STRING); +} + /** Register MRCP signaling agent */ -MRCP_DECLARE(apt_bool_t) mrcp_client_signaling_agent_register(mrcp_client_t *client, mrcp_sig_agent_t *signaling_agent, const char *name) +MRCP_DECLARE(apt_bool_t) mrcp_client_signaling_agent_register(mrcp_client_t *client, mrcp_sig_agent_t *signaling_agent) { - if(!signaling_agent || !name) { + if(!signaling_agent || !signaling_agent->id) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Signaling Agent [%s]",name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Signaling Agent [%s]",signaling_agent->id); signaling_agent->msg_pool = apt_task_msg_pool_create_dynamic(sizeof(sig_agent_task_msg_data_t),client->pool); signaling_agent->parent = client; signaling_agent->resource_factory = client->resource_factory; - apr_hash_set(client->sig_agent_table,name,APR_HASH_KEY_STRING,signaling_agent); + apr_hash_set(client->sig_agent_table,signaling_agent->id,APR_HASH_KEY_STRING,signaling_agent); if(client->task) { apt_task_t *task = apt_consumer_task_base_get(client->task); apt_task_add(task,signaling_agent->task); @@ -391,22 +415,45 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_signaling_agent_register(mrcp_client_t *cli } /** Get signaling agent by name */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_client_signaling_agent_get(mrcp_client_t *client, const char *name) +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_client_signaling_agent_get(const mrcp_client_t *client, const char *name) { return apr_hash_get(client->sig_agent_table,name,APR_HASH_KEY_STRING); } +/** Register MRCP signaling settings */ +MRCP_DECLARE(apt_bool_t) mrcp_client_signaling_settings_register(mrcp_client_t *client, mrcp_sig_settings_t *signaling_settings, const char *name) +{ + if(!signaling_settings || !name) { + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Signaling Settings [%s]",name); + apr_hash_set(client->sig_settings_table,name,APR_HASH_KEY_STRING,signaling_settings); + return TRUE; +} + +/** Get signaling settings by name */ +MRCP_DECLARE(mrcp_sig_settings_t*) mrcp_client_signaling_settings_get(const mrcp_client_t *client, const char *name) +{ + return apr_hash_get(client->sig_settings_table,name,APR_HASH_KEY_STRING); +} + + /** Register MRCP connection agent (MRCPv2 only) */ -MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_register(mrcp_client_t *client, mrcp_connection_agent_t *connection_agent, const char *name) +MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_register(mrcp_client_t *client, mrcp_connection_agent_t *connection_agent) { - if(!connection_agent || !name) { + const char *id; + if(!connection_agent) { + return FALSE; + } + id = mrcp_client_connection_agent_id_get(connection_agent); + if(!id) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Connection Agent [%s]",name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Connection Agent [%s]",id); mrcp_client_connection_resource_factory_set(connection_agent,client->resource_factory); mrcp_client_connection_agent_handler_set(connection_agent,client,&connection_method_vtable); client->cnt_msg_pool = apt_task_msg_pool_create_dynamic(sizeof(connection_agent_task_msg_data_t),client->pool); - apr_hash_set(client->cnt_agent_table,name,APR_HASH_KEY_STRING,connection_agent); + apr_hash_set(client->cnt_agent_table,id,APR_HASH_KEY_STRING,connection_agent); if(client->task) { apt_task_t *task = apt_consumer_task_base_get(client->task); apt_task_t *connection_task = mrcp_client_connection_agent_task_get(connection_agent); @@ -416,7 +463,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_register(mrcp_client_t *cl } /** Get connection agent by name */ -MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_client_connection_agent_get(mrcp_client_t *client, const char *name) +MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_client_connection_agent_get(const mrcp_client_t *client, const char *name) { return apr_hash_get(client->cnt_agent_table,name,APR_HASH_KEY_STRING); } @@ -428,14 +475,18 @@ MRCP_DECLARE(mrcp_profile_t*) mrcp_client_profile_create( mrcp_connection_agent_t *connection_agent, mpf_engine_t *media_engine, mpf_termination_factory_t *rtp_factory, + mpf_rtp_settings_t *rtp_settings, + mrcp_sig_settings_t *signaling_settings, apr_pool_t *pool) { mrcp_profile_t *profile = apr_palloc(pool,sizeof(mrcp_profile_t)); profile->resource_factory = resource_factory; profile->media_engine = media_engine; profile->rtp_termination_factory = rtp_factory; + profile->rtp_settings = rtp_settings; profile->signaling_agent = signaling_agent; profile->connection_agent = connection_agent; + profile->signaling_settings = signaling_settings; return profile; } @@ -459,13 +510,18 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_profile_register(mrcp_client_t *client, mrc return FALSE; } + if(!profile->signaling_settings) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing signaling settings",name); + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Profile [%s]",name); apr_hash_set(client->profile_table,name,APR_HASH_KEY_STRING,profile); return TRUE; } /** Get profile by name */ -MRCP_DECLARE(mrcp_profile_t*) mrcp_client_profile_get(mrcp_client_t *client, const char *name) +MRCP_DECLARE(mrcp_profile_t*) mrcp_client_profile_get(const mrcp_client_t *client, const char *name) { return apr_hash_get(client->profile_table,name,APR_HASH_KEY_STRING); } @@ -484,421 +540,52 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_application_register(mrcp_client_t *client, } /** Get memory pool */ -MRCP_DECLARE(apr_pool_t*) mrcp_client_memory_pool_get(mrcp_client_t *client) +MRCP_DECLARE(apr_pool_t*) mrcp_client_memory_pool_get(const mrcp_client_t *client) { return client->pool; } - -/** Create application instance */ -MRCP_DECLARE(mrcp_application_t*) mrcp_application_create(const mrcp_app_message_handler_f handler, void *obj, apr_pool_t *pool) -{ - mrcp_application_t *application; - if(!handler) { - return FALSE; - } - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create Application"); - application = apr_palloc(pool,sizeof(mrcp_application_t)); - application->obj = obj; - application->handler = handler; - application->client = NULL; - return application; -} - -/** Destroy application instance */ -MRCP_DECLARE(apt_bool_t) mrcp_application_destroy(mrcp_application_t *application) -{ - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy Application"); - return TRUE; -} - -/** Get external object associated with the application */ -MRCP_DECLARE(void*) mrcp_application_object_get(mrcp_application_t *application) +/** Get directory layout */ +MRCP_DECLARE(apt_dir_layout_t*) mrcp_client_dir_layout_get(const mrcp_client_t *client) { - return application->obj; + return client->dir_layout; } -/** Get dir layout structure */ -MRCP_DECLARE(const apt_dir_layout_t*) mrcp_application_dir_layout_get(mrcp_application_t *application) +mrcp_client_session_t* mrcp_client_session_create(mrcp_client_t *client) { - return application->client->dir_layout; -} - - - -/** Create client session */ -MRCP_DECLARE(mrcp_session_t*) mrcp_application_session_create(mrcp_application_t *application, const char *profile_name, void *obj) -{ - mrcp_profile_t *profile; - mrcp_client_session_t *session; - if(!application || !application->client) { - return NULL; - } - - profile = mrcp_client_profile_get(application->client,profile_name); - if(!profile) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Profile [%s]",profile_name); - return NULL; - } - - session = mrcp_client_session_create(application,obj); - if(!session) { - return NULL; - } + apr_pool_t *pool; + mrcp_client_session_t *session = (mrcp_client_session_t*) mrcp_session_create(sizeof(mrcp_client_session_t)-sizeof(mrcp_session_t)); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCP Handle "APT_PTR_FMT" [%s]", - MRCP_SESSION_PTR(session), - profile_name); - session->profile = profile; - session->codec_manager = application->client->codec_manager; + pool = session->base.pool; + session->base.name = apr_psprintf(pool,"0x%pp",session); session->base.response_vtable = &session_response_vtable; session->base.event_vtable = &session_event_vtable; - return &session->base; -} - -/** Get memory pool the session object is created out of */ -MRCP_DECLARE(apr_pool_t*) mrcp_application_session_pool_get(mrcp_session_t *session) -{ - if(!session) { - return NULL; - } - return session->pool; -} - -/** Get session identifier */ -MRCP_DECLARE(const apt_str_t*) mrcp_application_session_id_get(mrcp_session_t *session) -{ - if(!session) { - return NULL; - } - return &session->id; -} - -/** Get external object associated with the session */ -MRCP_DECLARE(void*) mrcp_application_session_object_get(mrcp_session_t *session) -{ - mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; - if(!client_session) { - return NULL; - } - return client_session->app_obj; -} - -/** Set (associate) external object to the session */ -MRCP_DECLARE(void) mrcp_application_session_object_set(mrcp_session_t *session, void *obj) -{ - mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; - if(client_session) { - client_session->app_obj = obj; - } -} - -/** Send session update request */ -MRCP_DECLARE(apt_bool_t) mrcp_application_session_update(mrcp_session_t *session) -{ - if(!session) { - return FALSE; - } - return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_SESSION_UPDATE,session,NULL); -} -/** Send session termination request */ -MRCP_DECLARE(apt_bool_t) mrcp_application_session_terminate(mrcp_session_t *session) -{ - if(!session) { - return FALSE; - } - return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_SESSION_TERMINATE,session,NULL); -} - -/** Destroy client session (session must be terminated prior to destroy) */ -MRCP_DECLARE(apt_bool_t) mrcp_application_session_destroy(mrcp_session_t *session) -{ - if(!session) { - return FALSE; - } - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy MRCP Handle "APT_PTR_FMT,MRCP_SESSION_PTR(session)); - mrcp_session_destroy(session); - return TRUE; -} - - -/** Create control channel */ -MRCP_DECLARE(mrcp_channel_t*) mrcp_application_channel_create( - mrcp_session_t *session, - mrcp_resource_id resource_id, - mpf_termination_t *termination, - mpf_rtp_termination_descriptor_t *rtp_descriptor, - void *obj) -{ - mrcp_resource_t *resource; - mrcp_profile_t *profile; - mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; - if(!client_session || !client_session->profile) { - /* Invalid params */ - return FALSE; - } - profile = client_session->profile; - - if(!profile->resource_factory) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: invalid profile"); - return FALSE; - } - resource = mrcp_resource_get(profile->resource_factory,resource_id); - if(!resource) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: no such resource"); - return FALSE; - } - - if(termination) { - /* Media engine and RTP factory must be specified in this case */ - if(!profile->media_engine || !profile->rtp_termination_factory) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: invalid profile"); - return FALSE; - } - } - else { - /* Either termination or rtp_descriptor must be specified */ - if(!rtp_descriptor) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Channel: missing both termination and RTP descriptor"); - return FALSE; - } - } - - return mrcp_client_channel_create(session,resource,termination,rtp_descriptor,obj); -} - -/** Get external object associated with the channel */ -MRCP_DECLARE(void*) mrcp_application_channel_object_get(mrcp_channel_t *channel) -{ - if(!channel) { - return FALSE; - } - return channel->obj; -} - -/** Get RTP termination descriptor */ -MRCP_DECLARE(mpf_rtp_termination_descriptor_t*) mrcp_application_rtp_descriptor_get(mrcp_channel_t *channel) -{ - if(!channel || !channel->rtp_termination_slot) { - return NULL; - } - return channel->rtp_termination_slot->descriptor; -} - -/** Get codec descriptor of source stream */ -MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_source_descriptor_get(mrcp_channel_t *channel) -{ - mpf_audio_stream_t *audio_stream; - if(!channel || !channel->termination) { - return NULL; - } - audio_stream = mpf_termination_audio_stream_get(channel->termination); - if(!audio_stream) { - return NULL; - } - return audio_stream->rx_descriptor; -} - -/** Get codec descriptor of sink stream */ -MRCP_DECLARE(const mpf_codec_descriptor_t*) mrcp_application_sink_descriptor_get(mrcp_channel_t *channel) -{ - mpf_audio_stream_t *audio_stream; - if(!channel || !channel->termination) { - return NULL; - } - audio_stream = mpf_termination_audio_stream_get(channel->termination); - if(!audio_stream) { - return NULL; - } - return audio_stream->tx_descriptor; -} - - -/** Send channel add request */ -MRCP_DECLARE(apt_bool_t) mrcp_application_channel_add(mrcp_session_t *session, mrcp_channel_t *channel) -{ - if(!session || !channel) { - return FALSE; - } - return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_CHANNEL_ADD,session,channel); -} - -/** Send channel removal request */ -MRCP_DECLARE(apt_bool_t) mrcp_application_channel_remove(mrcp_session_t *session, mrcp_channel_t *channel) -{ - if(!session || !channel) { - return FALSE; - } - return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_CHANNEL_REMOVE,session,channel); -} - -/** Send resource discovery request */ -MRCP_DECLARE(apt_bool_t) mrcp_application_resource_discover(mrcp_session_t *session) -{ - if(!session) { - return FALSE; - } - return mrcp_app_signaling_task_msg_signal(MRCP_SIG_COMMAND_RESOURCE_DISCOVER,session,NULL); -} - -/** Create MRCP message */ -MRCP_DECLARE(mrcp_message_t*) mrcp_application_message_create(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_method_id method_id) -{ - mrcp_message_t *mrcp_message; - mrcp_profile_t *profile; - mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; - if(!client_session || !channel || !channel->resource) { - return NULL; - } - profile = client_session->profile; - if(!profile || !profile->resource_factory) { - return NULL; - } - mrcp_message = mrcp_request_create( - channel->resource, - profile->signaling_agent->mrcp_version, - method_id, - session->pool); - return mrcp_message; -} - -/** Send MRCP message */ -MRCP_DECLARE(apt_bool_t) mrcp_application_message_send(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message) -{ - if(!session || !channel || !message) { - return FALSE; - } - return mrcp_app_control_task_msg_signal(session,channel,message); -} - -/** - * Create audio termination - * @param session the session to create termination for - * @param stream_vtable the virtual table of audio stream - * @param capabilities the capabilities of the stream - * @param obj the external object - */ -MRCP_DECLARE(mpf_termination_t*) mrcp_application_audio_termination_create( - mrcp_session_t *session, - const mpf_audio_stream_vtable_t *stream_vtable, - mpf_stream_capabilities_t *capabilities, - void *obj) -{ - mpf_audio_stream_t *audio_stream; - - if(!capabilities) { - return NULL; - } - - if(mpf_codec_capabilities_validate(&capabilities->codecs) == FALSE) { - return NULL; - } - - /* create audio stream */ - audio_stream = mpf_audio_stream_create( - obj, /* object to associate */ - stream_vtable, /* virtual methods table of audio stream */ - capabilities, /* stream capabilities */ - session->pool); /* memory pool to allocate memory from */ - if(!audio_stream) { - return NULL; - } - - /* create raw termination */ - return mpf_raw_termination_create( - NULL, /* no object to associate */ - audio_stream, /* audio stream */ - NULL, /* no video stream */ - session->pool); /* memory pool to allocate memory from */ -} - -/** Create source media termination */ -MRCP_DECLARE(mpf_termination_t*) mrcp_application_source_termination_create( - mrcp_session_t *session, - const mpf_audio_stream_vtable_t *stream_vtable, - mpf_codec_descriptor_t *codec_descriptor, - void *obj) -{ - mpf_stream_capabilities_t *capabilities; - mpf_audio_stream_t *audio_stream; - - capabilities = mpf_source_stream_capabilities_create(session->pool); - if(codec_descriptor) { - mpf_codec_capabilities_add( - &capabilities->codecs, - mpf_sample_rate_mask_get(codec_descriptor->sampling_rate), - codec_descriptor->name.buf); - } - else { - mpf_codec_default_capabilities_add(&capabilities->codecs); - } - - /* create audio stream */ - audio_stream = mpf_audio_stream_create( - obj, /* object to associate */ - stream_vtable, /* virtual methods table of audio stream */ - capabilities, /* stream capabilities */ - session->pool); /* memory pool to allocate memory from */ - - if(!audio_stream) { - return NULL; - } - - audio_stream->rx_descriptor = codec_descriptor; - - /* create raw termination */ - return mpf_raw_termination_create( - NULL, /* no object to associate */ - audio_stream, /* audio stream */ - NULL, /* no video stream */ - session->pool); /* memory pool to allocate memory from */ -} - -MRCP_DECLARE(mpf_termination_t*) mrcp_application_sink_termination_create( - mrcp_session_t *session, - const mpf_audio_stream_vtable_t *stream_vtable, - mpf_codec_descriptor_t *codec_descriptor, - void *obj) -{ - mpf_stream_capabilities_t *capabilities; - mpf_audio_stream_t *audio_stream; - - capabilities = mpf_sink_stream_capabilities_create(session->pool); - if(codec_descriptor) { - mpf_codec_capabilities_add( - &capabilities->codecs, - mpf_sample_rate_mask_get(codec_descriptor->sampling_rate), - codec_descriptor->name.buf); - } - else { - mpf_codec_default_capabilities_add(&capabilities->codecs); - } - - /* create audio stream */ - audio_stream = mpf_audio_stream_create( - obj, /* object to associate */ - stream_vtable, /* virtual methods table of audio stream */ - capabilities, /* stream capabilities */ - session->pool); /* memory pool to allocate memory from */ - if(!audio_stream) { - return NULL; - } - - audio_stream->tx_descriptor = codec_descriptor; - - /* create raw termination */ - return mpf_raw_termination_create( - NULL, /* no object to associate */ - audio_stream, /* audio stream */ - NULL, /* no video stream */ - session->pool); /* memory pool to allocate memory from */ + session->application = NULL; + session->app_obj = NULL; + session->profile = NULL; + session->context = NULL; + session->codec_manager = client->codec_manager; + session->terminations = apr_array_make(pool,2,sizeof(rtp_termination_slot_t)); + session->channels = apr_array_make(pool,2,sizeof(mrcp_channel_t*)); + session->registered = FALSE; + session->offer = NULL; + session->answer = NULL; + session->active_request = NULL; + session->request_queue = apt_list_create(pool); + session->mpf_task_msg = NULL; + session->subrequest_count = 0; + session->state = SESSION_STATE_NONE; + session->status = MRCP_SIG_STATUS_CODE_SUCCESS; + return session; } void mrcp_client_session_add(mrcp_client_t *client, mrcp_client_session_t *session) { if(session) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add MRCP Handle "APT_PTR_FMT,MRCP_SESSION_PTR(session)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add MRCP Handle "APT_NAMESID_FMT, + session->base.name, + MRCP_SESSION_SID(&session->base)); apr_hash_set(client->session_table,session,sizeof(session),session); } } @@ -906,7 +593,9 @@ void mrcp_client_session_add(mrcp_client_t *client, mrcp_client_session_t *sessi void mrcp_client_session_remove(mrcp_client_t *client, mrcp_client_session_t *session) { if(session) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove MRCP Handle "APT_PTR_FMT,MRCP_SESSION_PTR(session)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove MRCP Handle "APT_NAMESID_FMT, + session->base.name, + MRCP_SESSION_SID(&session->base)); apr_hash_set(client->session_table,session,sizeof(session),NULL); } } @@ -946,7 +635,6 @@ static apt_bool_t mrcp_client_msg_process(apt_task_t *task, apt_task_msg_t *msg) case MRCP_CLIENT_SIGNALING_TASK_MSG: { const sig_agent_task_msg_data_t *sig_message = (const sig_agent_task_msg_data_t*)msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Signaling Task Message [%d]", msg->sub_type); switch(msg->sub_type) { case SIG_AGENT_TASK_MSG_ANSWER: mrcp_client_session_answer_process(sig_message->session,sig_message->descriptor); @@ -971,7 +659,6 @@ static apt_bool_t mrcp_client_msg_process(apt_task_t *task, apt_task_msg_t *msg) case MRCP_CLIENT_CONNECTION_TASK_MSG: { const connection_agent_task_msg_data_t *data = (const connection_agent_task_msg_data_t*)msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Connection Task Message [%d]", msg->sub_type); switch(msg->sub_type) { case CONNECTION_AGENT_TASK_MSG_ADD_CHANNEL: mrcp_client_on_channel_add(data->channel,data->descriptor,data->status); @@ -996,27 +683,25 @@ static apt_bool_t mrcp_client_msg_process(apt_task_t *task, apt_task_msg_t *msg) case MRCP_CLIENT_MEDIA_TASK_MSG: { mpf_message_container_t *container = (mpf_message_container_t*) msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Media Task Message"); mrcp_client_mpf_message_process(container); break; } case MRCP_CLIENT_APPLICATION_TASK_MSG: { mrcp_app_message_t **app_message = (mrcp_app_message_t**) msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Application Task Message [%d]", (*app_message)->message_type); mrcp_client_app_message_process(*app_message); break; } default: { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Receive Unknown Task Message [%d]", msg->type); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Task Message Received [%d;%d]", msg->type,msg->sub_type); break; } } return TRUE; } -static apt_bool_t mrcp_app_signaling_task_msg_signal(mrcp_sig_command_e command_id, mrcp_session_t *session, mrcp_channel_t *channel) +apt_bool_t mrcp_app_signaling_task_msg_signal(mrcp_sig_command_e command_id, mrcp_session_t *session, mrcp_channel_t *channel) { mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; mrcp_application_t *application = client_session->application; @@ -1035,11 +720,10 @@ static apt_bool_t mrcp_app_signaling_task_msg_signal(mrcp_sig_command_e command_ app_message->descriptor = NULL; *slot = app_message; } - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Application Task Message"); return apt_task_msg_signal(task,task_msg); } -static apt_bool_t mrcp_app_control_task_msg_signal(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message) +apt_bool_t mrcp_app_control_task_msg_signal(mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message) { mrcp_client_session_t *client_session = (mrcp_client_session_t*)session; mrcp_application_t *application = client_session->application; @@ -1057,7 +741,6 @@ static apt_bool_t mrcp_app_control_task_msg_signal(mrcp_session_t *session, mrcp app_message->control_message = message; *slot = app_message; } - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Application Task Message"); return apt_task_msg_signal(task,task_msg); } @@ -1072,7 +755,6 @@ static apt_bool_t mrcp_client_signaling_task_msg_signal(sig_agent_task_msg_type_ data->descriptor = descriptor; data->message = message; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Signaling Task Message"); return apt_task_msg_parent_signal(session->signaling_agent->task,task_msg); } @@ -1101,12 +783,10 @@ static apt_bool_t mrcp_client_connection_task_msg_signal( data->message = message; data->status = status; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Connection Task Message"); return apt_task_msg_signal(task,task_msg); } - static apt_bool_t mrcp_client_answer_signal(mrcp_session_t *session, mrcp_session_descriptor_t *descriptor) { return mrcp_client_signaling_task_msg_signal(SIG_AGENT_TASK_MSG_ANSWER,session,descriptor,NULL); diff --git a/libs/unimrcp/libs/mrcp-client/src/mrcp_client_session.c b/libs/unimrcp/libs/mrcp-client/src/mrcp_client_session.c index a2659e0f3c..b7c8db3bb7 100644 --- a/libs/unimrcp/libs/mrcp-client/src/mrcp_client_session.c +++ b/libs/unimrcp/libs/mrcp-client/src/mrcp_client_session.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_client_session.c 1799 2011-05-12 02:32:32Z achaloyan $ */ #include "mrcp_client_session.h" @@ -29,6 +31,10 @@ #include "apt_obj_list.h" #include "apt_log.h" +/** Macro to log session name and identifier */ +#define MRCP_SESSION_NAMESID(session) \ + session->base.name, MRCP_SESSION_SID(&session->base) + void mrcp_client_session_add(mrcp_client_t *client, mrcp_client_session_t *session); void mrcp_client_session_remove(mrcp_client_t *client, mrcp_client_session_t *session); @@ -88,41 +94,17 @@ static mrcp_app_message_t* mrcp_client_app_response_create(const mrcp_app_messag } -mrcp_client_session_t* mrcp_client_session_create(mrcp_application_t *application, void *obj) -{ - apr_pool_t *pool; - mrcp_client_session_t *session = (mrcp_client_session_t*) mrcp_session_create(sizeof(mrcp_client_session_t)-sizeof(mrcp_session_t)); - pool = session->base.pool; - session->application = application; - session->codec_manager = NULL; - session->app_obj = obj; - session->profile = NULL; - session->context = NULL; - session->terminations = apr_array_make(pool,2,sizeof(rtp_termination_slot_t)); - session->channels = apr_array_make(pool,2,sizeof(mrcp_channel_t*)); - session->registered = FALSE; - session->offer = NULL; - session->answer = NULL; - session->active_request = NULL; - session->request_queue = apt_list_create(pool); - session->mpf_task_msg = NULL; - session->subrequest_count = 0; - session->state = SESSION_STATE_NONE; - session->status = MRCP_SIG_STATUS_CODE_SUCCESS; - return session; -} - mrcp_channel_t* mrcp_client_channel_create( - mrcp_session_t *session, + mrcp_client_session_t *session, mrcp_resource_t *resource, mpf_termination_t *termination, mpf_rtp_termination_descriptor_t *rtp_descriptor, void *obj) { - mrcp_channel_t *channel = apr_palloc(session->pool,sizeof(mrcp_channel_t)); - channel->pool = session->pool; + mrcp_channel_t *channel = apr_palloc(session->base.pool,sizeof(mrcp_channel_t)); + channel->pool = session->base.pool; channel->obj = obj; - channel->session = session; + channel->session = &session->base; channel->control_channel = NULL; channel->termination = termination; channel->rtp_termination_slot = NULL; @@ -131,7 +113,7 @@ mrcp_channel_t* mrcp_client_channel_create( channel->waiting_for_termination = FALSE; if(rtp_descriptor) { - rtp_termination_slot_t *termination_slot = apr_palloc(session->pool,sizeof(rtp_termination_slot_t)); + rtp_termination_slot_t *termination_slot = apr_palloc(channel->pool,sizeof(rtp_termination_slot_t)); termination_slot->descriptor = rtp_descriptor; termination_slot->termination = NULL; termination_slot->waiting = FALSE; @@ -139,7 +121,8 @@ mrcp_channel_t* mrcp_client_channel_create( termination_slot->id = 0; channel->rtp_termination_slot = termination_slot; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Channel "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(session)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Create Channel "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); return channel; } @@ -149,14 +132,15 @@ apt_bool_t mrcp_client_session_answer_process(mrcp_client_session_t *session, mr return FALSE; } if(!descriptor) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Answer "APT_PTRSID_FMT" [null descriptor]", MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Receive Answer "APT_NAMESID_FMT" [null descriptor]", + MRCP_SESSION_NAMESID(session)); session->status = MRCP_SIG_STATUS_CODE_FAILURE; /* raise app response */ return mrcp_app_sig_response_raise(session,TRUE); } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Answer "APT_PTRSID_FMT" [c:%d a:%d v:%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Receive Answer "APT_NAMESID_FMT" [c:%d a:%d v:%d]", + MRCP_SESSION_NAMESID(session), descriptor->control_media_arr->nelts, descriptor->audio_media_arr->nelts, descriptor->video_media_arr->nelts); @@ -207,7 +191,7 @@ apt_bool_t mrcp_client_session_answer_process(mrcp_client_session_t *session, mr apt_bool_t mrcp_client_session_terminate_response_process(mrcp_client_session_t *session) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Terminate Response "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Session Terminated "APT_NAMESID_FMT, MRCP_SESSION_NAMESID(session)); if(mrcp_client_session_subrequest_remove(session) == TRUE) { mrcp_app_session_terminate_raise(session,MRCP_SIG_STATUS_CODE_SUCCESS); @@ -220,7 +204,8 @@ apt_bool_t mrcp_client_session_terminate_event_process(mrcp_client_session_t *se if(session->state == SESSION_STATE_TERMINATING) { /* session termination request has been sent, still waiting for the response, all the events must be ignored at this stage */ - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unexpected Event! "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,session->base.log_obj,"Unexpected Event! "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); return FALSE; } @@ -266,7 +251,7 @@ apt_bool_t mrcp_client_session_control_response_process(mrcp_client_session_t *s apt_bool_t mrcp_client_session_discover_response_process(mrcp_client_session_t *session, mrcp_session_descriptor_t *descriptor) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Resource Discovery Response "APT_PTR_FMT, MRCP_SESSION_PTR(&session->base)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Resources Discovered %s", session->base.name); if(!session->active_request) { return FALSE; } @@ -288,13 +273,16 @@ apt_bool_t mrcp_client_session_discover_response_process(mrcp_client_session_t * control_media->resource_name = descriptor->resource_name; } } + else { + session->answer = descriptor; + } if(mrcp_client_session_subrequest_remove(session) == TRUE) { mrcp_app_message_t *response; response = mrcp_client_app_response_create(session->active_request,MRCP_SIG_STATUS_CODE_SUCCESS,session->base.pool); response->descriptor = session->answer; session->answer = NULL; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App Resource Discovery Response "APT_PTR_FMT, MRCP_SESSION_PTR(&session->base)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App Resource Discovery Response %s", session->base.name); session->application->handler(response); session->active_request = apt_list_pop_front(session->request_queue); @@ -308,7 +296,9 @@ apt_bool_t mrcp_client_session_discover_response_process(mrcp_client_session_t * apt_bool_t mrcp_client_on_channel_add(mrcp_channel_t *channel, mrcp_control_descriptor_t *descriptor, apt_bool_t status) { mrcp_client_session_t *session = (mrcp_client_session_t*)channel->session; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Control Channel Add "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Control Channel Added "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf); if(!channel->waiting_for_channel) { return FALSE; } @@ -323,7 +313,9 @@ apt_bool_t mrcp_client_on_channel_add(mrcp_channel_t *channel, mrcp_control_desc apt_bool_t mrcp_client_on_channel_modify(mrcp_channel_t *channel, mrcp_control_descriptor_t *descriptor, apt_bool_t status) { mrcp_client_session_t *session = (mrcp_client_session_t*)channel->session; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Control Channel Modify "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Control Channel Modified "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf); if(!channel->waiting_for_channel) { return FALSE; } @@ -341,7 +333,9 @@ apt_bool_t mrcp_client_on_channel_modify(mrcp_channel_t *channel, mrcp_control_d apt_bool_t mrcp_client_on_channel_remove(mrcp_channel_t *channel, apt_bool_t status) { mrcp_client_session_t *session = (mrcp_client_session_t*)channel->session; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Control Channel Remove "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Control Channel Removed "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf); if(!channel->waiting_for_channel) { return FALSE; } @@ -395,16 +389,18 @@ apt_bool_t mrcp_client_app_message_process(mrcp_app_message_t *app_message) { mrcp_client_session_t *session = (mrcp_client_session_t*)app_message->session; if(app_message->message_type == MRCP_APP_MESSAGE_TYPE_SIGNALING) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive App Request "APT_PTRSID_FMT" [%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Receive App Request "APT_NAMESID_FMT" [%d]", + MRCP_SESSION_NAMESID(session), app_message->sig_message.command_id); } else { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive App MRCP Request "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Receive App MRCP Request "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); } if(session->active_request) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Push Request to Queue "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Push Request to Queue "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); apt_list_push_back(session->request_queue,app_message,session->base.pool); return TRUE; } @@ -417,11 +413,13 @@ apt_bool_t mrcp_client_app_message_process(mrcp_app_message_t *app_message) static apt_bool_t mrcp_client_session_offer_send(mrcp_client_session_t *session) { mrcp_session_descriptor_t *descriptor = session->offer; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Offer "APT_PTRSID_FMT" [c:%d a:%d v:%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Send Offer "APT_NAMESID_FMT" [c:%d a:%d v:%d] to %s:%hu", + MRCP_SESSION_NAMESID(session), descriptor->control_media_arr->nelts, descriptor->audio_media_arr->nelts, - descriptor->video_media_arr->nelts); + descriptor->video_media_arr->nelts, + session->profile->signaling_settings->server_ip, + session->profile->signaling_settings->server_port); return mrcp_session_offer(&session->base,descriptor); } @@ -456,8 +454,8 @@ static apt_bool_t mrcp_app_sig_response_raise(mrcp_client_session_t *session, ap } session->active_request = NULL; response = mrcp_client_app_response_create(request,session->status,session->base.pool); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App Response "APT_PTRSID_FMT" [%d] %s [%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Raise App Response "APT_NAMESID_FMT" [%d] %s [%d]", + MRCP_SESSION_NAMESID(session), response->sig_message.command_id, session->status == MRCP_SIG_STATUS_CODE_SUCCESS ? "SUCCESS" : "FAILURE", session->status); @@ -482,8 +480,8 @@ static apt_bool_t mrcp_app_sig_event_raise(mrcp_client_session_t *session, mrcp_ app_event->application = session->application; app_event->session = &session->base; app_event->channel = channel; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App Event "APT_PTRSID_FMT" [%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Raise App Event "APT_NAMESID_FMT" [%d]", + MRCP_SESSION_NAMESID(session), app_event->sig_message.event_id); return session->application->handler(app_event); } @@ -501,7 +499,8 @@ static apt_bool_t mrcp_app_control_message_raise(mrcp_client_session_t *session, mrcp_message->start_line.method_id = mrcp_request->start_line.method_id; mrcp_message->start_line.method_name = mrcp_request->start_line.method_name; response->control_message = mrcp_message; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App MRCP Response "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Raise App MRCP Response "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); session->application->handler(response); session->active_request = apt_list_pop_front(session->request_queue); @@ -516,7 +515,8 @@ static apt_bool_t mrcp_app_control_message_raise(mrcp_client_session_t *session, app_message->application = session->application; app_message->session = &session->base; app_message->channel = channel; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App MRCP Event "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Raise App MRCP Event "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); session->application->handler(app_message); } return TRUE; @@ -532,8 +532,8 @@ static apt_bool_t mrcp_app_failure_message_raise(mrcp_client_session_t *session) session->active_request = NULL; response = mrcp_client_app_response_create(request,session->status,session->base.pool); if(response->message_type == MRCP_APP_MESSAGE_TYPE_SIGNALING) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App Response "APT_PTRSID_FMT" [%d] %s [%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Raise App Response "APT_NAMESID_FMT" [%d] %s [%d]", + MRCP_SESSION_NAMESID(session), response->sig_message.command_id, session->status == MRCP_SIG_STATUS_CODE_SUCCESS ? "SUCCESS" : "FAILURE", session->status); @@ -542,7 +542,8 @@ static apt_bool_t mrcp_app_failure_message_raise(mrcp_client_session_t *session) mrcp_message_t *mrcp_response = mrcp_response_create(response->control_message,response->control_message->pool); mrcp_response->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED; response->control_message = mrcp_response; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Raise App MRCP Response "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Raise App MRCP Response "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); } session->application->handler(response); return TRUE; @@ -612,15 +613,16 @@ static apt_bool_t mrcp_client_message_send(mrcp_client_session_t *session, mrcp_ if(!session->base.id.length) { mrcp_message_t *response = mrcp_response_create(message,message->pool); response->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Raise App Failure MRCP Response "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Raise App Failure MRCP Response "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); mrcp_app_control_message_raise(session,channel,response); return TRUE; } message->channel_id.session_id = session->base.id; message->start_line.request_id = ++session->base.last_request_id; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send MRCP Request "APT_PTRSIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Send MRCP Request "APT_NAMESIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_SESSION_NAMESID(session), channel->resource->name.buf, message->start_line.request_id); @@ -646,8 +648,8 @@ static apt_bool_t mrcp_client_channel_modify(mrcp_client_session_t *session, mrc return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Modify Control Channel "APT_PTRSIDRES_FMT" [%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_NOTICE,session->base.log_obj,"Modify Control Channel "APT_NAMESIDRES_FMT" [%d]", + MRCP_SESSION_NAMESID(session), channel->resource->name.buf, enable); if(mrcp_client_channel_find(session,channel,&index) == TRUE) { @@ -704,6 +706,7 @@ static apt_bool_t mrcp_client_channel_add(mrcp_client_session_t *session, mrcp_c mrcp_control_descriptor_t *control_media; if(!channel->control_channel) { channel->control_channel = mrcp_client_control_channel_create(profile->connection_agent,channel,pool); + mrcp_client_control_channel_log_obj_set(channel->control_channel,session->base.log_obj); } control_media = mrcp_control_offer_create(pool); control_media->id = mrcp_session_control_media_add(session->offer,control_media); @@ -715,8 +718,8 @@ static apt_bool_t mrcp_client_channel_add(mrcp_client_session_t *session, mrcp_c } } - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Add Control Channel "APT_PTRSIDRES_FMT, - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_NOTICE,session->base.log_obj,"Add Control Channel "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), channel->resource->name.buf); /* add control channel */ APR_ARRAY_PUSH(session->channels,mrcp_channel_t*) = channel; @@ -736,8 +739,14 @@ static apt_bool_t mrcp_client_channel_add(mrcp_client_session_t *session, mrcp_c if(!session->context) { /* create media context first */ - session->context = mpf_engine_context_create(profile->media_engine,session,5,pool); + session->context = mpf_engine_context_create( + profile->media_engine, + session->base.name, + session,5,pool); } + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Add Media Termination "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(channel->termination)); if(mpf_engine_termination_message_add( profile->media_engine, MPF_ADD_TERMINATION,session->context,channel->termination,NULL, @@ -749,6 +758,7 @@ static apt_bool_t mrcp_client_channel_add(mrcp_client_session_t *session, mrcp_c /* initialize rtp descriptor */ rtp_descriptor = apr_palloc(pool,sizeof(mpf_rtp_termination_descriptor_t)); mpf_rtp_termination_descriptor_init(rtp_descriptor); + rtp_descriptor->audio.settings = profile->rtp_settings; audio_stream = mpf_termination_audio_stream_get(channel->termination); if(audio_stream) { mpf_rtp_media_descriptor_t *media; @@ -759,10 +769,12 @@ static apt_bool_t mrcp_client_channel_add(mrcp_client_session_t *session, mrcp_c rtp_descriptor->audio.local = media; } - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add RTP Termination "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); /* create rtp termination */ termination = mpf_termination_create(profile->rtp_termination_factory,session,pool); slot->termination = termination; + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Add Media Termination "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(termination)); /* send add termination request (add to media context) */ if(mpf_engine_termination_message_add( @@ -805,7 +817,8 @@ static apt_bool_t mrcp_client_session_update(mrcp_client_session_t *session) if(!session->offer) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Update Session "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Update Session "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); return mrcp_client_session_offer_send(session); } @@ -816,7 +829,8 @@ static apt_bool_t mrcp_client_session_terminate(mrcp_client_session_t *session) rtp_termination_slot_t *slot; int i; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Terminate Session "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Terminate Session "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); profile = session->profile; mrcp_client_session_state_set(session,SESSION_STATE_TERMINATING); @@ -837,7 +851,8 @@ static apt_bool_t mrcp_client_session_terminate(mrcp_client_session_t *session) if(channel->control_channel) { /* remove channel */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Remove Control Channel "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Remove Control Channel "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); if(mrcp_client_control_channel_remove(channel->control_channel) == TRUE) { channel->waiting_for_channel = TRUE; mrcp_client_session_subrequest_add(session); @@ -846,7 +861,9 @@ static apt_bool_t mrcp_client_session_terminate(mrcp_client_session_t *session) /* send subtract termination request */ if(channel->termination) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract Channel Termination "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Subtract Media Termination "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(channel->termination)); if(mpf_engine_termination_message_add( profile->media_engine, MPF_SUBTRACT_TERMINATION,session->context,channel->termination,NULL, @@ -865,7 +882,9 @@ static apt_bool_t mrcp_client_session_terminate(mrcp_client_session_t *session) if(!slot || !slot->termination) continue; /* send subtract termination request */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract Termination "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Subtract Media Termination "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(slot->termination)); if(mpf_engine_termination_message_add( profile->media_engine, MPF_SUBTRACT_TERMINATION,session->context,slot->termination,NULL, @@ -887,7 +906,7 @@ static apt_bool_t mrcp_client_resource_discover(mrcp_client_session_t *session) { mrcp_session_descriptor_t *descriptor = NULL; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Resource Discovery Request "APT_PTR_FMT, MRCP_SESSION_PTR(&session->base)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Discover Resources "APT_PTR_FMT, MRCP_SESSION_PTR(&session->base)); session->answer = NULL; mrcp_client_session_state_set(session,SESSION_STATE_DISCOVERING); @@ -925,6 +944,9 @@ static apt_bool_t mrcp_client_on_termination_add(mrcp_client_session_t *session, if(!session) { return FALSE; } + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Media Termination Added "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(mpf_message->termination)); termination_slot = mrcp_client_rtp_termination_find(session,mpf_message->termination); if(termination_slot) { /* rtp termination */ @@ -966,6 +988,9 @@ static apt_bool_t mrcp_client_on_termination_modify(mrcp_client_session_t *sessi if(!session) { return FALSE; } + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Media Termination Modified "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(mpf_message->termination)); termination_slot = mrcp_client_rtp_termination_find(session,mpf_message->termination); if(termination_slot) { /* rtp termination */ @@ -995,6 +1020,9 @@ static apt_bool_t mrcp_client_on_termination_subtract(mrcp_client_session_t *ses if(!session) { return FALSE; } + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Media Termination Subtracted "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(mpf_message->termination)); termination_slot = mrcp_client_rtp_termination_find(session,mpf_message->termination); if(termination_slot) { /* rtp termination */ @@ -1036,15 +1064,12 @@ apt_bool_t mrcp_client_mpf_message_process(mpf_message_container_t *mpf_message_ if(mpf_message->message_type == MPF_MESSAGE_TYPE_RESPONSE) { switch(mpf_message->command_id) { case MPF_ADD_TERMINATION: - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Termination Add "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); mrcp_client_on_termination_add(session,mpf_message); break; case MPF_MODIFY_TERMINATION: - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Termination Modify "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); mrcp_client_on_termination_modify(session,mpf_message); break; case MPF_SUBTRACT_TERMINATION: - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Termination Subtract "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); mrcp_client_on_termination_subtract(session,mpf_message); break; case MPF_ADD_ASSOCIATION: @@ -1068,7 +1093,8 @@ apt_bool_t mrcp_client_mpf_message_process(mpf_message_container_t *mpf_message_ } } else if(mpf_message->message_type == MPF_MESSAGE_TYPE_EVENT) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process MPF Event "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Process MPF Event "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); } } return TRUE; @@ -1117,7 +1143,8 @@ static apt_bool_t mrcp_client_control_media_answer_process(mrcp_client_session_t /* get control descriptor */ control_descriptor = mrcp_session_control_media_get(descriptor,i); /* modify channel */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify Control Channel "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Modify Control Channel "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); if(mrcp_client_control_channel_modify(channel->control_channel,control_descriptor) == TRUE) { channel->waiting_for_channel = TRUE; mrcp_client_session_subrequest_add(session); @@ -1157,7 +1184,9 @@ static apt_bool_t mrcp_client_av_media_answer_process(mrcp_client_session_t *ses rtp_descriptor->audio.remote = remote_media; /* send modify termination request */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify Termination "APT_PTRSID_FMT, MRCP_SESSION_PTRSID(&session->base)); + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Modify Media Termination "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(slot->termination)); if(mpf_engine_termination_message_add( session->profile->media_engine, MPF_MODIFY_TERMINATION,session->context,slot->termination,rtp_descriptor, @@ -1183,15 +1212,15 @@ static apt_bool_t mrcp_app_request_dispatch(mrcp_client_session_t *session, cons if(session->state == SESSION_STATE_TERMINATING) { /* no more requests are allowed, as session is being terminated! just return, it is horribly wrong and can crash anytime here */ - apt_log(APT_LOG_MARK,APT_PRIO_ERROR,"Inappropriate Application Request "APT_PTRSID_FMT" [%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_ERROR,session->base.log_obj,"Inappropriate Application Request "APT_NAMESID_FMT" [%d]", + MRCP_SESSION_NAMESID(session), app_message->sig_message.command_id); return FALSE; } if(session->registered == FALSE) { session->base.signaling_agent = session->profile->signaling_agent; - session->base.signaling_agent->create_client_session(&session->base); + session->base.signaling_agent->create_client_session(&session->base,session->profile->signaling_settings); mrcp_client_session_add(session->application->client,session); session->registered = TRUE; @@ -1200,8 +1229,8 @@ static apt_bool_t mrcp_app_request_dispatch(mrcp_client_session_t *session, cons switch(app_message->message_type) { case MRCP_APP_MESSAGE_TYPE_SIGNALING: { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Dispatch Application Request "APT_PTRSID_FMT" [%d]", - MRCP_SESSION_PTRSID(&session->base), + apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Dispatch App Request "APT_NAMESID_FMT" [%d]", + MRCP_SESSION_NAMESID(session), app_message->sig_message.command_id); switch(app_message->sig_message.command_id) { case MRCP_SIG_COMMAND_SESSION_UPDATE: @@ -1232,90 +1261,3 @@ static apt_bool_t mrcp_app_request_dispatch(mrcp_client_session_t *session, cons } return TRUE; } - -/** Dispatch application message */ -MRCP_DECLARE(apt_bool_t) mrcp_application_message_dispatch(const mrcp_app_message_dispatcher_t *dispatcher, const mrcp_app_message_t *app_message) -{ - apt_bool_t status = FALSE; - switch(app_message->message_type) { - case MRCP_APP_MESSAGE_TYPE_SIGNALING: - { - if(app_message->sig_message.message_type == MRCP_SIG_MESSAGE_TYPE_RESPONSE) { - switch(app_message->sig_message.command_id) { - case MRCP_SIG_COMMAND_SESSION_UPDATE: - if(dispatcher->on_session_update) { - status = dispatcher->on_session_update( - app_message->application, - app_message->session, - app_message->sig_message.status); - } - break; - case MRCP_SIG_COMMAND_SESSION_TERMINATE: - if(dispatcher->on_session_terminate) { - status = dispatcher->on_session_terminate( - app_message->application, - app_message->session, - app_message->sig_message.status); - } - break; - case MRCP_SIG_COMMAND_CHANNEL_ADD: - if(dispatcher->on_channel_add) { - status = dispatcher->on_channel_add( - app_message->application, - app_message->session, - app_message->channel, - app_message->sig_message.status); - } - break; - case MRCP_SIG_COMMAND_CHANNEL_REMOVE: - if(dispatcher->on_channel_remove) { - status = dispatcher->on_channel_remove( - app_message->application, - app_message->session, - app_message->channel, - app_message->sig_message.status); - } - break; - case MRCP_SIG_COMMAND_RESOURCE_DISCOVER: - if(dispatcher->on_resource_discover) { - status = dispatcher->on_resource_discover( - app_message->application, - app_message->session, - app_message->descriptor, - app_message->sig_message.status); - } - break; - default: - break; - } - } - else if(app_message->sig_message.message_type == MRCP_SIG_MESSAGE_TYPE_EVENT) { - switch(app_message->sig_message.event_id) { - case MRCP_SIG_EVENT_TERMINATE: - if(dispatcher->on_terminate_event) { - status = dispatcher->on_terminate_event( - app_message->application, - app_message->session, - app_message->channel); - } - break; - default: - break; - } - } - break; - } - case MRCP_APP_MESSAGE_TYPE_CONTROL: - { - if(dispatcher->on_message_receive) { - status = dispatcher->on_message_receive( - app_message->application, - app_message->session, - app_message->channel, - app_message->control_message); - } - break; - } - } - return status; -} diff --git a/libs/unimrcp/libs/mrcp-engine/Makefile.am b/libs/unimrcp/libs/mrcp-engine/Makefile.am index 74bac2d06b..f30e21a2bd 100644 --- a/libs/unimrcp/libs/mrcp-engine/Makefile.am +++ b/libs/unimrcp/libs/mrcp-engine/Makefile.am @@ -18,13 +18,15 @@ include_HEADERS = include/mrcp_engine_types.h \ include/mrcp_synth_engine.h \ include/mrcp_recog_engine.h \ include/mrcp_recorder_engine.h \ + include/mrcp_verifier_engine.h \ include/mrcp_resource_engine.h \ include/mrcp_engine_factory.h \ include/mrcp_engine_loader.h \ include/mrcp_state_machine.h \ include/mrcp_synth_state_machine.h \ include/mrcp_recog_state_machine.h \ - include/mrcp_recorder_state_machine.h + include/mrcp_recorder_state_machine.h \ + include/mrcp_verifier_state_machine.h libmrcpengine_la_SOURCES = src/mrcp_engine_iface.c \ src/mrcp_engine_impl.c \ @@ -32,4 +34,5 @@ libmrcpengine_la_SOURCES = src/mrcp_engine_iface.c \ src/mrcp_engine_loader.c \ src/mrcp_synth_state_machine.c \ src/mrcp_recog_state_machine.c \ - src/mrcp_recorder_state_machine.c + src/mrcp_recorder_state_machine.c \ + src/mrcp_verifier_state_machine.c diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_factory.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_factory.h index ac8ccd78da..b86192eff6 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_factory.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_factory.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_factory.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __MRCP_ENGINE_FACTORY_H__ -#define __MRCP_ENGINE_FACTORY_H__ +#ifndef MRCP_ENGINE_FACTORY_H +#define MRCP_ENGINE_FACTORY_H /** * @file mrcp_engine_factory.h @@ -43,15 +45,18 @@ MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_close(mrcp_engine_factory_t *factor /** Register engine */ -MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_engine_register(mrcp_engine_factory_t *factory, mrcp_engine_t *engine, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_engine_register(mrcp_engine_factory_t *factory, mrcp_engine_t *engine); /** Get engine by name */ -MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_get(mrcp_engine_factory_t *factory, const char *name); +MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_get(const mrcp_engine_factory_t *factory, const char *name); /** Find engine by resource identifier */ -MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_find(mrcp_engine_factory_t *factory, mrcp_resource_id resource_id); +MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_find(const mrcp_engine_factory_t *factory, mrcp_resource_id resource_id); + +/** Start iterating over the engines in a factory */ +MRCP_DECLARE(apr_hash_index_t*) mrcp_engine_factory_engine_first(const mrcp_engine_factory_t *factory); APT_END_EXTERN_C -#endif /*__MRCP_ENGINE_FACTORY_H__*/ +#endif /* MRCP_ENGINE_FACTORY_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_iface.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_iface.h index ee123fee0f..e602b7d836 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_iface.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_iface.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_iface.h 1677 2010-05-01 18:45:50Z achaloyan $ */ -#ifndef __MRCP_ENGINE_IFACE_H__ -#define __MRCP_ENGINE_IFACE_H__ +#ifndef MRCP_ENGINE_IFACE_H +#define MRCP_ENGINE_IFACE_H /** * @file mrcp_engine_iface.h @@ -27,30 +29,20 @@ APT_BEGIN_EXTERN_C /** Destroy engine */ -static APR_INLINE apt_bool_t mrcp_engine_virtual_destroy(mrcp_engine_t *engine) -{ - return engine->method_vtable->destroy(engine); -} +apt_bool_t mrcp_engine_virtual_destroy(mrcp_engine_t *engine); /** Open engine */ -static APR_INLINE apt_bool_t mrcp_engine_virtual_open(mrcp_engine_t *engine) -{ - if(engine->is_open == FALSE) { - engine->is_open = engine->method_vtable->open(engine); - return engine->is_open; - } - return FALSE; -} +apt_bool_t mrcp_engine_virtual_open(mrcp_engine_t *engine); + +/** Response to open engine request */ +void mrcp_engine_on_open(mrcp_engine_t *engine, apt_bool_t status); /** Close engine */ -static APR_INLINE apt_bool_t mrcp_engine_virtual_close(mrcp_engine_t *engine) -{ - if(engine->is_open == TRUE) { - engine->is_open = FALSE; - return engine->method_vtable->close(engine); - } - return FALSE; -} +apt_bool_t mrcp_engine_virtual_close(mrcp_engine_t *engine); + +/** Response to close engine request */ +void mrcp_engine_on_close(mrcp_engine_t *engine); + /** Create engine channel */ mrcp_engine_channel_t* mrcp_engine_channel_virtual_create(mrcp_engine_t *engine, mrcp_version_e mrcp_version, apr_pool_t *pool); @@ -90,4 +82,4 @@ mrcp_engine_config_t* mrcp_engine_config_alloc(apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__MRCP_ENGINE_IFACE_H__*/ +#endif /* MRCP_ENGINE_IFACE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_impl.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_impl.h index 32de2ad6b2..915d1e53f5 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_impl.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_impl.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_impl.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __MRCP_ENGINE_IMPL_H__ -#define __MRCP_ENGINE_IMPL_H__ +#ifndef MRCP_ENGINE_IMPL_H +#define MRCP_ENGINE_IMPL_H /** * @file mrcp_engine_impl.h @@ -34,6 +36,18 @@ mrcp_engine_t* mrcp_engine_create( const mrcp_engine_method_vtable_t *vtable, apr_pool_t *pool); +/** Send engine open response */ +static APR_INLINE apt_bool_t mrcp_engine_open_respond(mrcp_engine_t *engine, apt_bool_t status) +{ + return engine->event_vtable->on_open(engine,status); +} + +/** Send engine close response */ +static APR_INLINE apt_bool_t mrcp_engine_close_respond(mrcp_engine_t *engine) +{ + return engine->event_vtable->on_close(engine); +} + /** Get engine config */ const mrcp_engine_config_t* mrcp_engine_config_get(const mrcp_engine_t *engine); @@ -104,18 +118,18 @@ static APR_INLINE const char* mrcp_engine_channel_id_get(mrcp_engine_channel_t * } /** Get MRCP version channel is created in the scope of */ -static APR_INLINE mrcp_version_e mrcp_engine_channel_version_get(mrcp_engine_channel_t *channel) +static APR_INLINE mrcp_version_e mrcp_engine_channel_version_get(const mrcp_engine_channel_t *channel) { return channel->mrcp_version; } /** Get codec descriptor of the audio source stream */ -const mpf_codec_descriptor_t* mrcp_engine_source_stream_codec_get(mrcp_engine_channel_t *channel); +const mpf_codec_descriptor_t* mrcp_engine_source_stream_codec_get(const mrcp_engine_channel_t *channel); /** Get codec descriptor of the audio sink stream */ -const mpf_codec_descriptor_t* mrcp_engine_sink_stream_codec_get(mrcp_engine_channel_t *channel); +const mpf_codec_descriptor_t* mrcp_engine_sink_stream_codec_get(const mrcp_engine_channel_t *channel); APT_END_EXTERN_C -#endif /*__MRCP_ENGINE_IMPL_H__*/ +#endif /* MRCP_ENGINE_IMPL_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_loader.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_loader.h index a4fc9d2e39..f6a47b8fa2 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_loader.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_loader.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_loader.h 1700 2010-05-21 18:56:06Z achaloyan $ */ -#ifndef __MRCP_ENGINE_LOADER_H__ -#define __MRCP_ENGINE_LOADER_H__ +#ifndef MRCP_ENGINE_LOADER_H +#define MRCP_ENGINE_LOADER_H /** * @file mrcp_engine_loader.h @@ -40,9 +42,13 @@ MRCP_DECLARE(apt_bool_t) mrcp_engine_loader_plugins_unload(mrcp_engine_loader_t /** Load engine plugin */ -MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_loader_plugin_load(mrcp_engine_loader_t *loader, const char *path, const char *name); +MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_loader_plugin_load( + mrcp_engine_loader_t *loader, + const char *id, + const char *path, + mrcp_engine_config_t *config); APT_END_EXTERN_C -#endif /*__MRCP_ENGINE_LOADER_H__*/ +#endif /* MRCP_ENGINE_LOADER_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_plugin.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_plugin.h index afa5e334c3..50a5391ef3 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_plugin.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_plugin.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_plugin.h 1724 2010-06-02 18:42:20Z achaloyan $ */ -#ifndef __MRCP_ENGINE_PLUGIN_H__ -#define __MRCP_ENGINE_PLUGIN_H__ +#ifndef MRCP_ENGINE_PLUGIN_H +#define MRCP_ENGINE_PLUGIN_H /** * @file mrcp_engine_plugin.h @@ -64,13 +66,13 @@ typedef apt_bool_t (*mrcp_plugin_log_accessor_f)(apt_logger_t *logger); * plugins such as structure size changes. No binary compatibility is * possible across a change in the major version. */ -#define PLUGIN_MAJOR_VERSION 0 +#define PLUGIN_MAJOR_VERSION 1 /** minor version * Minor API changes that do not cause binary compatibility problems. * Reset to 0 when upgrading PLUGIN_MAJOR_VERSION */ -#define PLUGIN_MINOR_VERSION 6 +#define PLUGIN_MINOR_VERSION 0 /** patch level * The Patch Level never includes API changes, simply bug fixes. @@ -113,4 +115,4 @@ static APR_INLINE int mrcp_plugin_version_check(mrcp_plugin_version_t *version) APT_END_EXTERN_C -#endif /*__MRCP_ENGINE_PLUGIN_H__*/ +#endif /* MRCP_ENGINE_PLUGIN_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_types.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_types.h index eec9ec89a5..2187d19829 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_types.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_engine_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_types.h 1700 2010-05-21 18:56:06Z achaloyan $ */ -#ifndef __MRCP_ENGINE_TYPES_H__ -#define __MRCP_ENGINE_TYPES_H__ +#ifndef MRCP_ENGINE_TYPES_H +#define MRCP_ENGINE_TYPES_H /** * @file mrcp_engine_types.h @@ -35,6 +37,8 @@ typedef struct mrcp_engine_t mrcp_engine_t; typedef struct mrcp_engine_config_t mrcp_engine_config_t; /** MRCP engine vtable declaration */ typedef struct mrcp_engine_method_vtable_t mrcp_engine_method_vtable_t; +/** MRCP engine event vtable declaration */ +typedef struct mrcp_engine_event_vtable_t mrcp_engine_event_vtable_t; /** MRCP engine channel declaration */ typedef struct mrcp_engine_channel_t mrcp_engine_channel_t; /** MRCP engine channel virtual method table declaration */ @@ -100,14 +104,28 @@ struct mrcp_engine_method_vtable_t { mrcp_engine_channel_t* (*create_channel)(mrcp_engine_t *engine, apr_pool_t *pool); }; +/** Table of MRCP engine virtual event handlers */ +struct mrcp_engine_event_vtable_t { + /** Open event handler */ + apt_bool_t (*on_open)(mrcp_engine_t *channel, apt_bool_t status); + /** Close event handler */ + apt_bool_t (*on_close)(mrcp_engine_t *channel); +}; + /** MRCP engine */ struct mrcp_engine_t { + /** Identifier of the engine */ + const char *id; /** Resource identifier */ mrcp_resource_id resource_id; /** External object associated with engine */ void *obj; /** Table of virtual methods */ const mrcp_engine_method_vtable_t *method_vtable; + /** Table of virtual event handlers */ + const mrcp_engine_event_vtable_t *event_vtable; + /** External object used with event handlers */ + void *event_obj; /** Codec manager */ const mpf_codec_manager_t *codec_manager; /** Dir layout structure */ @@ -121,15 +139,12 @@ struct mrcp_engine_t { /** Pool to allocate memory from */ apr_pool_t *pool; - /** Create state machine */ mrcp_state_machine_t* (*create_state_machine)(void *obj, mrcp_version_e version, apr_pool_t *pool); }; /** MRCP engine config */ struct mrcp_engine_config_t { - /** Name of the engine */ - const char *name; /** Max number of simultaneous channels */ apr_size_t max_channel_count; /** Table of name/value string params */ @@ -138,4 +153,4 @@ struct mrcp_engine_config_t { APT_END_EXTERN_C -#endif /*__MRCP_ENGINE_TYPES_H__*/ +#endif /* MRCP_ENGINE_TYPES_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_engine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_engine.h index 2e58c0663c..7a79f7e536 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_engine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recog_engine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RECOG_ENGINE_H__ -#define __MRCP_RECOG_ENGINE_H__ +#ifndef MRCP_RECOG_ENGINE_H +#define MRCP_RECOG_ENGINE_H /** * @file mrcp_recog_engine.h @@ -30,4 +32,4 @@ #include "mrcp_generic_header.h" #include "mrcp_message.h" -#endif /*__MRCP_RECOG_ENGINE_H__*/ +#endif /* MRCP_RECOG_ENGINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_state_machine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_state_machine.h index 32d5482593..f03ebf13de 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_state_machine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recog_state_machine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recog_state_machine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RECOG_STATE_MACHINE_H__ -#define __MRCP_RECOG_STATE_MACHINE_H__ +#ifndef MRCP_RECOG_STATE_MACHINE_H +#define MRCP_RECOG_STATE_MACHINE_H /** * @file mrcp_recog_state_machine.h @@ -31,4 +33,4 @@ mrcp_state_machine_t* mrcp_recog_state_machine_create(void *obj, mrcp_version_e APT_END_EXTERN_C -#endif /*__MRCP_RECOG_STATE_MACHINE_H__*/ +#endif /* MRCP_RECOG_STATE_MACHINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_engine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_engine.h index 3e4e818d4d..9c2c239145 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_engine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recorder_engine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RECORDER_ENGINE_H__ -#define __MRCP_RECORDER_ENGINE_H__ +#ifndef MRCP_RECORDER_ENGINE_H +#define MRCP_RECORDER_ENGINE_H /** * @file mrcp_recorder_engine.h @@ -30,4 +32,4 @@ #include "mrcp_generic_header.h" #include "mrcp_message.h" -#endif /*__MRCP_RECORDER_ENGINE_H__*/ +#endif /* MRCP_RECORDER_ENGINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_state_machine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_state_machine.h index ccd6096d95..2c2f19bb58 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_state_machine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_recorder_state_machine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recorder_state_machine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RECORDER_STATE_MACHINE_H__ -#define __MRCP_RECORDER_STATE_MACHINE_H__ +#ifndef MRCP_RECORDER_STATE_MACHINE_H +#define MRCP_RECORDER_STATE_MACHINE_H /** * @file mrcp_recorder_state_machine.h @@ -31,4 +33,4 @@ mrcp_state_machine_t* mrcp_recorder_state_machine_create(void *obj, mrcp_version APT_END_EXTERN_C -#endif /*__MRCP_RECORDER_STATE_MACHINE_H__*/ +#endif /* MRCP_RECORDER_STATE_MACHINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_resource_engine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_resource_engine.h index c69e5d0b93..650e47a9e1 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_resource_engine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_resource_engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_resource_engine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RESOURCE_ENGINE_H__ -#define __MRCP_RESOURCE_ENGINE_H__ +#ifndef MRCP_RESOURCE_ENGINE_H +#define MRCP_RESOURCE_ENGINE_H /** * @file mrcp_resource_engine.h @@ -46,4 +48,4 @@ static APR_INLINE mrcp_engine_t* mrcp_resource_engine_create( APT_END_EXTERN_C -#endif /*__MRCP_RESOURCE_ENGINE_H__*/ +#endif /* MRCP_RESOURCE_ENGINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_state_machine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_state_machine.h index 4089a8bd07..a34a280443 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_state_machine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_state_machine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_state_machine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_STATE_MACHINE_H__ -#define __MRCP_STATE_MACHINE_H__ +#ifndef MRCP_STATE_MACHINE_H +#define MRCP_STATE_MACHINE_H /** * @file mrcp_state_machine.h @@ -81,4 +83,4 @@ static APR_INLINE apt_bool_t mrcp_state_machine_deactivate(mrcp_state_machine_t APT_END_EXTERN_C -#endif /*__MRCP_STATE_MACHINE_H__*/ +#endif /* MRCP_STATE_MACHINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_engine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_engine.h index 305f7eadaa..8cdc18dcef 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_engine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_synth_engine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_SYNTH_ENGINE_H__ -#define __MRCP_SYNTH_ENGINE_H__ +#ifndef MRCP_SYNTH_ENGINE_H +#define MRCP_SYNTH_ENGINE_H /** * @file mrcp_synth_engine.h @@ -30,4 +32,4 @@ #include "mrcp_generic_header.h" #include "mrcp_message.h" -#endif /*__MRCP_SYNTH_ENGINE_H__*/ +#endif /* MRCP_SYNTH_ENGINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_state_machine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_state_machine.h index efe26dcc73..08ae5716c1 100644 --- a/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_state_machine.h +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_synth_state_machine.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_synth_state_machine.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_SYNTH_STATE_MACHINE_H__ -#define __MRCP_SYNTH_STATE_MACHINE_H__ +#ifndef MRCP_SYNTH_STATE_MACHINE_H +#define MRCP_SYNTH_STATE_MACHINE_H /** * @file mrcp_synth_state_machine.h @@ -31,4 +33,4 @@ mrcp_state_machine_t* mrcp_synth_state_machine_create(void *obj, mrcp_version_e APT_END_EXTERN_C -#endif /*__MRCP_SYNTH_STATE_MACHINE_H__*/ +#endif /* MRCP_SYNTH_STATE_MACHINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_verifier_engine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_verifier_engine.h new file mode 100644 index 0000000000..20e4de31f1 --- /dev/null +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_verifier_engine.h @@ -0,0 +1,35 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: mrcp_verifier_engine.h 1755 2010-08-18 19:35:08Z achaloyan $ + */ + +#ifndef MRCP_VERIFIER_ENGINE_H +#define MRCP_VERIFIER_ENGINE_H + +/** + * @file mrcp_verifier_engine.h + * @brief Verifier Engine Includes + */ + +#include "mrcp_engine_plugin.h" +#include "mrcp_engine_impl.h" + +#include "mrcp_verifier_resource.h" +#include "mrcp_verifier_header.h" +#include "mrcp_generic_header.h" +#include "mrcp_message.h" + +#endif /* MRCP_VERIFIER_ENGINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/include/mrcp_verifier_state_machine.h b/libs/unimrcp/libs/mrcp-engine/include/mrcp_verifier_state_machine.h new file mode 100644 index 0000000000..a3b5e8e2b4 --- /dev/null +++ b/libs/unimrcp/libs/mrcp-engine/include/mrcp_verifier_state_machine.h @@ -0,0 +1,36 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: mrcp_verifier_state_machine.h 1755 2010-08-18 19:35:08Z achaloyan $ + */ + +#ifndef MRCP_VERIFIER_STATE_MACHINE_H +#define MRCP_VERIFIER_STATE_MACHINE_H + +/** + * @file mrcp_verifier_state_machine.h + * @brief MRCP Verifier State Machine + */ + +#include "mrcp_state_machine.h" + +APT_BEGIN_EXTERN_C + +/** Create MRCP verifier state machine */ +mrcp_state_machine_t* mrcp_verifier_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool); + +APT_END_EXTERN_C + +#endif /* MRCP_VERIFIER_STATE_MACHINE_H */ diff --git a/libs/unimrcp/libs/mrcp-engine/mrcpengine.2008.vcproj b/libs/unimrcp/libs/mrcp-engine/mrcpengine.2008.vcproj deleted file mode 100644 index fbc62b016a..0000000000 --- a/libs/unimrcp/libs/mrcp-engine/mrcpengine.2008.vcproj +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/mrcp-engine/mrcpengine.vcproj b/libs/unimrcp/libs/mrcp-engine/mrcpengine.vcproj index c5b163eae1..8966705a4e 100644 --- a/libs/unimrcp/libs/mrcp-engine/mrcpengine.vcproj +++ b/libs/unimrcp/libs/mrcp-engine/mrcpengine.vcproj @@ -296,6 +296,14 @@ RelativePath=".\include\mrcp_synth_state_machine.h" > + + + + + + diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_factory.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_factory.c index 2faaabfd2c..8de989af0a 100644 --- a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_factory.c +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_factory.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_factory.c 1761 2010-08-20 17:35:28Z achaloyan $ */ #include @@ -19,6 +21,7 @@ #include "mrcp_synth_state_machine.h" #include "mrcp_recog_state_machine.h" #include "mrcp_recorder_state_machine.h" +#include "mrcp_verifier_state_machine.h" #include "apt_log.h" /** Engine factory declaration */ @@ -61,7 +64,6 @@ MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_open(mrcp_engine_factory_t *factory mrcp_engine_t *engine; apr_hash_index_t *it; void *val; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open MRCP Engines"); it = apr_hash_first(factory->pool,factory->engines); for(; it; it = apr_hash_next(it)) { apr_hash_this(it,NULL,NULL,&val); @@ -79,7 +81,6 @@ MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_close(mrcp_engine_factory_t *factor mrcp_engine_t *engine; apr_hash_index_t *it; void *val; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close MRCP Engines"); it=apr_hash_first(factory->pool,factory->engines); for(; it; it = apr_hash_next(it)) { apr_hash_this(it,NULL,NULL,&val); @@ -92,9 +93,9 @@ MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_close(mrcp_engine_factory_t *factor } /** Register new engine */ -MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_engine_register(mrcp_engine_factory_t *factory, mrcp_engine_t *engine, const char *name) +MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_engine_register(mrcp_engine_factory_t *factory, mrcp_engine_t *engine) { - if(!engine || !name) { + if(!engine || !engine->id) { return FALSE; } @@ -108,6 +109,9 @@ MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_engine_register(mrcp_engine_factory case MRCP_RECORDER_RESOURCE: engine->create_state_machine = mrcp_recorder_state_machine_create; break; + case MRCP_VERIFIER_RESOURCE: + engine->create_state_machine = mrcp_verifier_state_machine_create; + break; default: break; } @@ -116,12 +120,12 @@ MRCP_DECLARE(apt_bool_t) mrcp_engine_factory_engine_register(mrcp_engine_factory return FALSE; } - apr_hash_set(factory->engines,name,APR_HASH_KEY_STRING,engine); + apr_hash_set(factory->engines,engine->id,APR_HASH_KEY_STRING,engine); return TRUE; } /** Get engine by name */ -MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_get(mrcp_engine_factory_t *factory, const char *name) +MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_get(const mrcp_engine_factory_t *factory, const char *name) { if(!name) { return NULL; @@ -130,7 +134,7 @@ MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_get(mrcp_engine_factory_ } /** Find engine by resource identifier */ -MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_find(mrcp_engine_factory_t *factory, mrcp_resource_id resource_id) +MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_find(const mrcp_engine_factory_t *factory, mrcp_resource_id resource_id) { mrcp_engine_t *engine; void *val; @@ -145,3 +149,9 @@ MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_factory_engine_find(mrcp_engine_factory } return NULL; } + +/** Start iterating over the engines in a factory */ +MRCP_DECLARE(apr_hash_index_t*) mrcp_engine_factory_engine_first(const mrcp_engine_factory_t *factory) +{ + return apr_hash_first(factory->pool,factory->engines); +} diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_iface.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_iface.c index 137af17827..e8f45a4f98 100644 --- a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_iface.c +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_iface.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,9 +12,55 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_iface.c 1700 2010-05-21 18:56:06Z achaloyan $ */ #include "mrcp_engine_iface.h" +#include "apt_log.h" + +/** Destroy engine */ +apt_bool_t mrcp_engine_virtual_destroy(mrcp_engine_t *engine) +{ + return engine->method_vtable->destroy(engine); +} + +/** Open engine */ +apt_bool_t mrcp_engine_virtual_open(mrcp_engine_t *engine) +{ + if(engine->is_open == FALSE) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open Engine [%s]",engine->id); + return engine->method_vtable->open(engine); + } + return FALSE; +} + +/** Response to open engine request */ +void mrcp_engine_on_open(mrcp_engine_t *engine, apt_bool_t status) +{ + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Engine Opened [%s] status [%s]", + engine->id, + status == TRUE ? "success" : "failure"); + engine->is_open = status; +} + +/** Close engine */ +apt_bool_t mrcp_engine_virtual_close(mrcp_engine_t *engine) +{ + if(engine->is_open == TRUE) { + engine->is_open = FALSE; + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close Engine [%s]",engine->id); + return engine->method_vtable->close(engine); + } + return FALSE; +} + +/** Response to close engine request */ +void mrcp_engine_on_close(mrcp_engine_t *engine) +{ + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Engine Closed [%s]",engine->id); + engine->is_open = FALSE; +} /** Create engine channel */ mrcp_engine_channel_t* mrcp_engine_channel_virtual_create(mrcp_engine_t *engine, mrcp_version_e mrcp_version, apr_pool_t *pool) @@ -48,7 +94,6 @@ apt_bool_t mrcp_engine_channel_virtual_destroy(mrcp_engine_channel_t *channel) mrcp_engine_config_t* mrcp_engine_config_alloc(apr_pool_t *pool) { mrcp_engine_config_t *config = apr_palloc(pool,sizeof(mrcp_engine_config_t)); - config->name = NULL; config->max_channel_count = 0; config->params = NULL; return config; diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_impl.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_impl.c index e2c7a24dae..969dee4675 100644 --- a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_impl.c +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_impl.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_impl.c 1710 2010-05-24 17:36:19Z achaloyan $ */ #include "mrcp_engine_impl.h" @@ -25,9 +27,12 @@ mrcp_engine_t* mrcp_engine_create( apr_pool_t *pool) { mrcp_engine_t *engine = apr_palloc(pool,sizeof(mrcp_engine_t)); + engine->id = NULL; engine->resource_id = resource_id; engine->obj = obj; engine->method_vtable =vtable; + engine->event_vtable = NULL; + engine->event_obj = NULL; engine->config = NULL; engine->codec_manager = NULL; engine->dir_layout = NULL; @@ -217,7 +222,7 @@ mrcp_engine_channel_t* mrcp_engine_sink_channel_create( } /** Get codec descriptor of the audio source stream */ -const mpf_codec_descriptor_t* mrcp_engine_source_stream_codec_get(mrcp_engine_channel_t *channel) +const mpf_codec_descriptor_t* mrcp_engine_source_stream_codec_get(const mrcp_engine_channel_t *channel) { if(channel && channel->termination) { mpf_audio_stream_t *audio_stream = mpf_termination_audio_stream_get(channel->termination); @@ -229,7 +234,7 @@ const mpf_codec_descriptor_t* mrcp_engine_source_stream_codec_get(mrcp_engine_ch } /** Get codec descriptor of the audio sink stream */ -const mpf_codec_descriptor_t* mrcp_engine_sink_stream_codec_get(mrcp_engine_channel_t *channel) +const mpf_codec_descriptor_t* mrcp_engine_sink_stream_codec_get(const mrcp_engine_channel_t *channel) { if(channel && channel->termination) { mpf_audio_stream_t *audio_stream = mpf_termination_audio_stream_get(channel->termination); diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_loader.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_loader.c index dfa5bd617a..da29170d65 100644 --- a/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_loader.c +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_engine_loader.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_engine_loader.c 1700 2010-05-21 18:56:06Z achaloyan $ */ #include @@ -121,17 +123,17 @@ static apt_bool_t plugin_logger_load(apr_dso_handle_t *plugin) /** Load engine plugin */ -MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_loader_plugin_load(mrcp_engine_loader_t *loader, const char *path, const char *name) +MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_loader_plugin_load(mrcp_engine_loader_t *loader, const char *id, const char *path, mrcp_engine_config_t *config) { apr_dso_handle_t *plugin = NULL; mrcp_plugin_creator_f plugin_creator = NULL; mrcp_engine_t *engine = NULL; - if(!path || !name) { + if(!path || !id) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Load Plugin: invalid params"); return NULL; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Load Plugin [%s] [%s]",path,name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Load Plugin [%s] [%s]",id,path); if(apr_dso_load(&plugin,path,loader->pool) != APR_SUCCESS) { char derr[512] = ""; apr_dso_error(plugin,derr,sizeof(derr)); @@ -153,12 +155,14 @@ MRCP_DECLARE(mrcp_engine_t*) mrcp_engine_loader_plugin_load(mrcp_engine_loader_t plugin_logger_load(plugin); - apr_hash_set(loader->plugins,name,APR_HASH_KEY_STRING,plugin); + apr_hash_set(loader->plugins,id,APR_HASH_KEY_STRING,plugin); engine = plugin_creator(loader->pool); if(!engine) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create MRCP Engine"); } - + + engine->id = id; + engine->config = config; return engine; } diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_recog_state_machine.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_recog_state_machine.c index 1965192d96..50ddb972cb 100644 --- a/libs/unimrcp/libs/mrcp-engine/src/mrcp_recog_state_machine.c +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_recog_state_machine.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recog_state_machine.c 1782 2010-09-06 17:52:41Z achaloyan $ */ #include "apt_obj_list.h" @@ -41,19 +43,19 @@ static const char * state_names[RECOGNIZER_STATE_COUNT] = { typedef struct mrcp_recog_state_machine_t mrcp_recog_state_machine_t; struct mrcp_recog_state_machine_t { /** state machine base */ - mrcp_state_machine_t base; + mrcp_state_machine_t base; /** recognizer state */ - mrcp_recog_state_e state; + mrcp_recog_state_e state; /** indicate whether active_request was processed from pending request queue */ - apt_bool_t is_pending; + apt_bool_t is_pending; /** request sent to recognition engine and waiting for the response to be received */ - mrcp_message_t *active_request; + mrcp_message_t *active_request; /** in-progress recognize request */ - mrcp_message_t *recog; + mrcp_message_t *recog; /** queue of pending recognition requests */ - apt_obj_list_t *queue; + apt_obj_list_t *queue; /** properties used in set/get params */ - mrcp_message_header_t properties; + mrcp_message_header_t *properties; }; typedef apt_bool_t (*recog_method_f)(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message); @@ -83,9 +85,12 @@ static APR_INLINE apt_bool_t recog_event_dispatch(mrcp_recog_state_machine_t *st return state_machine->base.on_dispatch(&state_machine->base,message); } -static APR_INLINE void recog_state_change(mrcp_recog_state_machine_t *state_machine, mrcp_recog_state_e state) +static APR_INLINE void recog_state_change(mrcp_recog_state_machine_t *state_machine, mrcp_recog_state_e state, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"State Transition %s -> %s",state_names[state_machine->state],state_names[state]); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"State Transition %s -> %s "APT_SIDRES_FMT, + state_names[state_machine->state], + state_names[state], + MRCP_MESSAGE_SIDRES(message)); state_machine->state = state; if(state == RECOGNIZER_STATE_IDLE) { state_machine->recog = NULL; @@ -95,32 +100,24 @@ static APR_INLINE void recog_state_change(mrcp_recog_state_machine_t *state_mach static apt_bool_t recog_request_set_params(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SET-PARAMS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); - mrcp_message_header_set(&state_machine->properties,&message->header,message->pool); + mrcp_header_fields_set(state_machine->properties,&message->header,message->pool); return recog_request_dispatch(state_machine,message); } static apt_bool_t recog_response_set_params(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SET-PARAMS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_response_dispatch(state_machine,message); } static apt_bool_t recog_request_get_params(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-PARAMS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_request_dispatch(state_machine,message); } static apt_bool_t recog_response_get_params(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-PARAMS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); - mrcp_message_header_set(&message->header,&state_machine->active_request->header,message->pool); - mrcp_message_header_get(&message->header,&state_machine->properties,message->pool); + mrcp_header_fields_set(&message->header,&state_machine->active_request->header,message->pool); + mrcp_header_fields_get(&message->header,state_machine->properties,message->pool); return recog_response_dispatch(state_machine,message); } @@ -132,18 +129,14 @@ static apt_bool_t recog_request_define_grammar(mrcp_recog_state_machine_t *state return recog_response_dispatch(state_machine,response_message); } else if(state_machine->state == RECOGNIZER_STATE_RECOGNIZED) { - recog_state_change(state_machine,RECOGNIZER_STATE_IDLE); + recog_state_change(state_machine,RECOGNIZER_STATE_IDLE,message); } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process DEFINE-GRAMMAR Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_request_dispatch(state_machine,message); } static apt_bool_t recog_response_define_grammar(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process DEFINE-GRAMMAR Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(mrcp_resource_header_property_check(message,RECOGNIZER_HEADER_COMPLETION_CAUSE) != TRUE) { mrcp_recog_header_t *recog_header = mrcp_resource_header_prepare(message); recog_header->completion_cause = RECOGNIZER_COMPLETION_CAUSE_SUCCESS; @@ -154,10 +147,11 @@ static apt_bool_t recog_response_define_grammar(mrcp_recog_state_machine_t *stat static apt_bool_t recog_request_recognize(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - mrcp_message_header_inherit(&message->header,&state_machine->properties,message->pool); + mrcp_header_fields_inherit(&message->header,state_machine->properties,message->pool); if(state_machine->state == RECOGNIZER_STATE_RECOGNIZING) { mrcp_message_t *response; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Queue Up RECOGNIZE Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Queue Up RECOGNIZE Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); message->start_line.request_state = MRCP_REQUEST_STATE_PENDING; apt_list_push_back(state_machine->queue,message,message->pool); @@ -167,18 +161,14 @@ static apt_bool_t recog_request_recognize(mrcp_recog_state_machine_t *state_mach return recog_response_dispatch(state_machine,response); } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RECOGNIZE Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_request_dispatch(state_machine,message); } static apt_bool_t recog_response_recognize(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RECOGNIZE Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(message->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS) { state_machine->recog = state_machine->active_request; - recog_state_change(state_machine,RECOGNIZER_STATE_RECOGNIZING); + recog_state_change(state_machine,RECOGNIZER_STATE_RECOGNIZING,message); } if(state_machine->is_pending == TRUE) { state_machine->is_pending = FALSE; @@ -188,13 +178,22 @@ static apt_bool_t recog_response_recognize(mrcp_recog_state_machine_t *state_mac return recog_response_dispatch(state_machine,message); } +static apt_bool_t recog_request_interpret(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) +{ + mrcp_header_fields_inherit(&message->header,state_machine->properties,message->pool); + return recog_request_dispatch(state_machine,message); +} + +static apt_bool_t recog_response_interpret(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) +{ + return recog_response_dispatch(state_machine,message); +} + static apt_bool_t recog_request_get_result(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { mrcp_message_t *response_message; if(state_machine->state == RECOGNIZER_STATE_RECOGNIZED) { /* found recognized request */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-RESULT Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_request_dispatch(state_machine,message); } @@ -206,8 +205,6 @@ static apt_bool_t recog_request_get_result(mrcp_recog_state_machine_t *state_mac static apt_bool_t recog_response_get_result(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-RESULT Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_response_dispatch(state_machine,message); } @@ -216,8 +213,6 @@ static apt_bool_t recog_request_recognition_start_timers(mrcp_recog_state_machin mrcp_message_t *response_message; if(state_machine->state == RECOGNIZER_STATE_RECOGNIZING) { /* found in-progress request */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process START-INPUT-TIMERS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_request_dispatch(state_machine,message); } @@ -229,8 +224,6 @@ static apt_bool_t recog_request_recognition_start_timers(mrcp_recog_state_machin static apt_bool_t recog_response_recognition_start_timers(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process START-INPUT-TIMERS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recog_response_dispatch(state_machine,message); } @@ -252,7 +245,9 @@ static apt_bool_t recog_pending_requests_remove(mrcp_recog_state_machine_t *stat while(elem) { pending_message = apt_list_elem_object_get(elem); if(!request_id_list || active_request_id_list_find(generic_header,pending_message->start_line.request_id) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove Pending RECOGNIZE Request [%d]",pending_message->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove Pending RECOGNIZE Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(pending_message), + pending_message->start_line.request_id); elem = apt_list_elem_remove(state_machine->queue,elem); /* append active id list */ active_request_id_list_append(response_generic_header,pending_message->start_line.request_id); @@ -283,13 +278,14 @@ static apt_bool_t recog_request_stop(mrcp_recog_state_machine_t *state_machine, if(!request_id_list || active_request_id_list_find(generic_header,state_machine->recog->start_line.request_id) == TRUE) { /* found in-progress RECOGNIZE request, stop it */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process STOP Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Found IN-PROGRESS RECOGNIZE Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return recog_request_dispatch(state_machine,message); } } else if(state_machine->state == RECOGNIZER_STATE_RECOGNIZED) { - recog_state_change(state_machine,RECOGNIZER_STATE_IDLE); + recog_state_change(state_machine,RECOGNIZER_STATE_IDLE,message); } /* found no in-progress RECOGNIZE request, sending immediate response */ @@ -302,19 +298,19 @@ static apt_bool_t recog_response_stop(mrcp_recog_state_machine_t *state_machine, { mrcp_message_t *pending_request; mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process STOP Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); /* append active id list */ active_request_id_list_append(generic_header,state_machine->recog->start_line.request_id); mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); recog_pending_requests_remove(state_machine,state_machine->active_request,message); - recog_state_change(state_machine,RECOGNIZER_STATE_IDLE); + recog_state_change(state_machine,RECOGNIZER_STATE_IDLE,message); pending_request = apt_list_pop_front(state_machine->queue); recog_response_dispatch(state_machine,message); /* process pending RECOGNIZE requests / if any */ if(pending_request) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending RECOGNIZE Request [%d]",pending_request->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending RECOGNIZE Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(pending_request), + pending_request->start_line.request_id); state_machine->is_pending = TRUE; recog_request_dispatch(state_machine,pending_request); } @@ -333,8 +329,6 @@ static apt_bool_t recog_event_start_of_input(mrcp_recog_state_machine_t *state_m return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process START-OF-INPUT Event [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); message->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS; return recog_event_dispatch(state_machine,message); } @@ -343,47 +337,62 @@ static apt_bool_t recog_event_recognition_complete(mrcp_recog_state_machine_t *s { mrcp_message_t *pending_request; if(!state_machine->recog) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECOGNITION-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECOGNITION-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return FALSE; } if(state_machine->recog->start_line.request_id != message->start_line.request_id) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECOGNITION-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECOGNITION-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return FALSE; } if(state_machine->active_request && state_machine->active_request->start_line.method_id == RECOGNIZER_STOP) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Ignore RECOGNITION-COMPLETE Event [%d]: waiting for STOP response",message->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Ignore RECOGNITION-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]: waiting for STOP response", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RECOGNITION-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(mrcp_resource_header_property_check(message,RECOGNIZER_HEADER_COMPLETION_CAUSE) != TRUE) { mrcp_recog_header_t *recog_header = mrcp_resource_header_prepare(message); recog_header->completion_cause = RECOGNIZER_COMPLETION_CAUSE_SUCCESS; mrcp_resource_header_property_add(message,RECOGNIZER_HEADER_COMPLETION_CAUSE); } - recog_state_change(state_machine,RECOGNIZER_STATE_RECOGNIZED); + recog_state_change(state_machine,RECOGNIZER_STATE_RECOGNIZED,message); recog_event_dispatch(state_machine,message); /* process pending RECOGNIZE requests */ pending_request = apt_list_pop_front(state_machine->queue); if(pending_request) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending RECOGNIZE Request [%d]",pending_request->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending RECOGNIZE Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(pending_request), + pending_request->start_line.request_id); state_machine->is_pending = TRUE; recog_request_dispatch(state_machine,pending_request); } return TRUE; } +static apt_bool_t recog_event_interpretation_complete(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(mrcp_resource_header_property_check(message,RECOGNIZER_HEADER_COMPLETION_CAUSE) != TRUE) { + mrcp_recog_header_t *recog_header = mrcp_resource_header_prepare(message); + recog_header->completion_cause = RECOGNIZER_COMPLETION_CAUSE_SUCCESS; + mrcp_resource_header_property_add(message,RECOGNIZER_HEADER_COMPLETION_CAUSE); + } + return recog_event_dispatch(state_machine,message); +} + static recog_method_f recog_request_method_array[RECOGNIZER_METHOD_COUNT] = { recog_request_set_params, recog_request_get_params, recog_request_define_grammar, recog_request_recognize, + recog_request_interpret, recog_request_get_result, recog_request_recognition_start_timers, recog_request_stop @@ -394,6 +403,7 @@ static recog_method_f recog_response_method_array[RECOGNIZER_METHOD_COUNT] = { recog_response_get_params, recog_response_define_grammar, recog_response_recognize, + recog_response_interpret, recog_response_get_result, recog_response_recognition_start_timers, recog_response_stop @@ -401,7 +411,8 @@ static recog_method_f recog_response_method_array[RECOGNIZER_METHOD_COUNT] = { static recog_method_f recog_event_method_array[RECOGNIZER_EVENT_COUNT] = { recog_event_start_of_input, - recog_event_recognition_complete + recog_event_recognition_complete, + recog_event_interpretation_complete }; /** Update state according to received incoming request from MRCP client */ @@ -412,6 +423,10 @@ static apt_bool_t recog_request_state_update(mrcp_recog_state_machine_t *state_m return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = recog_request_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -436,6 +451,10 @@ static apt_bool_t recog_response_state_update(mrcp_recog_state_machine_t *state_ return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Response "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = recog_response_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -451,6 +470,10 @@ static apt_bool_t recog_event_state_update(mrcp_recog_state_machine_t *state_mac return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = recog_event_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -505,7 +528,8 @@ static apt_bool_t recog_state_deactivate(mrcp_state_machine_t *base) message->start_line.request_id = source->start_line.request_id + 1; apt_string_set(&message->start_line.method_name,"DEACTIVATE"); /* informative only */ message->header = source->header; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create and Process STOP Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create and Process STOP Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return recog_request_dispatch(state_machine,message); } @@ -513,7 +537,6 @@ static apt_bool_t recog_state_deactivate(mrcp_state_machine_t *base) /** Create MRCP recognizer state machine */ mrcp_state_machine_t* mrcp_recog_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool) { - mrcp_message_header_t *properties; mrcp_recog_state_machine_t *state_machine = apr_palloc(pool,sizeof(mrcp_recog_state_machine_t)); mrcp_state_machine_init(&state_machine->base,obj); state_machine->base.update = recog_state_update; @@ -523,9 +546,9 @@ mrcp_state_machine_t* mrcp_recog_state_machine_create(void *obj, mrcp_version_e state_machine->active_request = NULL; state_machine->recog = NULL; state_machine->queue = apt_list_create(pool); - properties = &state_machine->properties; - mrcp_message_header_init(properties); - properties->generic_header_accessor.vtable = mrcp_generic_header_vtable_get(version); - properties->resource_header_accessor.vtable = mrcp_recog_header_vtable_get(version); + state_machine->properties = mrcp_message_header_create( + mrcp_generic_header_vtable_get(version), + mrcp_recog_header_vtable_get(version), + pool); return &state_machine->base; } diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_recorder_state_machine.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_recorder_state_machine.c index 9692d33244..312b4d57c3 100644 --- a/libs/unimrcp/libs/mrcp-engine/src/mrcp_recorder_state_machine.c +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_recorder_state_machine.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recorder_state_machine.c 1705 2010-05-23 14:04:20Z achaloyan $ */ #include "apt_obj_list.h" @@ -39,15 +41,15 @@ typedef struct mrcp_recorder_state_machine_t mrcp_recorder_state_machine_t; struct mrcp_recorder_state_machine_t { /** state machine base */ - mrcp_state_machine_t base; + mrcp_state_machine_t base; /** recorder state */ - mrcp_recorder_state_e state; + mrcp_recorder_state_e state; /** request sent to recorder engine and waiting for the response to be received */ - mrcp_message_t *active_request; + mrcp_message_t *active_request; /** in-progress record request */ - mrcp_message_t *record; + mrcp_message_t *record; /** properties used in set/get params */ - mrcp_message_header_t properties; + mrcp_message_header_t *properties; }; typedef apt_bool_t (*recorder_method_f)(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message); @@ -77,9 +79,12 @@ static APR_INLINE apt_bool_t recorder_event_dispatch(mrcp_recorder_state_machine return state_machine->base.on_dispatch(&state_machine->base,message); } -static APR_INLINE void recorder_state_change(mrcp_recorder_state_machine_t *state_machine, mrcp_recorder_state_e state) +static APR_INLINE void recorder_state_change(mrcp_recorder_state_machine_t *state_machine, mrcp_recorder_state_e state, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"State Transition %s -> %s",state_names[state_machine->state],state_names[state]); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"State Transition %s -> %s "APT_SIDRES_FMT, + state_names[state_machine->state], + state_names[state], + MRCP_MESSAGE_SIDRES(message)); state_machine->state = state; if(state == RECORDER_STATE_IDLE) { state_machine->record = NULL; @@ -89,41 +94,34 @@ static APR_INLINE void recorder_state_change(mrcp_recorder_state_machine_t *stat static apt_bool_t recorder_request_set_params(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SET-PARAMS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); - mrcp_message_header_set(&state_machine->properties,&message->header,message->pool); + mrcp_header_fields_set(state_machine->properties,&message->header,message->pool); return recorder_request_dispatch(state_machine,message); } static apt_bool_t recorder_response_set_params(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SET-PARAMS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recorder_response_dispatch(state_machine,message); } static apt_bool_t recorder_request_get_params(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-PARAMS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recorder_request_dispatch(state_machine,message); } static apt_bool_t recorder_response_get_params(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-PARAMS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); - mrcp_message_header_set(&message->header,&state_machine->active_request->header,message->pool); - mrcp_message_header_get(&message->header,&state_machine->properties,message->pool); + mrcp_header_fields_set(&message->header,&state_machine->active_request->header,message->pool); + mrcp_header_fields_get(&message->header,state_machine->properties,message->pool); return recorder_response_dispatch(state_machine,message); } static apt_bool_t recorder_request_record(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { - mrcp_message_header_inherit(&message->header,&state_machine->properties,message->pool); + mrcp_header_fields_inherit(&message->header,state_machine->properties,message->pool); if(state_machine->state == RECORDER_STATE_RECORDING) { mrcp_message_t *response; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Reject RECORD Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Reject RECORD Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); /* there is in-progress request, reject this one */ @@ -132,18 +130,14 @@ static apt_bool_t recorder_request_record(mrcp_recorder_state_machine_t *state_m return recorder_response_dispatch(state_machine,response); } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RECORD Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recorder_request_dispatch(state_machine,message); } static apt_bool_t recorder_response_record(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RECORD Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(message->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS) { state_machine->record = state_machine->active_request; - recorder_state_change(state_machine,RECORDER_STATE_RECORDING); + recorder_state_change(state_machine,RECORDER_STATE_RECORDING,message); } return recorder_response_dispatch(state_machine,message); } @@ -153,8 +147,6 @@ static apt_bool_t recorder_request_stop(mrcp_recorder_state_machine_t *state_mac mrcp_message_t *response; if(state_machine->state == RECORDER_STATE_RECORDING) { /* found in-progress RECORDER request, stop it */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process STOP Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recorder_request_dispatch(state_machine,message); } @@ -166,12 +158,10 @@ static apt_bool_t recorder_request_stop(mrcp_recorder_state_machine_t *state_mac static apt_bool_t recorder_response_stop(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process STOP Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); /* append active id list */ active_request_id_list_append(generic_header,state_machine->record->start_line.request_id); mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); - recorder_state_change(state_machine,RECORDER_STATE_IDLE); + recorder_state_change(state_machine,RECORDER_STATE_IDLE,message); return recorder_response_dispatch(state_machine,message); } @@ -180,8 +170,6 @@ static apt_bool_t recorder_request_start_timers(mrcp_recorder_state_machine_t *s mrcp_message_t *response; if(state_machine->state == RECORDER_STATE_RECORDING) { /* found in-progress request */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process START-INPUT-TIMERS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recorder_request_dispatch(state_machine,message); } @@ -193,8 +181,6 @@ static apt_bool_t recorder_request_start_timers(mrcp_recorder_state_machine_t *s static apt_bool_t recorder_response_start_timers(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process START-INPUT-TIMERS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return recorder_response_dispatch(state_machine,message); } @@ -210,8 +196,6 @@ static apt_bool_t recorder_event_start_of_input(mrcp_recorder_state_machine_t *s return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process START-OF-INPUT Event [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); message->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS; return recorder_event_dispatch(state_machine,message); } @@ -219,30 +203,32 @@ static apt_bool_t recorder_event_start_of_input(mrcp_recorder_state_machine_t *s static apt_bool_t recorder_event_record_complete(mrcp_recorder_state_machine_t *state_machine, mrcp_message_t *message) { if(!state_machine->record) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECORD-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECORD-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return FALSE; } if(state_machine->record->start_line.request_id != message->start_line.request_id) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECORD-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected RECORD-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return FALSE; } if(state_machine->active_request && state_machine->active_request->start_line.method_id == RECORDER_STOP) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Ignore RECORD-COMPLETE Event [%d]: waiting for STOP response",message->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Ignore RECORD-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]: waiting for STOP response", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RECORD-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(mrcp_resource_header_property_check(message,RECORDER_HEADER_COMPLETION_CAUSE) != TRUE) { mrcp_recorder_header_t *recorder_header = mrcp_resource_header_prepare(message); recorder_header->completion_cause = RECORDER_COMPLETION_CAUSE_SUCCESS_SILENCE; mrcp_resource_header_property_add(message,RECORDER_HEADER_COMPLETION_CAUSE); } - recorder_state_change(state_machine,RECORDER_STATE_IDLE); + recorder_state_change(state_machine,RECORDER_STATE_IDLE,message); return recorder_event_dispatch(state_machine,message); } @@ -275,6 +261,10 @@ static apt_bool_t recorder_request_state_update(mrcp_recorder_state_machine_t *s return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = recorder_request_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -299,6 +289,10 @@ static apt_bool_t recorder_response_state_update(mrcp_recorder_state_machine_t * return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Response "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = recorder_response_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -314,6 +308,10 @@ static apt_bool_t recorder_event_state_update(mrcp_recorder_state_machine_t *sta return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = recorder_event_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -368,7 +366,8 @@ static apt_bool_t recorder_state_deactivate(mrcp_state_machine_t *base) message->start_line.request_id = source->start_line.request_id + 1; apt_string_set(&message->start_line.method_name,"DEACTIVATE"); /* informative only */ message->header = source->header; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create and Process STOP Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create and Process STOP Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return recorder_request_dispatch(state_machine,message); } @@ -376,7 +375,6 @@ static apt_bool_t recorder_state_deactivate(mrcp_state_machine_t *base) /** Create MRCP recorder state machine */ mrcp_state_machine_t* mrcp_recorder_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool) { - mrcp_message_header_t *properties; mrcp_recorder_state_machine_t *state_machine = apr_palloc(pool,sizeof(mrcp_recorder_state_machine_t)); mrcp_state_machine_init(&state_machine->base,obj); state_machine->base.update = recorder_state_update; @@ -384,9 +382,9 @@ mrcp_state_machine_t* mrcp_recorder_state_machine_create(void *obj, mrcp_version state_machine->state = RECORDER_STATE_IDLE; state_machine->active_request = NULL; state_machine->record = NULL; - properties = &state_machine->properties; - mrcp_message_header_init(properties); - properties->generic_header_accessor.vtable = mrcp_generic_header_vtable_get(version); - properties->resource_header_accessor.vtable = mrcp_recorder_header_vtable_get(version); + state_machine->properties = mrcp_message_header_create( + mrcp_generic_header_vtable_get(version), + mrcp_recorder_header_vtable_get(version), + pool); return &state_machine->base; } diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_synth_state_machine.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_synth_state_machine.c index 01ff0af30f..523fbd3fbc 100644 --- a/libs/unimrcp/libs/mrcp-engine/src/mrcp_synth_state_machine.c +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_synth_state_machine.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_synth_state_machine.c 1705 2010-05-23 14:04:20Z achaloyan $ */ #include "apt_obj_list.h" @@ -41,19 +43,19 @@ static const char * state_names[SYNTHESIZER_STATE_COUNT] = { typedef struct mrcp_synth_state_machine_t mrcp_synth_state_machine_t; struct mrcp_synth_state_machine_t { /** state machine base */ - mrcp_state_machine_t base; + mrcp_state_machine_t base; /** synthesizer state */ - mrcp_synth_state_e state; + mrcp_synth_state_e state; /** indicate whether active_request was processed from pending request queue */ - apt_bool_t is_pending; + apt_bool_t is_pending; /** request sent to synthesizer engine and waiting for the response to be received */ - mrcp_message_t *active_request; + mrcp_message_t *active_request; /** in-progress speak request */ - mrcp_message_t *speaker; + mrcp_message_t *speaker; /** queue of pending speak requests */ - apt_obj_list_t *queue; + apt_obj_list_t *queue; /** properties used in set/get params */ - mrcp_message_header_t properties; + mrcp_message_header_t *properties; }; typedef apt_bool_t (*synth_method_f)(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message); @@ -83,9 +85,12 @@ static APR_INLINE apt_bool_t synth_event_dispatch(mrcp_synth_state_machine_t *st return state_machine->base.on_dispatch(&state_machine->base,message); } -static APR_INLINE void synth_state_change(mrcp_synth_state_machine_t *state_machine, mrcp_synth_state_e state) +static APR_INLINE void synth_state_change(mrcp_synth_state_machine_t *state_machine, mrcp_synth_state_e state, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"State Transition %s -> %s",state_names[state_machine->state],state_names[state]); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"State Transition %s -> %s "APT_SIDRES_FMT, + state_names[state_machine->state], + state_names[state], + MRCP_MESSAGE_SIDRES(message)); state_machine->state = state; if(state == SYNTHESIZER_STATE_IDLE) { state_machine->speaker = NULL; @@ -95,41 +100,34 @@ static APR_INLINE void synth_state_change(mrcp_synth_state_machine_t *state_mach static apt_bool_t synth_request_set_params(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SET-PARAMS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); - mrcp_message_header_set(&state_machine->properties,&message->header,message->pool); + mrcp_header_fields_set(state_machine->properties,&message->header,message->pool); return synth_request_dispatch(state_machine,message); } static apt_bool_t synth_response_set_params(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SET-PARAMS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return synth_response_dispatch(state_machine,message); } static apt_bool_t synth_request_get_params(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-PARAMS Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return synth_request_dispatch(state_machine,message); } static apt_bool_t synth_response_get_params(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process GET-PARAMS Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); - mrcp_message_header_set(&message->header,&state_machine->active_request->header,message->pool); - mrcp_message_header_get(&message->header,&state_machine->properties,message->pool); + mrcp_header_fields_set(&message->header,&state_machine->active_request->header,message->pool); + mrcp_header_fields_get(&message->header,state_machine->properties,message->pool); return synth_response_dispatch(state_machine,message); } static apt_bool_t synth_request_speak(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - mrcp_message_header_inherit(&message->header,&state_machine->properties,message->pool); + mrcp_header_fields_inherit(&message->header,state_machine->properties,message->pool); if(state_machine->speaker) { mrcp_message_t *response; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Queue Up SPEAK Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Queue Up SPEAK Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); message->start_line.request_state = MRCP_REQUEST_STATE_PENDING; apt_list_push_back(state_machine->queue,message,message->pool); @@ -139,18 +137,14 @@ static apt_bool_t synth_request_speak(mrcp_synth_state_machine_t *state_machine, return synth_response_dispatch(state_machine,response); } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SPEAK Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return synth_request_dispatch(state_machine,message); } static apt_bool_t synth_response_speak(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SPEAK Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(message->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS) { state_machine->speaker = state_machine->active_request; - synth_state_change(state_machine,SYNTHESIZER_STATE_SPEAKING); + synth_state_change(state_machine,SYNTHESIZER_STATE_SPEAKING,message); } if(state_machine->is_pending == TRUE) { mrcp_message_t *event_message = mrcp_event_create( @@ -183,7 +177,9 @@ static apt_bool_t synth_pending_requests_remove(mrcp_synth_state_machine_t *stat while(elem) { pending_message = apt_list_elem_object_get(elem); if(!request_id_list || active_request_id_list_find(generic_header,pending_message->start_line.request_id) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove Pending SPEAK Request [%d]",pending_message->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove Pending SPEAK Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(pending_message), + pending_message->start_line.request_id); elem = apt_list_elem_remove(state_machine->queue,elem); /* append active id list */ active_request_id_list_append(response_generic_header,pending_message->start_line.request_id); @@ -214,7 +210,8 @@ static apt_bool_t synth_request_stop(mrcp_synth_state_machine_t *state_machine, if(!request_id_list || active_request_id_list_find(generic_header,state_machine->speaker->start_line.request_id) == TRUE) { /* found in-progress SPEAK request, stop it */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process STOP Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Found IN-PROGRESS SPEAK Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return synth_request_dispatch(state_machine,message); } @@ -230,19 +227,19 @@ static apt_bool_t synth_response_stop(mrcp_synth_state_machine_t *state_machine, { mrcp_message_t *pending_request; mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process STOP Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); /* append active id list */ active_request_id_list_append(generic_header,state_machine->speaker->start_line.request_id); mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); synth_pending_requests_remove(state_machine,state_machine->active_request,message); - synth_state_change(state_machine,SYNTHESIZER_STATE_IDLE); + synth_state_change(state_machine,SYNTHESIZER_STATE_IDLE,message); pending_request = apt_list_pop_front(state_machine->queue); synth_response_dispatch(state_machine,message); /* process pending SPEAK requests / if any */ if(pending_request) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending SPEAK Request [%d]",pending_request->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending SPEAK Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), + pending_request->start_line.request_id); state_machine->is_pending = TRUE; synth_request_dispatch(state_machine,pending_request); } @@ -254,7 +251,6 @@ static apt_bool_t synth_request_pause(mrcp_synth_state_machine_t *state_machine, if(state_machine->speaker) { /* speaking or paused state */ if(state_machine->state == SYNTHESIZER_STATE_SPEAKING) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process PAUSE Request [%d]",state_machine->speaker->start_line.request_id); synth_request_dispatch(state_machine,message); } else { @@ -274,14 +270,12 @@ static apt_bool_t synth_request_pause(mrcp_synth_state_machine_t *state_machine, static apt_bool_t synth_response_pause(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process PAUSE Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(message->start_line.status_code == MRCP_STATUS_CODE_SUCCESS) { mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); /* append active id list */ active_request_id_list_append(generic_header,state_machine->speaker->start_line.request_id); mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); - synth_state_change(state_machine,SYNTHESIZER_STATE_PAUSED); + synth_state_change(state_machine,SYNTHESIZER_STATE_PAUSED,message); } synth_response_dispatch(state_machine,message); return TRUE; @@ -292,7 +286,6 @@ static apt_bool_t synth_request_resume(mrcp_synth_state_machine_t *state_machine if(state_machine->speaker) { /* speaking or paused state */ if(state_machine->state == SYNTHESIZER_STATE_PAUSED) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RESUME Request [%d]",state_machine->speaker->start_line.request_id); synth_request_dispatch(state_machine,message); } else { @@ -312,14 +305,12 @@ static apt_bool_t synth_request_resume(mrcp_synth_state_machine_t *state_machine static apt_bool_t synth_response_resume(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process RESUME Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(message->start_line.status_code == MRCP_STATUS_CODE_SUCCESS) { mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); /* append active id list */ active_request_id_list_append(generic_header,state_machine->speaker->start_line.request_id); mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); - synth_state_change(state_machine,SYNTHESIZER_STATE_SPEAKING); + synth_state_change(state_machine,SYNTHESIZER_STATE_SPEAKING,message); } synth_response_dispatch(state_machine,message); return TRUE; @@ -338,8 +329,6 @@ static apt_bool_t synth_request_barge_in_occurred(mrcp_synth_state_machine_t *st } if(kill_on_barge_in == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process BARGE-IN Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return synth_request_dispatch(state_machine,message); } } @@ -352,13 +341,11 @@ static apt_bool_t synth_request_barge_in_occurred(mrcp_synth_state_machine_t *st static apt_bool_t synth_response_barge_in_occurred(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process BARGE-IN Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); /* append active id list */ active_request_id_list_append(generic_header,state_machine->speaker->start_line.request_id); mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); synth_pending_requests_remove(state_machine,state_machine->active_request,message); - synth_state_change(state_machine,SYNTHESIZER_STATE_IDLE); + synth_state_change(state_machine,SYNTHESIZER_STATE_IDLE,message); return synth_response_dispatch(state_machine,message); } @@ -366,8 +353,6 @@ static apt_bool_t synth_request_control(mrcp_synth_state_machine_t *state_machin { mrcp_message_t *response_message; if(state_machine->state == SYNTHESIZER_STATE_SPEAKING) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process CONTROL Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return synth_request_dispatch(state_machine,message); } @@ -379,8 +364,6 @@ static apt_bool_t synth_request_control(mrcp_synth_state_machine_t *state_machin static apt_bool_t synth_response_control(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process CONTROL Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); /* append active id list */ active_request_id_list_append(generic_header,state_machine->speaker->start_line.request_id); mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); @@ -391,8 +374,6 @@ static apt_bool_t synth_request_define_lexicon(mrcp_synth_state_machine_t *state { mrcp_message_t *response_message; if(state_machine->state == SYNTHESIZER_STATE_IDLE) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process DEFINE-LEXICON Request [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return synth_request_dispatch(state_machine,message); } @@ -404,8 +385,6 @@ static apt_bool_t synth_request_define_lexicon(mrcp_synth_state_machine_t *state static apt_bool_t synth_response_define_lexicon(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process DEFINE-LEXICON Response [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); return synth_response_dispatch(state_machine,message); } @@ -421,8 +400,6 @@ static apt_bool_t synth_event_speech_marker(mrcp_synth_state_machine_t *state_ma return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SPEECH-MARKER Event [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); message->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS; return synth_event_dispatch(state_machine,message); } @@ -431,36 +408,40 @@ static apt_bool_t synth_event_speak_complete(mrcp_synth_state_machine_t *state_m { mrcp_message_t *pending_request; if(!state_machine->speaker) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected SPEAK-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected SPEAK-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return FALSE; } if(state_machine->speaker->start_line.request_id != message->start_line.request_id) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected SPEAK-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected SPEAK-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return FALSE; } if(state_machine->active_request && state_machine->active_request->start_line.method_id == SYNTHESIZER_STOP) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Ignore SPEAK-COMPLETE Event [%d]: waiting for STOP response",message->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Ignore SPEAK-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]: waiting for STOP response", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process SPEAK-COMPLETE Event [%"MRCP_REQUEST_ID_FMT"]", - message->start_line.request_id); if(mrcp_resource_header_property_check(message,SYNTHESIZER_HEADER_COMPLETION_CAUSE) != TRUE) { mrcp_synth_header_t *synth_header = mrcp_resource_header_prepare(message); synth_header->completion_cause = SYNTHESIZER_COMPLETION_CAUSE_NORMAL; mrcp_resource_header_property_add(message,SYNTHESIZER_HEADER_COMPLETION_CAUSE); } - synth_state_change(state_machine,SYNTHESIZER_STATE_IDLE); + synth_state_change(state_machine,SYNTHESIZER_STATE_IDLE,message); synth_event_dispatch(state_machine,message); /* process pending SPEAK requests */ pending_request = apt_list_pop_front(state_machine->queue); if(pending_request) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending SPEAK Request [%d]",pending_request->start_line.request_id); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process Pending SPEAK Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(pending_request), + pending_request->start_line.request_id); state_machine->is_pending = TRUE; synth_request_dispatch(state_machine,pending_request); } @@ -504,6 +485,10 @@ static apt_bool_t synth_request_state_update(mrcp_synth_state_machine_t *state_m return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = synth_request_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -528,6 +513,10 @@ static apt_bool_t synth_response_state_update(mrcp_synth_state_machine_t *state_ return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Response "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = synth_response_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -543,6 +532,10 @@ static apt_bool_t synth_event_state_update(mrcp_synth_state_machine_t *state_mac return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); method = synth_event_method_array[message->start_line.method_id]; if(method) { return method(state_machine,message); @@ -594,7 +587,8 @@ static apt_bool_t synth_state_deactivate(mrcp_state_machine_t *base) message->start_line.request_id = source->start_line.request_id + 1; apt_string_set(&message->start_line.method_name,"DEACTIVATE"); /* informative only */ message->header = source->header; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create and Process STOP Request [%"MRCP_REQUEST_ID_FMT"]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create and Process STOP Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), message->start_line.request_id); return synth_request_dispatch(state_machine,message); } @@ -602,7 +596,6 @@ static apt_bool_t synth_state_deactivate(mrcp_state_machine_t *base) /** Create MRCP synthesizer state machine */ mrcp_state_machine_t* mrcp_synth_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool) { - mrcp_message_header_t *properties; mrcp_synth_state_machine_t *state_machine = apr_palloc(pool,sizeof(mrcp_synth_state_machine_t)); mrcp_state_machine_init(&state_machine->base,obj); state_machine->base.update = synth_state_update; @@ -612,9 +605,9 @@ mrcp_state_machine_t* mrcp_synth_state_machine_create(void *obj, mrcp_version_e state_machine->active_request = NULL; state_machine->speaker = NULL; state_machine->queue = apt_list_create(pool); - properties = &state_machine->properties; - mrcp_message_header_init(properties); - properties->generic_header_accessor.vtable = mrcp_generic_header_vtable_get(version); - properties->resource_header_accessor.vtable = mrcp_synth_header_vtable_get(version); + state_machine->properties = mrcp_message_header_create( + mrcp_generic_header_vtable_get(version), + mrcp_synth_header_vtable_get(version), + pool); return &state_machine->base; } diff --git a/libs/unimrcp/libs/mrcp-engine/src/mrcp_verifier_state_machine.c b/libs/unimrcp/libs/mrcp-engine/src/mrcp_verifier_state_machine.c new file mode 100644 index 0000000000..335fdc9758 --- /dev/null +++ b/libs/unimrcp/libs/mrcp-engine/src/mrcp_verifier_state_machine.c @@ -0,0 +1,525 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: mrcp_verifier_state_machine.c 1756 2010-08-19 19:02:39Z achaloyan $ + */ + +#include "apt_obj_list.h" +#include "apt_log.h" +#include "mrcp_verifier_state_machine.h" +#include "mrcp_generic_header.h" +#include "mrcp_verifier_header.h" +#include "mrcp_verifier_resource.h" +#include "mrcp_message.h" + +/** MRCP verifier states */ +typedef enum { + VERIFIER_STATE_IDLE, + VERIFIER_STATE_OPENED, + VERIFIER_STATE_VERIFYING, + + VERIFIER_STATE_COUNT +} mrcp_verifier_state_e; + +static const char * state_names[VERIFIER_STATE_COUNT] = { + "IDLE", + "OPENED", + "VERIFYING" +}; + +typedef struct mrcp_verifier_state_machine_t mrcp_verifier_state_machine_t; + +struct mrcp_verifier_state_machine_t { + /** state machine base */ + mrcp_state_machine_t base; + /** verifier state */ + mrcp_verifier_state_e state; + /** request sent to verification engine and waiting for the response to be received */ + mrcp_message_t *active_request; + /** in-progress verify request */ + mrcp_message_t *verify; + /** properties used in set/get params */ + mrcp_message_header_t *properties; +}; + +typedef apt_bool_t (*verifier_method_f)(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message); + +static APR_INLINE apt_bool_t verifier_request_dispatch(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + state_machine->active_request = message; + return state_machine->base.on_dispatch(&state_machine->base,message); +} + +static APR_INLINE apt_bool_t verifier_response_dispatch(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + state_machine->active_request = NULL; + if(state_machine->base.active == FALSE) { + /* this is the response to deactivation (STOP) request */ + return state_machine->base.on_deactivate(&state_machine->base); + } + return state_machine->base.on_dispatch(&state_machine->base,message); +} + +static APR_INLINE apt_bool_t verifier_event_dispatch(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->base.active == FALSE) { + /* do nothing, state machine has already been deactivated */ + return FALSE; + } + return state_machine->base.on_dispatch(&state_machine->base,message); +} + +static APR_INLINE void verifier_state_change(mrcp_verifier_state_machine_t *state_machine, mrcp_verifier_state_e state, mrcp_message_t *message) +{ + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"State Transition %s -> %s "APT_SIDRES_FMT, + state_names[state_machine->state], + state_names[state], + MRCP_MESSAGE_SIDRES(message)); + state_machine->state = state; + if(state == VERIFIER_STATE_IDLE) { + state_machine->verify = NULL; + } +} + + +static apt_bool_t verifier_request_set_params(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + mrcp_header_fields_set(state_machine->properties,&message->header,message->pool); + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_set_params(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_get_params(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_get_params(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + mrcp_header_fields_set(&message->header,&state_machine->active_request->header,message->pool); + mrcp_header_fields_get(&message->header,state_machine->properties,message->pool); + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_start_session(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_VERIFYING) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_start_session(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + verifier_state_change(state_machine,VERIFIER_STATE_OPENED,message); + + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_end_session(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_IDLE) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_end_session(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + verifier_state_change(state_machine,VERIFIER_STATE_IDLE,message); + + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_query_voiceprint(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_IDLE) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_query_voiceprint(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_delete_voiceprint(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_IDLE) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_delete_voiceprint(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_verify(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_IDLE || state_machine->state == VERIFIER_STATE_VERIFYING) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + state_machine->verify = message; + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_verify(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + verifier_state_change(state_machine,VERIFIER_STATE_VERIFYING,message); + + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_verify_from_buffer(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_IDLE || state_machine->state == VERIFIER_STATE_VERIFYING) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + state_machine->verify = message; + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_verify_from_buffer(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + verifier_state_change(state_machine,VERIFIER_STATE_VERIFYING,message); + + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_verify_rollback(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_verify_rollback(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_stop(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_IDLE) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + if(state_machine->state == VERIFIER_STATE_OPENED) { + /* no in-progress VERIFY request, sending immediate response */ + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + return verifier_response_dispatch(state_machine,response_message); + } + + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_stop(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + mrcp_generic_header_t *generic_header = mrcp_generic_header_prepare(message); + /* append active id list */ + active_request_id_list_append(generic_header,state_machine->verify->start_line.request_id); + mrcp_generic_header_property_add(message,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); + verifier_state_change(state_machine,VERIFIER_STATE_OPENED,message); + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_clear_buffer(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_clear_buffer(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_start_input_timers(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state == VERIFIER_STATE_IDLE || state_machine->state == VERIFIER_STATE_VERIFYING) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_start_input_timers(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_response_dispatch(state_machine,message); +} + +static apt_bool_t verifier_request_get_intermidiate_result(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(state_machine->state != VERIFIER_STATE_VERIFYING) { + mrcp_message_t *response_message = mrcp_response_create(message,message->pool); + response_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_NOT_VALID; + return verifier_response_dispatch(state_machine,response_message); + } + return verifier_request_dispatch(state_machine,message); +} + +static apt_bool_t verifier_response_get_intermidiate_result(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + return verifier_response_dispatch(state_machine,message); +} + + +static apt_bool_t verifier_event_start_of_input(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(!state_machine->verify) { + /* unexpected event, no in-progress verify request */ + return FALSE; + } + + if(state_machine->verify->start_line.request_id != message->start_line.request_id) { + /* unexpected event */ + return FALSE; + } + + message->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS; + return verifier_event_dispatch(state_machine,message); +} + +static apt_bool_t verifier_event_verification_complete(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + if(!state_machine->verify) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected VERIFICATION-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + return FALSE; + } + + if(state_machine->verify->start_line.request_id != message->start_line.request_id) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Unexpected VERIFICATION-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + return FALSE; + } + + if(state_machine->active_request && state_machine->active_request->start_line.method_id == VERIFIER_STOP) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Ignore VERIFICATION-COMPLETE Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]: waiting for STOP response", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + return FALSE; + } + + if(mrcp_resource_header_property_check(message,VERIFIER_HEADER_COMPLETION_CAUSE) != TRUE) { + mrcp_verifier_header_t *verifier_header = mrcp_resource_header_prepare(message); + verifier_header->completion_cause = VERIFIER_COMPLETION_CAUSE_SUCCESS; + mrcp_resource_header_property_add(message,VERIFIER_HEADER_COMPLETION_CAUSE); + } + verifier_state_change(state_machine,VERIFIER_STATE_OPENED,message); + return verifier_event_dispatch(state_machine,message); +} + +static verifier_method_f verifier_request_method_array[VERIFIER_METHOD_COUNT] = { + verifier_request_set_params, + verifier_request_get_params, + verifier_request_start_session, + verifier_request_end_session, + verifier_request_query_voiceprint, + verifier_request_delete_voiceprint, + verifier_request_verify, + verifier_request_verify_from_buffer, + verifier_request_verify_rollback, + verifier_request_stop, + verifier_request_clear_buffer, + verifier_request_start_input_timers, + verifier_request_get_intermidiate_result +}; + +static verifier_method_f verifier_response_method_array[VERIFIER_METHOD_COUNT] = { + verifier_response_set_params, + verifier_response_get_params, + verifier_response_start_session, + verifier_response_end_session, + verifier_response_query_voiceprint, + verifier_response_delete_voiceprint, + verifier_response_verify, + verifier_response_verify_from_buffer, + verifier_response_verify_rollback, + verifier_response_stop, + verifier_response_clear_buffer, + verifier_response_start_input_timers, + verifier_response_get_intermidiate_result +}; + +static verifier_method_f verifier_event_method_array[VERIFIER_EVENT_COUNT] = { + verifier_event_start_of_input, + verifier_event_verification_complete +}; + +/** Update state according to received incoming request from MRCP client */ +static apt_bool_t verifier_request_state_update(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + verifier_method_f method; + if(message->start_line.method_id >= VERIFIER_METHOD_COUNT) { + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + method = verifier_request_method_array[message->start_line.method_id]; + if(method) { + return method(state_machine,message); + } + return verifier_request_dispatch(state_machine,message); +} + +/** Update state according to received outgoing response from verification engine */ +static apt_bool_t verifier_response_state_update(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + verifier_method_f method; + if(!state_machine->active_request) { + /* unexpected response, no active request waiting for response */ + return FALSE; + } + if(state_machine->active_request->start_line.request_id != message->start_line.request_id) { + /* unexpected response, request id doesn't match */ + return FALSE; + } + + if(message->start_line.method_id >= VERIFIER_METHOD_COUNT) { + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Response "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + method = verifier_response_method_array[message->start_line.method_id]; + if(method) { + return method(state_machine,message); + } + return verifier_response_dispatch(state_machine,message); +} + +/** Update state according to received outgoing event from verification engine */ +static apt_bool_t verifier_event_state_update(mrcp_verifier_state_machine_t *state_machine, mrcp_message_t *message) +{ + verifier_method_f method; + if(message->start_line.method_id >= VERIFIER_EVENT_COUNT) { + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Process %s Event "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + message->start_line.method_name.buf, + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + method = verifier_event_method_array[message->start_line.method_id]; + if(method) { + return method(state_machine,message); + } + return verifier_event_dispatch(state_machine,message); +} + +/** Update state according to request received from MRCP client or response/event received from verification engine */ +static apt_bool_t verifier_state_update(mrcp_state_machine_t *base, mrcp_message_t *message) +{ + mrcp_verifier_state_machine_t *state_machine = (mrcp_verifier_state_machine_t*)base; + apt_bool_t status = TRUE; + switch(message->start_line.message_type) { + case MRCP_MESSAGE_TYPE_REQUEST: + status = verifier_request_state_update(state_machine,message); + break; + case MRCP_MESSAGE_TYPE_RESPONSE: + status = verifier_response_state_update(state_machine,message); + break; + case MRCP_MESSAGE_TYPE_EVENT: + status = verifier_event_state_update(state_machine,message); + break; + default: + status = FALSE; + break; + } + return status; +} + +/** Deactivate state machine */ +static apt_bool_t verifier_state_deactivate(mrcp_state_machine_t *base) +{ + mrcp_verifier_state_machine_t *state_machine = (mrcp_verifier_state_machine_t*)base; + mrcp_message_t *message; + mrcp_message_t *source; + if(state_machine->state != VERIFIER_STATE_VERIFYING) { + /* no in-progress VERIFY request to deactivate */ + return FALSE; + } + source = state_machine->verify; + if(!source) { + return FALSE; + } + + /* create internal STOP request */ + message = mrcp_request_create( + source->resource, + source->start_line.version, + VERIFIER_STOP, + source->pool); + message->channel_id = source->channel_id; + message->start_line.request_id = source->start_line.request_id + 1; + apt_string_set(&message->start_line.method_name,"DEACTIVATE"); /* informative only */ + message->header = source->header; + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create and Process STOP Request "APT_SIDRES_FMT" [%"MRCP_REQUEST_ID_FMT"]", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + return verifier_request_dispatch(state_machine,message); +} + +/** Create MRCP verification state machine */ +mrcp_state_machine_t* mrcp_verifier_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool) +{ + mrcp_verifier_state_machine_t *state_machine = apr_palloc(pool,sizeof(mrcp_verifier_state_machine_t)); + mrcp_state_machine_init(&state_machine->base,obj); + state_machine->base.update = verifier_state_update; + state_machine->base.deactivate = verifier_state_deactivate; + state_machine->state = VERIFIER_STATE_IDLE; + state_machine->active_request = NULL; + state_machine->verify = NULL; + state_machine->properties = mrcp_message_header_create( + mrcp_generic_header_vtable_get(version), + mrcp_verifier_header_vtable_get(version), + pool); + return &state_machine->base; +} diff --git a/libs/unimrcp/libs/mrcp-server/include/mrcp_server.h b/libs/unimrcp/libs/mrcp-server/include/mrcp_server.h index 59a33db059..f2bf49fe37 100644 --- a/libs/unimrcp/libs/mrcp-server/include/mrcp_server.h +++ b/libs/unimrcp/libs/mrcp-server/include/mrcp_server.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_server.h 1721 2010-06-01 05:45:46Z achaloyan $ */ -#ifndef __MRCP_SERVER_H__ -#define __MRCP_SERVER_H__ +#ifndef MRCP_SERVER_H +#define MRCP_SERVER_H /** * @file mrcp_server.h @@ -24,6 +26,7 @@ #include "mrcp_server_types.h" #include "mrcp_engine_iface.h" +#include "mpf_rtp_descriptor.h" #include "apt_task.h" APT_BEGIN_EXTERN_C @@ -59,15 +62,18 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_destroy(mrcp_server_t *server); * @param server the MRCP server to set resource factory for * @param resource_factory the resource factory to set */ -MRCP_DECLARE(apt_bool_t) mrcp_server_resource_factory_register(mrcp_server_t *server, mrcp_resource_factory_t *resource_factory); +MRCP_DECLARE(apt_bool_t) mrcp_server_resource_factory_register( + mrcp_server_t *server, + mrcp_resource_factory_t *resource_factory); /** * Register MRCP engine. * @param server the MRCP server to set engine for * @param engine the engine to set - * @param config the config of the engine */ -MRCP_DECLARE(apt_bool_t) mrcp_server_engine_register(mrcp_server_t *server, mrcp_engine_t *engine, mrcp_engine_config_t *config); +MRCP_DECLARE(apt_bool_t) mrcp_server_engine_register( + mrcp_server_t *server, + mrcp_engine_t *engine); /** * Register codec manager. @@ -80,15 +86,16 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_codec_manager_register(mrcp_server_t *serve * Get registered codec manager. * @param server the MRCP server to get codec manager from */ -MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_server_codec_manager_get(mrcp_server_t *server); +MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_server_codec_manager_get(const mrcp_server_t *server); /** * Register media engine. * @param server the MRCP server to set media engine for * @param media_engine the media engine to set - * @param name the name of the media engine */ -MRCP_DECLARE(apt_bool_t) mrcp_server_media_engine_register(mrcp_server_t *server, mpf_engine_t *media_engine, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_server_media_engine_register( + mrcp_server_t *server, + mpf_engine_t *media_engine); /** * Register RTP termination factory. @@ -96,95 +103,123 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_media_engine_register(mrcp_server_t *server * @param rtp_termination_factory the termination factory * @param name the name of the factory */ -MRCP_DECLARE(apt_bool_t) mrcp_server_rtp_factory_register(mrcp_server_t *server, mpf_termination_factory_t *rtp_termination_factory, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_server_rtp_factory_register( + mrcp_server_t *server, + mpf_termination_factory_t *rtp_termination_factory, + const char *name); + +/** + * Register RTP settings. + * @param server the MRCP server to set RTP settings for + * @param rtp_settings the settings to set + * @param name the name of the settings + */ +MRCP_DECLARE(apt_bool_t) mrcp_server_rtp_settings_register( + mrcp_server_t *server, + mpf_rtp_settings_t *rtp_settings, + const char *name); /** * Register MRCP signaling agent. * @param server the MRCP server to set signaling agent for * @param signaling_agent the signaling agent to set - * @param name the name of the agent */ -MRCP_DECLARE(apt_bool_t) mrcp_server_signaling_agent_register(mrcp_server_t *server, mrcp_sig_agent_t *signaling_agent, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_server_signaling_agent_register( + mrcp_server_t *server, + mrcp_sig_agent_t *signaling_agent); /** * Register MRCP connection agent (MRCPv2 only). * @param server the MRCP server to set connection agent for * @param connection_agent the connection agent to set - * @param name the name of the agent */ -MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_register(mrcp_server_t *server, mrcp_connection_agent_t *connection_agent, const char *name); +MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_register( + mrcp_server_t *server, + mrcp_connection_agent_t *connection_agent); /** Create MRCP profile */ MRCP_DECLARE(mrcp_profile_t*) mrcp_server_profile_create( - mrcp_resource_factory_t *resource_factory, - mrcp_sig_agent_t *signaling_agent, - mrcp_connection_agent_t *connection_agent, - mpf_engine_t *media_engine, - mpf_termination_factory_t *rtp_factory, - apr_pool_t *pool); + const char *id, + mrcp_resource_factory_t *resource_factory, + mrcp_sig_agent_t *signaling_agent, + mrcp_connection_agent_t *connection_agent, + mpf_engine_t *media_engine, + mpf_termination_factory_t *rtp_factory, + mpf_rtp_settings_t *rtp_settings, + apr_pool_t *pool); /** * Register MRCP profile. * @param server the MRCP server to set profile for * @param profile the profile to set * @param plugin_map the map of engines (plugins) - * @param name the name of the profile */ MRCP_DECLARE(apt_bool_t) mrcp_server_profile_register( mrcp_server_t *server, mrcp_profile_t *profile, - apr_table_t *plugin_map, - const char *name); + apr_table_t *plugin_map); /** - * Register MRCP engine plugin. - * @param server the MRCP server to set engine for - * @param path the path to plugin - * @param config the config of the plugin + * Load MRCP engine as a plugin. + * @param server the MRCP server to use + * @param id the identifier of the plugin + * @param path the path to the plugin to load + * @param config the config of the engine */ -MRCP_DECLARE(apt_bool_t) mrcp_server_plugin_register(mrcp_server_t *server, const char *path, mrcp_engine_config_t *config); +MRCP_DECLARE(mrcp_engine_t*) mrcp_server_engine_load( + mrcp_server_t *server, + const char *id, + const char *path, + mrcp_engine_config_t *config); /** * Get memory pool. * @param server the MRCP server to get memory pool from */ -MRCP_DECLARE(apr_pool_t*) mrcp_server_memory_pool_get(mrcp_server_t *server); +MRCP_DECLARE(apr_pool_t*) mrcp_server_memory_pool_get(const mrcp_server_t *server); /** * Get media engine by name. * @param server the MRCP server to get media engine from * @param name the name of the media engine to lookup */ -MRCP_DECLARE(mpf_engine_t*) mrcp_server_media_engine_get(mrcp_server_t *server, const char *name); +MRCP_DECLARE(mpf_engine_t*) mrcp_server_media_engine_get(const mrcp_server_t *server, const char *name); /** * Get RTP termination factory by name. * @param server the MRCP server to get from * @param name the name to lookup */ -MRCP_DECLARE(mpf_termination_factory_t*) mrcp_server_rtp_factory_get(mrcp_server_t *server, const char *name); +MRCP_DECLARE(mpf_termination_factory_t*) mrcp_server_rtp_factory_get(const mrcp_server_t *server, const char *name); + +/** + * Get RTP settings by name + * @param server the MRCP server to get from + * @param name the name to lookup + */ +MRCP_DECLARE(mpf_rtp_settings_t*) mrcp_server_rtp_settings_get(const mrcp_server_t *server, const char *name); /** * Get signaling agent by name. * @param server the MRCP server to get from * @param name the name to lookup */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_server_signaling_agent_get(mrcp_server_t *server, const char *name); +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_server_signaling_agent_get(const mrcp_server_t *server, const char *name); /** * Get connection agent by name. * @param server the MRCP server to get from * @param name the name to lookup */ -MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_server_connection_agent_get(mrcp_server_t *server, const char *name); +MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_server_connection_agent_get(const mrcp_server_t *server, const char *name); /** * Get profile by name. * @param server the MRCP client to get from * @param name the name to lookup */ -MRCP_DECLARE(mrcp_profile_t*) mrcp_server_profile_get(mrcp_server_t *server, const char *name); +MRCP_DECLARE(mrcp_profile_t*) mrcp_server_profile_get(const mrcp_server_t *server, const char *name); APT_END_EXTERN_C -#endif /*__MRCP_SERVER_H__*/ +#endif /* MRCP_SERVER_H */ diff --git a/libs/unimrcp/libs/mrcp-server/include/mrcp_server_session.h b/libs/unimrcp/libs/mrcp-server/include/mrcp_server_session.h index 4cd88f6b3e..07258f0298 100644 --- a/libs/unimrcp/libs/mrcp-server/include/mrcp_server_session.h +++ b/libs/unimrcp/libs/mrcp-server/include/mrcp_server_session.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_server_session.h 1700 2010-05-21 18:56:06Z achaloyan $ */ -#ifndef __MRCP_SERVER_SESSION_H__ -#define __MRCP_SERVER_SESSION_H__ +#ifndef MRCP_SERVER_SESSION_H +#define MRCP_SERVER_SESSION_H /** * @file mrcp_server_session.h @@ -109,6 +111,8 @@ struct mrcp_server_session_t { /** MRCP profile */ struct mrcp_profile_t { + /** Identifier of the profile */ + const char *id; /** Table of engines (mrcp_engine_t*) */ apr_hash_t *engine_table; /** MRCP resource factory */ @@ -117,6 +121,8 @@ struct mrcp_profile_t { mpf_engine_t *media_engine; /** RTP termination factory */ mpf_termination_factory_t *rtp_termination_factory; + /** RTP settings */ + mpf_rtp_settings_t *rtp_settings; /** Signaling agent */ mrcp_sig_agent_t *signaling_agent; /** Connection agent */ @@ -152,4 +158,4 @@ mrcp_session_t* mrcp_server_channel_session_get(mrcp_channel_t *channel); APT_END_EXTERN_C -#endif /*__MRCP_SERVER_SESSION_H__*/ +#endif /* MRCP_SERVER_SESSION_H */ diff --git a/libs/unimrcp/libs/mrcp-server/include/mrcp_server_types.h b/libs/unimrcp/libs/mrcp-server/include/mrcp_server_types.h index ac640fc750..2c9f3f0be8 100644 --- a/libs/unimrcp/libs/mrcp-server/include/mrcp_server_types.h +++ b/libs/unimrcp/libs/mrcp-server/include/mrcp_server_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_server_types.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_SERVER_TYPES_H__ -#define __MRCP_SERVER_TYPES_H__ +#ifndef MRCP_SERVER_TYPES_H +#define MRCP_SERVER_TYPES_H /** * @file mrcp_server_types.h @@ -37,4 +39,4 @@ typedef struct mrcp_profile_t mrcp_profile_t; APT_END_EXTERN_C -#endif /*__MRCP_SERVER_TYPES_H__*/ +#endif /* MRCP_SERVER_TYPES_H */ diff --git a/libs/unimrcp/libs/mrcp-server/mrcpserver.2008.vcproj b/libs/unimrcp/libs/mrcp-server/mrcpserver.2008.vcproj deleted file mode 100644 index fe124d4a8a..0000000000 --- a/libs/unimrcp/libs/mrcp-server/mrcpserver.2008.vcproj +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/mrcp-server/src/mrcp_server.c b/libs/unimrcp/libs/mrcp-server/src/mrcp_server.c index 0c8d2a8a07..bd1b6aa848 100644 --- a/libs/unimrcp/libs/mrcp-server/src/mrcp_server.c +++ b/libs/unimrcp/libs/mrcp-server/src/mrcp_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_server.c 1721 2010-06-01 05:45:46Z achaloyan $ */ #include "mrcp_server.h" @@ -53,6 +55,8 @@ struct mrcp_server_t { apr_hash_t *sig_agent_table; /** Table of connection agents (mrcp_connection_agent_t*) */ apr_hash_t *cnt_agent_table; + /** Table of RTP settings (mpf_rtp_settings_t*) */ + apr_hash_t *rtp_settings_table; /** Table of profiles (mrcp_profile_t*) */ apr_hash_t *profile_table; @@ -126,6 +130,8 @@ static const mrcp_connection_event_vtable_t connection_method_vtable = { /* MRCP engine interface */ typedef enum { + ENGINE_TASK_MSG_OPEN_ENGINE, + ENGINE_TASK_MSG_CLOSE_ENGINE, ENGINE_TASK_MSG_OPEN_CHANNEL, ENGINE_TASK_MSG_CLOSE_CHANNEL, ENGINE_TASK_MSG_MESSAGE @@ -133,11 +139,20 @@ typedef enum { typedef struct engine_task_msg_data_t engine_task_msg_data_t; struct engine_task_msg_data_t { + mrcp_engine_t *engine; mrcp_channel_t *channel; apt_bool_t status; mrcp_message_t *mrcp_message; }; +static apt_bool_t mrcp_server_engine_open_signal(mrcp_engine_t *engine, apt_bool_t status); +static apt_bool_t mrcp_server_engine_close_signal(mrcp_engine_t *engine); + +const mrcp_engine_event_vtable_t engine_vtable = { + mrcp_server_engine_open_signal, + mrcp_server_engine_close_signal, +}; + static apt_bool_t mrcp_server_channel_open_signal(mrcp_engine_channel_t *channel, apt_bool_t status); static apt_bool_t mrcp_server_channel_close_signal(mrcp_engine_channel_t *channel); static apt_bool_t mrcp_server_channel_message_signal(mrcp_engine_channel_t *channel, mrcp_message_t *message); @@ -149,6 +164,8 @@ const mrcp_engine_channel_event_vtable_t engine_channel_vtable = { }; /* Task interface */ +static void mrcp_server_on_start_request(apt_task_t *task); +static void mrcp_server_on_terminate_request(apt_task_t *task); static void mrcp_server_on_start_complete(apt_task_t *task); static void mrcp_server_on_terminate_complete(apt_task_t *task); static apt_bool_t mrcp_server_msg_process(apt_task_t *task, apt_task_msg_t *msg); @@ -181,6 +198,7 @@ MRCP_DECLARE(mrcp_server_t*) mrcp_server_create(apt_dir_layout_t *dir_layout) server->rtp_factory_table = NULL; server->sig_agent_table = NULL; server->cnt_agent_table = NULL; + server->rtp_settings_table = NULL; server->profile_table = NULL; server->session_table = NULL; server->connection_msg_pool = NULL; @@ -198,6 +216,8 @@ MRCP_DECLARE(mrcp_server_t*) mrcp_server_create(apt_dir_layout_t *dir_layout) vtable = apt_task_vtable_get(task); if(vtable) { vtable->process_msg = mrcp_server_msg_process; + vtable->on_start_request = mrcp_server_on_start_request; + vtable->on_terminate_request = mrcp_server_on_terminate_request; vtable->on_start_complete = mrcp_server_on_start_complete; vtable->on_terminate_complete = mrcp_server_on_terminate_complete; } @@ -207,6 +227,7 @@ MRCP_DECLARE(mrcp_server_t*) mrcp_server_create(apt_dir_layout_t *dir_layout) server->media_engine_table = apr_hash_make(server->pool); server->rtp_factory_table = apr_hash_make(server->pool); + server->rtp_settings_table = apr_hash_make(server->pool); server->sig_agent_table = apr_hash_make(server->pool); server->cnt_agent_table = apr_hash_make(server->pool); @@ -249,7 +270,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_shutdown(mrcp_server_t *server) } server->session_table = NULL; uptime = apr_time_now() - server->start_time; - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Server Uptime [%d sec]", apr_time_sec(uptime)); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Server Uptime [%"APR_TIME_T_FMT" sec]", apr_time_sec(uptime)); return TRUE; } @@ -284,19 +305,21 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_resource_factory_register(mrcp_server_t *se } /** Register MRCP engine */ -MRCP_DECLARE(apt_bool_t) mrcp_server_engine_register(mrcp_server_t *server, mrcp_engine_t *engine, mrcp_engine_config_t *config) +MRCP_DECLARE(apt_bool_t) mrcp_server_engine_register(mrcp_server_t *server, mrcp_engine_t *engine) { - if(!engine || !config || !config->name) { + if(!engine || !engine->id) { return FALSE; } + if(!server->engine_msg_pool) { server->engine_msg_pool = apt_task_msg_pool_create_dynamic(sizeof(engine_task_msg_data_t),server->pool); } - engine->config = config; engine->codec_manager = server->codec_manager; engine->dir_layout = server->dir_layout; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register MRCP Engine [%s]",config->name); - return mrcp_engine_factory_engine_register(server->engine_factory,engine,config->name); + engine->event_vtable = &engine_vtable; + engine->event_obj = server; + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register MRCP Engine [%s]",engine->id); + return mrcp_engine_factory_engine_register(server->engine_factory,engine); } /** Register codec manager */ @@ -310,20 +333,26 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_codec_manager_register(mrcp_server_t *serve } /** Get registered codec manager */ -MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_server_codec_manager_get(mrcp_server_t *server) +MRCP_DECLARE(const mpf_codec_manager_t*) mrcp_server_codec_manager_get(const mrcp_server_t *server) { return server->codec_manager; } /** Register media engine */ -MRCP_DECLARE(apt_bool_t) mrcp_server_media_engine_register(mrcp_server_t *server, mpf_engine_t *media_engine, const char *name) +MRCP_DECLARE(apt_bool_t) mrcp_server_media_engine_register(mrcp_server_t *server, mpf_engine_t *media_engine) { - if(!media_engine || !name) { + const char *id; + if(!media_engine) { + return FALSE; + } + id = mpf_engine_id_get(media_engine); + if(!id) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Media Engine [%s]",name); + + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Media Engine [%s]",id); mpf_engine_codec_manager_register(media_engine,server->codec_manager); - apr_hash_set(server->media_engine_table,name,APR_HASH_KEY_STRING,media_engine); + apr_hash_set(server->media_engine_table,id,APR_HASH_KEY_STRING,media_engine); mpf_engine_task_msg_type_set(media_engine,MRCP_SERVER_MEDIA_TASK_MSG); if(server->task) { apt_task_t *media_task = mpf_task_get(media_engine); @@ -334,7 +363,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_media_engine_register(mrcp_server_t *server } /** Get media engine by name */ -MRCP_DECLARE(mpf_engine_t*) mrcp_server_media_engine_get(mrcp_server_t *server, const char *name) +MRCP_DECLARE(mpf_engine_t*) mrcp_server_media_engine_get(const mrcp_server_t *server, const char *name) { return apr_hash_get(server->media_engine_table,name,APR_HASH_KEY_STRING); } @@ -351,23 +380,40 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_rtp_factory_register(mrcp_server_t *server, } /** Get RTP termination factory by name */ -MRCP_DECLARE(mpf_termination_factory_t*) mrcp_server_rtp_factory_get(mrcp_server_t *server, const char *name) +MRCP_DECLARE(mpf_termination_factory_t*) mrcp_server_rtp_factory_get(const mrcp_server_t *server, const char *name) { return apr_hash_get(server->rtp_factory_table,name,APR_HASH_KEY_STRING); } +/** Register RTP settings */ +MRCP_DECLARE(apt_bool_t) mrcp_server_rtp_settings_register(mrcp_server_t *server, mpf_rtp_settings_t *rtp_settings, const char *name) +{ + if(!rtp_settings || !name) { + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register RTP Settings [%s]",name); + apr_hash_set(server->rtp_settings_table,name,APR_HASH_KEY_STRING,rtp_settings); + return TRUE; +} + +/** Get RTP settings by name */ +MRCP_DECLARE(mpf_rtp_settings_t*) mrcp_server_rtp_settings_get(const mrcp_server_t *server, const char *name) +{ + return apr_hash_get(server->rtp_settings_table,name,APR_HASH_KEY_STRING); +} + /** Register MRCP signaling agent */ -MRCP_DECLARE(apt_bool_t) mrcp_server_signaling_agent_register(mrcp_server_t *server, mrcp_sig_agent_t *signaling_agent, const char *name) +MRCP_DECLARE(apt_bool_t) mrcp_server_signaling_agent_register(mrcp_server_t *server, mrcp_sig_agent_t *signaling_agent) { - if(!signaling_agent || !name) { + if(!signaling_agent || !signaling_agent->id) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Signaling Agent [%s]",name); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Signaling Agent [%s]",signaling_agent->id); signaling_agent->parent = server; signaling_agent->resource_factory = server->resource_factory; signaling_agent->create_server_session = mrcp_server_sig_agent_session_create; signaling_agent->msg_pool = apt_task_msg_pool_create_dynamic(sizeof(mrcp_signaling_message_t*),server->pool); - apr_hash_set(server->sig_agent_table,name,APR_HASH_KEY_STRING,signaling_agent); + apr_hash_set(server->sig_agent_table,signaling_agent->id,APR_HASH_KEY_STRING,signaling_agent); if(server->task) { apt_task_t *task = apt_consumer_task_base_get(server->task); apt_task_add(task,signaling_agent->task); @@ -376,22 +422,27 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_signaling_agent_register(mrcp_server_t *ser } /** Get signaling agent by name */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_server_signaling_agent_get(mrcp_server_t *server, const char *name) +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_server_signaling_agent_get(const mrcp_server_t *server, const char *name) { return apr_hash_get(server->sig_agent_table,name,APR_HASH_KEY_STRING); } /** Register MRCP connection agent (MRCPv2 only) */ -MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_register(mrcp_server_t *server, mrcp_connection_agent_t *connection_agent, const char *name) +MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_register(mrcp_server_t *server, mrcp_connection_agent_t *connection_agent) { - if(!connection_agent || !name) { + const char *id; + if(!connection_agent) { return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Connection Agent [%s]",name); + id = mrcp_server_connection_agent_id_get(connection_agent); + if(!id) { + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Connection Agent [%s]",id); mrcp_server_connection_resource_factory_set(connection_agent,server->resource_factory); mrcp_server_connection_agent_handler_set(connection_agent,server,&connection_method_vtable); server->connection_msg_pool = apt_task_msg_pool_create_dynamic(sizeof(connection_agent_task_msg_data_t),server->pool); - apr_hash_set(server->cnt_agent_table,name,APR_HASH_KEY_STRING,connection_agent); + apr_hash_set(server->cnt_agent_table,id,APR_HASH_KEY_STRING,connection_agent); if(server->task) { apt_task_t *task = apt_consumer_task_base_get(server->task); apt_task_t *connection_task = mrcp_server_connection_agent_task_get(connection_agent); @@ -401,25 +452,29 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_register(mrcp_server_t *se } /** Get connection agent by name */ -MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_server_connection_agent_get(mrcp_server_t *server, const char *name) +MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_server_connection_agent_get(const mrcp_server_t *server, const char *name) { return apr_hash_get(server->cnt_agent_table,name,APR_HASH_KEY_STRING); } /** Create MRCP profile */ MRCP_DECLARE(mrcp_profile_t*) mrcp_server_profile_create( + const char *id, mrcp_resource_factory_t *resource_factory, mrcp_sig_agent_t *signaling_agent, mrcp_connection_agent_t *connection_agent, mpf_engine_t *media_engine, mpf_termination_factory_t *rtp_factory, + mpf_rtp_settings_t *rtp_settings, apr_pool_t *pool) { mrcp_profile_t *profile = apr_palloc(pool,sizeof(mrcp_profile_t)); + profile->id = id; profile->resource_factory = resource_factory; profile->engine_table = NULL; profile->media_engine = media_engine; profile->rtp_termination_factory = rtp_factory; + profile->rtp_settings = rtp_settings; profile->signaling_agent = signaling_agent; profile->connection_agent = connection_agent; return profile; @@ -452,8 +507,8 @@ static apt_bool_t mrcp_server_engine_table_make(mrcp_server_t *server, mrcp_prof } if(engine) { - if(engine->config->name) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Assign MRCP Engine [%s] [%s]",resource->name.buf,engine->config->name); + if(engine->id) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Assign MRCP Engine [%s] [%s]",resource->name.buf,engine->id); } apr_hash_set(profile->engine_table,resource->name.buf,resource->name.length,engine); } @@ -467,18 +522,17 @@ static apt_bool_t mrcp_server_engine_table_make(mrcp_server_t *server, mrcp_prof /** Register MRCP profile */ MRCP_DECLARE(apt_bool_t) mrcp_server_profile_register( - mrcp_server_t *server, - mrcp_profile_t *profile, - apr_table_t *plugin_map, - const char *name) + mrcp_server_t *server, + mrcp_profile_t *profile, + apr_table_t *plugin_map) { - if(!profile || !name) { + if(!profile || !profile->id) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile: no name"); return FALSE; } if(!profile->resource_factory) { if(!server->resource_factory) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile: no resources"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing resource factory",profile->id); return FALSE; } profile->resource_factory = server->resource_factory; @@ -486,58 +540,55 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_profile_register( mrcp_server_engine_table_make(server,profile,plugin_map); if(!profile->signaling_agent) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing signaling agent",name); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing signaling agent",profile->id); return FALSE; } if(profile->signaling_agent->mrcp_version == MRCP_VERSION_2 && !profile->connection_agent) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing connection agent",name); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing connection agent",profile->id); return FALSE; } if(!profile->media_engine) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing media engine",name); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing media engine",profile->id); return FALSE; } if(!profile->rtp_termination_factory) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing RTP factory",name); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Register Profile [%s]: missing RTP factory",profile->id); return FALSE; } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Profile [%s]",name); - apr_hash_set(server->profile_table,name,APR_HASH_KEY_STRING,profile); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register Profile [%s]",profile->id); + apr_hash_set(server->profile_table,profile->id,APR_HASH_KEY_STRING,profile); return TRUE; } /** Get profile by name */ -MRCP_DECLARE(mrcp_profile_t*) mrcp_server_profile_get(mrcp_server_t *server, const char *name) +MRCP_DECLARE(mrcp_profile_t*) mrcp_server_profile_get(const mrcp_server_t *server, const char *name) { return apr_hash_get(server->profile_table,name,APR_HASH_KEY_STRING); } -/** Register MRCP engine plugin */ -MRCP_DECLARE(apt_bool_t) mrcp_server_plugin_register(mrcp_server_t *server, const char *path, mrcp_engine_config_t *config) +/** Load MRCP engine */ +MRCP_DECLARE(mrcp_engine_t*) mrcp_server_engine_load( + mrcp_server_t *server, + const char *id, + const char *path, + mrcp_engine_config_t *config) { mrcp_engine_t *engine; - if(!config) { + if(!id || !path || !config) { return FALSE; } - - engine = mrcp_engine_loader_plugin_load(server->engine_loader,path,config->name); + + engine = mrcp_engine_loader_plugin_load(server->engine_loader,id,path,config); if(!engine) { return FALSE; } - if(!server->engine_msg_pool) { - server->engine_msg_pool = apt_task_msg_pool_create_dynamic(sizeof(engine_task_msg_data_t),server->pool); - } - engine->config = config; - engine->codec_manager = server->codec_manager; - engine->dir_layout = server->dir_layout; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Register MRCP Engine [%s]",config->name); - return mrcp_engine_factory_engine_register(server->engine_factory,engine,config->name); + return engine; } -MRCP_DECLARE(apr_pool_t*) mrcp_server_memory_pool_get(mrcp_server_t *server) +MRCP_DECLARE(apr_pool_t*) mrcp_server_memory_pool_get(const mrcp_server_t *server) { return server->pool; } @@ -563,22 +614,53 @@ static APR_INLINE mrcp_server_session_t* mrcp_server_session_find(mrcp_server_t return apr_hash_get(server->session_table,session_id->buf,session_id->length); } - -static void mrcp_server_on_start_complete(apt_task_t *task) +static void mrcp_server_on_start_request(apt_task_t *task) { apt_consumer_task_t *consumer_task = apt_task_object_get(task); mrcp_server_t *server = apt_consumer_task_object_get(consumer_task); - mrcp_engine_factory_open(server->engine_factory); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,SERVER_TASK_NAME" Started"); + mrcp_engine_t *engine; + apr_hash_index_t *it; + void *val; + it = mrcp_engine_factory_engine_first(server->engine_factory); + for(; it; it = apr_hash_next(it)) { + apr_hash_this(it,NULL,NULL,&val); + engine = val; + if(engine) { + if(mrcp_engine_virtual_open(engine) == TRUE) { + apt_task_start_request_add(task); + } + } + } } -static void mrcp_server_on_terminate_complete(apt_task_t *task) +static void mrcp_server_on_terminate_request(apt_task_t *task) { apt_consumer_task_t *consumer_task = apt_task_object_get(task); mrcp_server_t *server = apt_consumer_task_object_get(consumer_task); - mrcp_engine_factory_close(server->engine_factory); + mrcp_engine_t *engine; + apr_hash_index_t *it; + void *val; + it = mrcp_engine_factory_engine_first(server->engine_factory); + for(; it; it = apr_hash_next(it)) { + apr_hash_this(it,NULL,NULL,&val); + engine = val; + if(engine) { + if(mrcp_engine_virtual_close(engine) == TRUE) { + apt_task_terminate_request_add(task); + } + } + } +} + +static void mrcp_server_on_start_complete(apt_task_t *task) +{ + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,SERVER_TASK_NAME" Started"); +} + +static void mrcp_server_on_terminate_complete(apt_task_t *task) +{ apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,SERVER_TASK_NAME" Terminated"); } @@ -588,14 +670,12 @@ static apt_bool_t mrcp_server_msg_process(apt_task_t *task, apt_task_msg_t *msg) case MRCP_SERVER_SIGNALING_TASK_MSG: { mrcp_signaling_message_t **signaling_message = (mrcp_signaling_message_t**) msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Signaling Task Message [%d]", (*signaling_message)->type); mrcp_server_signaling_message_process(*signaling_message); break; } case MRCP_SERVER_CONNECTION_TASK_MSG: { const connection_agent_task_msg_data_t *connection_message = (const connection_agent_task_msg_data_t*)msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Connection Task Message [%d]", msg->sub_type); switch(msg->sub_type) { case CONNECTION_AGENT_TASK_MSG_ADD_CHANNEL: { @@ -630,8 +710,15 @@ static apt_bool_t mrcp_server_msg_process(apt_task_t *task, apt_task_msg_t *msg) case MRCP_SERVER_ENGINE_TASK_MSG: { engine_task_msg_data_t *data = (engine_task_msg_data_t*)msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Engine Task Message [%d]", msg->sub_type); switch(msg->sub_type) { + case ENGINE_TASK_MSG_OPEN_ENGINE: + mrcp_engine_on_open(data->engine,data->status); + apt_task_start_request_remove(task); + break; + case ENGINE_TASK_MSG_CLOSE_ENGINE: + mrcp_engine_on_close(data->engine); + apt_task_terminate_request_remove(task); + break; case ENGINE_TASK_MSG_OPEN_CHANNEL: mrcp_server_on_engine_channel_open(data->channel,data->status); break; @@ -649,13 +736,12 @@ static apt_bool_t mrcp_server_msg_process(apt_task_t *task, apt_task_msg_t *msg) case MRCP_SERVER_MEDIA_TASK_MSG: { mpf_message_container_t *mpf_message_container = (mpf_message_container_t*) msg->data; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Receive Media Task Message"); mrcp_server_mpf_message_process(mpf_message_container); break; } default: { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Receive Unknown Task Message [%d]", msg->type); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Task Message Received [%d;%d]", msg->type,msg->sub_type); break; } } @@ -678,7 +764,6 @@ static apt_bool_t mrcp_server_signaling_task_msg_signal(mrcp_signaling_message_t signaling_message->message = message; *slot = signaling_message; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Signaling Task Message"); return apt_task_msg_parent_signal(session->signaling_agent->task,task_msg); } @@ -702,15 +787,34 @@ static apt_bool_t mrcp_server_connection_task_msg_signal( data->message = message; data->status = status; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Connection Task Message"); return apt_task_msg_signal(task,task_msg); } static apt_bool_t mrcp_server_engine_task_msg_signal( engine_task_msg_type_e type, - mrcp_engine_channel_t *engine_channel, - apt_bool_t status, - mrcp_message_t *message) + mrcp_engine_t *engine, + apt_bool_t status) +{ + mrcp_server_t *server = engine->event_obj; + apt_task_t *task = apt_consumer_task_base_get(server->task); + engine_task_msg_data_t *data; + apt_task_msg_t *task_msg = apt_task_msg_acquire(server->engine_msg_pool); + task_msg->type = MRCP_SERVER_ENGINE_TASK_MSG; + task_msg->sub_type = type; + data = (engine_task_msg_data_t*) task_msg->data; + data->engine = engine; + data->channel = NULL; + data->status = status; + data->mrcp_message = NULL; + + return apt_task_msg_signal(task,task_msg); +} + +static apt_bool_t mrcp_server_channel_task_msg_signal( + engine_task_msg_type_e type, + mrcp_engine_channel_t *engine_channel, + apt_bool_t status, + mrcp_message_t *message) { mrcp_channel_t *channel = engine_channel->event_obj; mrcp_session_t *session = mrcp_server_channel_session_get(channel); @@ -721,11 +825,11 @@ static apt_bool_t mrcp_server_engine_task_msg_signal( task_msg->type = MRCP_SERVER_ENGINE_TASK_MSG; task_msg->sub_type = type; data = (engine_task_msg_data_t*) task_msg->data; + data->engine = engine_channel->engine; data->channel = channel; data->status = status; data->mrcp_message = message; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Engine Task Message"); return apt_task_msg_signal(task,task_msg); } @@ -734,19 +838,14 @@ static mrcp_profile_t* mrcp_server_profile_get_by_agent(mrcp_server_t *server, m mrcp_profile_t *profile; apr_hash_index_t *it; void *val; - const void *key; - const char *name; it = apr_hash_first(session->base.pool,server->profile_table); for(; it; it = apr_hash_next(it)) { - apr_hash_this(it,&key,NULL,&val); + apr_hash_this(it,NULL,NULL,&val); profile = val; - name = key; - if(profile && name && profile->signaling_agent == signaling_agent) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Found Profile [%s]",name); + if(profile && profile->signaling_agent == signaling_agent) { return profile; } } - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Find Profile by Agent "APT_SID_FMT,MRCP_SESSION_SID(&session->base)); return NULL; } @@ -757,9 +856,16 @@ static mrcp_session_t* mrcp_server_sig_agent_session_create(mrcp_sig_agent_t *si session->server = server; session->profile = mrcp_server_profile_get_by_agent(server,session,signaling_agent); if(!session->profile) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Find Profile by Agent "APT_NAMESID_FMT, + session->base.name, + MRCP_SESSION_SID(&session->base)); mrcp_session_destroy(&session->base); return NULL; } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Session "APT_NAMESID_FMT" [%s]", + session->base.name, + MRCP_SESSION_SID(&session->base), + session->profile->id); session->base.signaling_agent = signaling_agent; session->base.request_vtable = &session_request_vtable; return &session->base; @@ -840,9 +946,25 @@ static apt_bool_t mrcp_server_disconnect_signal(mrcp_control_channel_t *channel) TRUE); } -static apt_bool_t mrcp_server_channel_open_signal(mrcp_engine_channel_t *channel, apt_bool_t status) +static apt_bool_t mrcp_server_engine_open_signal(mrcp_engine_t *engine, apt_bool_t status) +{ + return mrcp_server_engine_task_msg_signal( + ENGINE_TASK_MSG_OPEN_ENGINE, + engine, + status); +} + +static apt_bool_t mrcp_server_engine_close_signal(mrcp_engine_t *engine) { return mrcp_server_engine_task_msg_signal( + ENGINE_TASK_MSG_CLOSE_ENGINE, + engine, + TRUE); +} + +static apt_bool_t mrcp_server_channel_open_signal(mrcp_engine_channel_t *channel, apt_bool_t status) +{ + return mrcp_server_channel_task_msg_signal( ENGINE_TASK_MSG_OPEN_CHANNEL, channel, status, @@ -851,7 +973,7 @@ static apt_bool_t mrcp_server_channel_open_signal(mrcp_engine_channel_t *channel static apt_bool_t mrcp_server_channel_close_signal(mrcp_engine_channel_t *channel) { - return mrcp_server_engine_task_msg_signal( + return mrcp_server_channel_task_msg_signal( ENGINE_TASK_MSG_CLOSE_CHANNEL, channel, TRUE, @@ -860,7 +982,7 @@ static apt_bool_t mrcp_server_channel_close_signal(mrcp_engine_channel_t *channe static apt_bool_t mrcp_server_channel_message_signal(mrcp_engine_channel_t *channel, mrcp_message_t *message) { - return mrcp_server_engine_task_msg_signal( + return mrcp_server_channel_task_msg_signal( ENGINE_TASK_MSG_MESSAGE, channel, TRUE, diff --git a/libs/unimrcp/libs/mrcp-server/src/mrcp_server_session.c b/libs/unimrcp/libs/mrcp-server/src/mrcp_server_session.c index b254300921..9a18b9ae14 100644 --- a/libs/unimrcp/libs/mrcp-server/src/mrcp_server_session.c +++ b/libs/unimrcp/libs/mrcp-server/src/mrcp_server_session.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_server_session.c 1794 2011-01-20 18:59:01Z achaloyan $ */ #include "mrcp_server.h" @@ -30,6 +32,10 @@ #include "apt_consumer_task.h" #include "apt_log.h" +/** Macro to log session name and identifier */ +#define MRCP_SESSION_NAMESID(session) \ + session->base.name, MRCP_SESSION_SID(&session->base) + #define MRCP_SESSION_ID_HEX_STRING_LENGTH 16 struct mrcp_channel_t { @@ -106,6 +112,7 @@ mrcp_server_session_t* mrcp_server_session_create() session->mpf_task_msg = NULL; session->subrequest_count = 0; session->state = SESSION_STATE_NONE; + session->base.name = apr_psprintf(session->base.pool,"0x%pp",session); return session; } @@ -124,7 +131,9 @@ static mrcp_engine_channel_t* mrcp_server_engine_channel_create( resource_name->buf, resource_name->length); if(!engine) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find MRCP Engine [%s]",resource_name->buf); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find MRCP Engine "APT_NAMESID_FMT" [%s]", + MRCP_SESSION_NAMESID(session), + resource_name->buf); return NULL; } @@ -177,17 +186,22 @@ static mrcp_channel_t* mrcp_server_channel_create(mrcp_server_session_t *session channel->engine_channel = engine_channel; } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Engine Channel [%s]",resource_name->buf); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Engine Channel "APT_NAMESID_FMT" [%s]", + MRCP_SESSION_NAMESID(session), + resource_name->buf); session->answer->status = MRCP_SESSION_STATUS_UNACCEPTABLE_RESOURCE; } } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Resource [%s]",resource_name->buf); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Resource "APT_NAMESID_FMT" [%s]", + MRCP_SESSION_NAMESID(session), + resource_name->buf); session->answer->status = MRCP_SESSION_STATUS_NO_SUCH_RESOURCE; } } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Invalid Resource Identifier"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Invalid Resource Identifier "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); session->answer->status = MRCP_SESSION_STATUS_NO_SUCH_RESOURCE; } @@ -245,7 +259,8 @@ apt_bool_t mrcp_server_signaling_message_process(mrcp_signaling_message_t *signa { mrcp_server_session_t *session = signaling_message->session; if(session->active_request) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Push Request to Queue"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Push Request to Queue "APT_NAMESID_FMT, + MRCP_SESSION_NAMESID(session)); apt_list_push_back(session->request_queue,signaling_message,session->base.pool); } else { @@ -258,7 +273,9 @@ apt_bool_t mrcp_server_signaling_message_process(mrcp_signaling_message_t *signa apt_bool_t mrcp_server_on_channel_modify(mrcp_channel_t *channel, mrcp_control_descriptor_t *answer, apt_bool_t status) { mrcp_server_session_t *session = (mrcp_server_session_t*)channel->session; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Control Channel Modify"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Control Channel Modified "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf); if(!answer) { return FALSE; } @@ -275,7 +292,9 @@ apt_bool_t mrcp_server_on_channel_modify(mrcp_channel_t *channel, mrcp_control_d apt_bool_t mrcp_server_on_channel_remove(mrcp_channel_t *channel, apt_bool_t status) { mrcp_server_session_t *session = (mrcp_server_session_t*)channel->session; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Control Channel Remove"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Control Channel Removed "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf); if(!channel->waiting_for_channel) { return FALSE; } @@ -306,7 +325,10 @@ apt_bool_t mrcp_server_on_disconnect(mrcp_channel_t *channel) apt_bool_t mrcp_server_on_engine_channel_open(mrcp_channel_t *channel, apt_bool_t status) { mrcp_server_session_t *session = (mrcp_server_session_t*)channel->session; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Engine Channel Open [%s]", status == TRUE ? "OK" : "Failed"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Engine Channel Opened "APT_NAMESIDRES_FMT" [%s]", + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf, + status == TRUE ? "OK" : "Failed"); if(status == FALSE) { session->answer->status = MRCP_SESSION_STATUS_UNAVAILABLE_RESOURCE; } @@ -317,7 +339,9 @@ apt_bool_t mrcp_server_on_engine_channel_open(mrcp_channel_t *channel, apt_bool_ apt_bool_t mrcp_server_on_engine_channel_close(mrcp_channel_t *channel) { mrcp_server_session_t *session = (mrcp_server_session_t*)channel->session; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Engine Channel Close"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Engine Channel Closed "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf); mrcp_server_session_subrequest_remove(session); return TRUE; } @@ -366,10 +390,13 @@ static apt_bool_t mrcp_server_session_offer_process(mrcp_server_session_t *sessi } mrcp_server_session_add(session); - session->context = mpf_engine_context_create(session->profile->media_engine,session,5,session->base.pool); + session->context = mpf_engine_context_create( + session->profile->media_engine, + session->base.name, + session,5,session->base.pool); } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Offer "APT_SID_FMT" [c:%d a:%d v:%d]", - MRCP_SESSION_SID(&session->base), + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Offer "APT_NAMESID_FMT" [c:%d a:%d v:%d]", + MRCP_SESSION_NAMESID(session), descriptor->control_media_arr->nelts, descriptor->audio_media_arr->nelts, descriptor->video_media_arr->nelts); @@ -422,7 +449,7 @@ static apt_bool_t mrcp_server_session_terminate_process(mrcp_server_session_t *s mrcp_channel_t *channel; mrcp_termination_slot_t *slot; int i; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Terminate Request "APT_SID_FMT,MRCP_SESSION_SID(&session->base)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Terminate Session "APT_NAMESID_FMT,MRCP_SESSION_NAMESID(session)); mrcp_server_session_state_set(session,SESSION_STATE_TERMINATING); @@ -441,7 +468,10 @@ static apt_bool_t mrcp_server_session_terminate_process(mrcp_server_session_t *s if(!channel) continue; /* send remove channel request */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Remove Control Channel [%d]",i); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Remove Control Channel "APT_NAMESIDRES_FMT" [%d]", + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf, + i); if(channel->control_channel) { if(mrcp_server_control_channel_remove(channel->control_channel) == TRUE) { channel->waiting_for_channel = TRUE; @@ -453,7 +483,9 @@ static apt_bool_t mrcp_server_session_terminate_process(mrcp_server_session_t *s mpf_termination_t *termination = channel->engine_channel->termination; /* send subtract termination request */ if(termination) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract Channel Termination"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract Media Termination "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(termination)); if(mpf_engine_termination_message_add( session->profile->media_engine, MPF_SUBTRACT_TERMINATION,session->context,termination,NULL, @@ -475,7 +507,9 @@ static apt_bool_t mrcp_server_session_terminate_process(mrcp_server_session_t *s if(!slot || !slot->termination) continue; /* send subtract termination request */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract RTP Termination [%d]",i); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract Media Termination "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(slot->termination)); if(mpf_engine_termination_message_add( session->profile->media_engine, MPF_SUBTRACT_TERMINATION,session->context,slot->termination,NULL, @@ -502,7 +536,7 @@ static apt_bool_t mrcp_server_session_deactivate(mrcp_server_session_t *session) { mrcp_channel_t *channel; int i; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Deactivate Session "APT_SID_FMT,MRCP_SESSION_SID(&session->base)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Deactivate Session "APT_NAMESID_FMT,MRCP_SESSION_NAMESID(session)); mrcp_server_session_state_set(session,SESSION_STATE_DEACTIVATING); for(i=0; ichannels->nelts; i++) { channel = APR_ARRAY_IDX(session->channels,i,mrcp_channel_t*); @@ -525,12 +559,16 @@ static apt_bool_t mrcp_server_on_message_receive(mrcp_server_session_t *session, if(!channel) { channel = mrcp_server_channel_find(session,&message->channel_id.resource_name); if(!channel) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Channel"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Channel "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + message->channel_id.resource_name.buf); return FALSE; } } if(!channel->resource || !channel->state_machine) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Resource"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Missing Resource "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf); return FALSE; } @@ -626,7 +664,10 @@ static apt_bool_t mrcp_server_resource_offer_process(mrcp_server_session_t *sess return FALSE; } /* add to channel array */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Control Channel [%d]",count); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Control Channel "APT_NAMESIDRES_FMT" [%d]", + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf, + count); APR_ARRAY_PUSH(session->channels,mrcp_channel_t*) = channel; if(channel->engine_channel && channel->engine_channel->termination) { mpf_termination_t *termination = channel->engine_channel->termination; @@ -668,7 +709,10 @@ static apt_bool_t mrcp_server_control_media_offer_process(mrcp_server_session_t control_descriptor = mrcp_session_control_media_get(descriptor,i); if(!control_descriptor) continue; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify Control Channel [%d]",i); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify Control Channel "APT_NAMESIDRES_FMT" [%d]", + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf, + i); if(channel->control_channel) { /* send offer */ if(mrcp_server_control_channel_modify(channel->control_channel,control_descriptor) == TRUE) { @@ -696,7 +740,10 @@ static apt_bool_t mrcp_server_control_media_offer_process(mrcp_server_session_t if(!channel) continue; control_descriptor->session_id = session->base.id; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Control Channel [%d]",i); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Control Channel "APT_NAMESIDRES_FMT" [%d]", + MRCP_SESSION_NAMESID(session), + channel->resource->name.buf, + i); APR_ARRAY_PUSH(session->channels,mrcp_channel_t*) = channel; if(channel->control_channel) { @@ -746,6 +793,7 @@ static mpf_rtp_termination_descriptor_t* mrcp_server_associations_build(mrcp_ser mpf_rtp_termination_descriptor_init(rtp_descriptor); rtp_descriptor->audio.local = NULL; rtp_descriptor->audio.remote = media_descriptor; + rtp_descriptor->audio.settings = session->profile->rtp_settings; slot->mid = media_descriptor->mid; slot->channels = apr_array_make(session->base.pool,1,sizeof(mrcp_channel_t*)); @@ -753,7 +801,7 @@ static mpf_rtp_termination_descriptor_t* mrcp_server_associations_build(mrcp_ser channel = APR_ARRAY_IDX(session->channels,i,mrcp_channel_t*); if(!channel) continue; - if(!channel->cmid_arr || mrcp_cmid_find(channel->cmid_arr,slot->mid) == TRUE) { + if(session->terminations->nelts == 1 || (!channel->cmid_arr || mrcp_cmid_find(channel->cmid_arr,slot->mid) == TRUE)) { APR_ARRAY_PUSH(slot->channels, mrcp_channel_t*) = channel; audio_stream = NULL; @@ -840,7 +888,10 @@ static apt_bool_t mrcp_server_av_media_offer_process(mrcp_server_session_t *sess if(!rtp_descriptor) continue; /* send modify termination request */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify RTP Termination [%d]",i); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Modify Media Termination "APT_NAMESIDRES_FMT" [%d]", + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(slot->termination), + i); if(mpf_engine_termination_message_add( session->profile->media_engine, MPF_MODIFY_TERMINATION,session->context,slot->termination,rtp_descriptor, @@ -859,7 +910,10 @@ static apt_bool_t mrcp_server_av_media_offer_process(mrcp_server_session_t *sess /* create new RTP termination instance */ termination = mpf_termination_create(session->profile->rtp_termination_factory,session,session->base.pool); /* add to termination array */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add RTP Termination [%d]",i); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Add Media Termination "APT_NAMESIDRES_FMT" [%d]", + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(termination), + i); slot = apr_array_push(session->terminations); slot->id = i; slot->mid = 0; @@ -890,8 +944,8 @@ static apt_bool_t mrcp_server_session_answer_send(mrcp_server_session_t *session { apt_bool_t status; mrcp_session_descriptor_t *descriptor = session->answer; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Answer "APT_SID_FMT" [c:%d a:%d v:%d] Status %s", - MRCP_SESSION_SID(&session->base), + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Answer "APT_NAMESID_FMT" [c:%d a:%d v:%d] Status %s", + MRCP_SESSION_NAMESID(session), descriptor->control_media_arr->nelts, descriptor->audio_media_arr->nelts, descriptor->video_media_arr->nelts, @@ -924,7 +978,7 @@ static apt_bool_t mrcp_server_session_terminate_send(mrcp_server_session_t *sess channel->engine_channel = NULL; } } - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Terminate Response "APT_SID_FMT,MRCP_SESSION_SID(&session->base)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Session Terminated "APT_NAMESID_FMT,MRCP_SESSION_NAMESID(session)); mrcp_session_terminate_response(&session->base); return TRUE; } @@ -979,6 +1033,9 @@ static apt_bool_t mrcp_server_on_termination_modify(mrcp_server_session_t *sessi if(!session) { return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Media Termination Modified "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(mpf_message->termination)); termination_slot = mrcp_server_rtp_termination_find(session,mpf_message->termination); if(termination_slot) { /* rtp termination */ @@ -1012,6 +1069,9 @@ static apt_bool_t mrcp_server_on_termination_subtract(mrcp_server_session_t *ses if(!session) { return FALSE; } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Media Termination Subtracted "APT_NAMESIDRES_FMT, + MRCP_SESSION_NAMESID(session), + mpf_termination_name_get(mpf_message->termination)); termination_slot = mrcp_server_rtp_termination_find(session,mpf_message->termination); if(termination_slot) { /* rtp termination */ @@ -1049,15 +1109,12 @@ apt_bool_t mrcp_server_mpf_message_process(mpf_message_container_t *mpf_message_ if(mpf_message->message_type == MPF_MESSAGE_TYPE_RESPONSE) { switch(mpf_message->command_id) { case MPF_ADD_TERMINATION: - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Termination Add"); mrcp_server_on_termination_modify(session,mpf_message); break; case MPF_MODIFY_TERMINATION: - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Termination Modify"); mrcp_server_on_termination_modify(session,mpf_message); break; case MPF_SUBTRACT_TERMINATION: - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"On Termination Subtract"); mrcp_server_on_termination_subtract(session,mpf_message); break; case MPF_ADD_ASSOCIATION: diff --git a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session.h b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session.h index 173d1c39b2..b1f2ead512 100644 --- a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session.h +++ b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_session.h 1792 2011-01-10 21:08:52Z achaloyan $ */ -#ifndef __MRCP_SESSION_H__ -#define __MRCP_SESSION_H__ +#ifndef MRCP_SESSION_H +#define MRCP_SESSION_H /** * @file mrcp_session.h @@ -51,6 +53,10 @@ struct mrcp_session_t { apr_pool_t *pool; /** External object associated with session */ void *obj; + /** External logger object associated with session */ + void *log_obj; + /** Informative name of the session used for debugging */ + const char *name; /** Back pointer to signaling agent */ mrcp_sig_agent_t *signaling_agent; @@ -189,4 +195,4 @@ static APR_INLINE apt_bool_t mrcp_session_discover_response(mrcp_session_t *sess APT_END_EXTERN_C -#endif /*__MRCP_SESSION_H__*/ +#endif /* MRCP_SESSION_H */ diff --git a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session_descriptor.h b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session_descriptor.h index 7a94a42496..9cdbbc9dfe 100644 --- a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session_descriptor.h +++ b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_session_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_session_descriptor.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_SESSION_DESCRIPTOR_H__ -#define __MRCP_SESSION_DESCRIPTOR_H__ +#ifndef MRCP_SESSION_DESCRIPTOR_H +#define MRCP_SESSION_DESCRIPTOR_H /** * @file mrcp_session_descriptor.h @@ -143,4 +145,4 @@ MRCP_DECLARE(const char*) mrcp_session_status_phrase_get(mrcp_session_status_e s APT_END_EXTERN_C -#endif /*__MRCP_SESSION_DESCRIPTOR_H__*/ +#endif /* MRCP_SESSION_DESCRIPTOR_H */ diff --git a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_agent.h b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_agent.h index d17986c445..a0ef308470 100644 --- a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_agent.h +++ b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_agent.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,48 +12,78 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sig_agent.h 1750 2010-07-23 19:33:34Z achaloyan $ */ -#ifndef __MRCP_SIG_AGENT_H__ -#define __MRCP_SIG_AGENT_H__ +#ifndef MRCP_SIG_AGENT_H +#define MRCP_SIG_AGENT_H /** * @file mrcp_sig_agent.h * @brief Abstract MRCP Signaling Agent */ +#include +#include #include "mrcp_sig_types.h" #include "apt_task.h" APT_BEGIN_EXTERN_C +/** Signaling settings */ +struct mrcp_sig_settings_t { + /** Server IP address */ + char *server_ip; + /** Server port */ + apr_port_t server_port; + /** Server SIP user name (v2 only) */ + char *user_name; + /** Resource location (v1 only) */ + char *resource_location; + /** Map of the MRCP resource names (v1 only) */ + apr_table_t *resource_map; + /** Force destination ip address. Should be used only in case + SDP contains incorrect connection address (local IP address behind NAT) */ + apt_bool_t force_destination; + /** Optional feature tags */ + char *feature_tags; +}; + + /** MRCP signaling agent */ struct mrcp_sig_agent_t { + /** Agent identifier */ + const char *id; /** Memory pool to allocate memory from */ - apr_pool_t *pool; + apr_pool_t *pool; /** External object associated with agent */ - void *obj; + void *obj; /** Parent object (client/server) */ - void *parent; + void *parent; /** MRCP version */ - mrcp_version_e mrcp_version; + mrcp_version_e mrcp_version; /** MRCP resource factory */ mrcp_resource_factory_t *resource_factory; /** Task interface */ - apt_task_t *task; + apt_task_t *task; /** Task message pool used to allocate signaling agent messages */ - apt_task_msg_pool_t *msg_pool; + apt_task_msg_pool_t *msg_pool; /** Virtual create_server_session */ mrcp_session_t* (*create_server_session)(mrcp_sig_agent_t *signaling_agent); /** Virtual create_client_session */ - apt_bool_t (*create_client_session)(mrcp_session_t *session); + apt_bool_t (*create_client_session)(mrcp_session_t *session, mrcp_sig_settings_t *settings); }; /** Create signaling agent. */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_signaling_agent_create(void *obj, mrcp_version_e mrcp_version, apr_pool_t *pool); +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_signaling_agent_create(const char *id, void *obj, mrcp_version_e mrcp_version, apr_pool_t *pool); + +/** Allocate MRCP signaling settings. */ +MRCP_DECLARE(mrcp_sig_settings_t*) mrcp_signaling_settings_alloc(apr_pool_t *pool); + APT_END_EXTERN_C -#endif /*__MRCP_SIG_AGENT_H__*/ +#endif /* MRCP_SIG_AGENT_H */ diff --git a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_types.h b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_types.h index 41de32b861..c45b4be6e6 100644 --- a/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_types.h +++ b/libs/unimrcp/libs/mrcp-signaling/include/mrcp_sig_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sig_types.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_SIG_TYPES_H__ -#define __MRCP_SIG_TYPES_H__ +#ifndef MRCP_SIG_TYPES_H +#define MRCP_SIG_TYPES_H /** * @file mrcp_sig_types.h @@ -26,6 +28,9 @@ APT_BEGIN_EXTERN_C +/** Opaque MRCP signaling settings declaration */ +typedef struct mrcp_sig_settings_t mrcp_sig_settings_t; + /** Opaque MRCP signaling agent declaration */ typedef struct mrcp_sig_agent_t mrcp_sig_agent_t; @@ -37,4 +42,4 @@ typedef struct mrcp_session_descriptor_t mrcp_session_descriptor_t; APT_END_EXTERN_C -#endif /*__MRCP_SIG_TYPES_H__*/ +#endif /* MRCP_SIG_TYPES_H */ diff --git a/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2008.vcproj b/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2008.vcproj deleted file mode 100644 index 25e0f23d9c..0000000000 --- a/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2008.vcproj +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2010.vcxproj b/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2010.vcxproj deleted file mode 100644 index f11e3bd765..0000000000 --- a/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2010.vcxproj +++ /dev/null @@ -1,121 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mrcpsignaling - {12A49562-BAB9-43A3-A21D-15B60BBB4C31} - mrcpsignaling - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - ProgramDatabase - - - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2010.vcxproj.filters b/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2010.vcxproj.filters deleted file mode 100644 index 4e5d30c3da..0000000000 --- a/libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2010.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {f3dc550f-1a0f-4b9e-b077-3b6940dc5531} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - include - - - include - - - - - src - - - src - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcp-signaling/src/mrcp_session_descriptor.c b/libs/unimrcp/libs/mrcp-signaling/src/mrcp_session_descriptor.c index 5b0162725f..54d89ff258 100644 --- a/libs/unimrcp/libs/mrcp-signaling/src/mrcp_session_descriptor.c +++ b/libs/unimrcp/libs/mrcp-signaling/src/mrcp_session_descriptor.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_session_descriptor.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mrcp_session_descriptor.h" diff --git a/libs/unimrcp/libs/mrcp-signaling/src/mrcp_sig_agent.c b/libs/unimrcp/libs/mrcp-signaling/src/mrcp_sig_agent.c index 90773c345b..ba8570a606 100644 --- a/libs/unimrcp/libs/mrcp-signaling/src/mrcp_sig_agent.c +++ b/libs/unimrcp/libs/mrcp-signaling/src/mrcp_sig_agent.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,15 +12,18 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sig_agent.c 1792 2011-01-10 21:08:52Z achaloyan $ */ #include "mrcp_sig_agent.h" #include "mrcp_session.h" #include "apt_pool.h" -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_signaling_agent_create(void *obj, mrcp_version_e mrcp_version, apr_pool_t *pool) +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_signaling_agent_create(const char *id, void *obj, mrcp_version_e mrcp_version, apr_pool_t *pool) { mrcp_sig_agent_t *sig_agent = apr_palloc(pool,sizeof(mrcp_sig_agent_t)); + sig_agent->id = id; sig_agent->pool = pool; sig_agent->obj = obj; sig_agent->mrcp_version = mrcp_version; @@ -33,6 +36,21 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_signaling_agent_create(void *obj, mrcp_vers return sig_agent; } +/** Allocate MRCP signaling settings */ +MRCP_DECLARE(mrcp_sig_settings_t*) mrcp_signaling_settings_alloc(apr_pool_t *pool) +{ + mrcp_sig_settings_t *settings = apr_palloc(pool,sizeof(mrcp_sig_settings_t)); + settings->server_ip = NULL; + settings->server_port = 0; + settings->user_name = NULL; + settings->resource_location = NULL; + settings->resource_map = apr_table_make(pool,2); + settings->force_destination = FALSE; + settings->feature_tags = NULL; + return settings; +} + + MRCP_DECLARE(mrcp_session_t*) mrcp_session_create(apr_size_t padding) { mrcp_session_t *session; @@ -43,6 +61,8 @@ MRCP_DECLARE(mrcp_session_t*) mrcp_session_create(apr_size_t padding) session = apr_palloc(pool,sizeof(mrcp_session_t)+padding); session->pool = pool; session->obj = NULL; + session->log_obj = NULL; + session->name = NULL; session->signaling_agent = NULL; session->request_vtable = NULL; session->response_vtable = NULL; diff --git a/libs/unimrcp/libs/mrcp/Makefile.am b/libs/unimrcp/libs/mrcp/Makefile.am index 014261f81d..7528d04928 100644 --- a/libs/unimrcp/libs/mrcp/Makefile.am +++ b/libs/unimrcp/libs/mrcp/Makefile.am @@ -14,6 +14,7 @@ include_HEADERS = include/mrcp.h \ message/include/mrcp_start_line.h \ message/include/mrcp_header_accessor.h \ message/include/mrcp_generic_header.h \ + message/include/mrcp_header.h \ message/include/mrcp_message.h \ control/include/mrcp_resource.h \ control/include/mrcp_resource_factory.h \ @@ -24,11 +25,14 @@ include_HEADERS = include/mrcp.h \ resources/include/mrcp_recog_header.h \ resources/include/mrcp_recog_resource.h \ resources/include/mrcp_recorder_header.h \ - resources/include/mrcp_recorder_resource.h + resources/include/mrcp_recorder_resource.h \ + resources/include/mrcp_verifier_header.h \ + resources/include/mrcp_verifier_resource.h -libmrcp_la_SOURCES = message/src/mrcp_header_accessor.c \ +libmrcp_la_SOURCES = message/src/mrcp_start_line.c \ + message/src/mrcp_header_accessor.c \ message/src/mrcp_generic_header.c \ - message/src/mrcp_start_line.c \ + message/src/mrcp_header.c \ message/src/mrcp_message.c \ control/src/mrcp_resource_factory.c \ control/src/mrcp_resource_loader.c \ @@ -38,4 +42,6 @@ libmrcp_la_SOURCES = message/src/mrcp_header_accessor.c \ resources/src/mrcp_recog_header.c \ resources/src/mrcp_recog_resource.c \ resources/src/mrcp_recorder_header.c \ - resources/src/mrcp_recorder_resource.c + resources/src/mrcp_recorder_resource.c \ + resources/src/mrcp_verifier_header.c \ + resources/src/mrcp_verifier_resource.c diff --git a/libs/unimrcp/libs/mrcp/control/include/mrcp_resource.h b/libs/unimrcp/libs/mrcp/control/include/mrcp_resource.h index dd7a7f8abd..0f45fe54cc 100644 --- a/libs/unimrcp/libs/mrcp/control/include/mrcp_resource.h +++ b/libs/unimrcp/libs/mrcp/control/include/mrcp_resource.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_resource.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RESOURCE_H__ -#define __MRCP_RESOURCE_H__ +#ifndef MRCP_RESOURCE_H +#define MRCP_RESOURCE_H /** * @file mrcp_resource.h @@ -77,4 +79,4 @@ static APR_INLINE apt_bool_t mrcp_resource_validate(mrcp_resource_t *resource) APT_END_EXTERN_C -#endif /*__MRCP_RESOURCE_H__*/ +#endif /* MRCP_RESOURCE_H */ diff --git a/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_factory.h b/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_factory.h index f0349a7e2e..84631b13d7 100644 --- a/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_factory.h +++ b/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_factory.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_resource_factory.h 1632 2010-03-30 20:46:25Z achaloyan $ */ -#ifndef __MRCP_RESOURCE_FACTORY_H__ -#define __MRCP_RESOURCE_FACTORY_H__ +#ifndef MRCP_RESOURCE_FACTORY_H +#define MRCP_RESOURCE_FACTORY_H /** * @file mrcp_resource_factory.h @@ -37,12 +39,12 @@ MRCP_DECLARE(apt_bool_t) mrcp_resource_factory_destroy(mrcp_resource_factory_t * MRCP_DECLARE(apt_bool_t) mrcp_resource_register(mrcp_resource_factory_t *resource_factory, mrcp_resource_t *resource); /** Get MRCP resource by resource id */ -MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_get(mrcp_resource_factory_t *resource_factory, mrcp_resource_id resource_id); +MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_get(const mrcp_resource_factory_t *resource_factory, mrcp_resource_id resource_id); /** Find MRCP resource by resource name */ -MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_find(mrcp_resource_factory_t *resource_factory, const apt_str_t *name); +MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_find(const mrcp_resource_factory_t *resource_factory, const apt_str_t *name); APT_END_EXTERN_C -#endif /*__MRCP_RESOURCE_FACTORY_H__*/ +#endif /* MRCP_RESOURCE_FACTORY_H */ diff --git a/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_loader.h b/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_loader.h index e88cca4305..a6608aba3b 100644 --- a/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_loader.h +++ b/libs/unimrcp/libs/mrcp/control/include/mrcp_resource_loader.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_resource_loader.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __MRCP_RESOURCE_LOADER_H__ -#define __MRCP_RESOURCE_LOADER_H__ +#ifndef MRCP_RESOURCE_LOADER_H +#define MRCP_RESOURCE_LOADER_H /** * @file mrcp_resource_loader.h @@ -44,8 +46,8 @@ MRCP_DECLARE(apt_bool_t) mrcp_resource_load(mrcp_resource_loader_t *loader, cons MRCP_DECLARE(apt_bool_t) mrcp_resource_load_by_id(mrcp_resource_loader_t *loader, mrcp_resource_id id); /** Get MRCP resource factory */ -MRCP_DECLARE(mrcp_resource_factory_t*) mrcp_resource_factory_get(mrcp_resource_loader_t *loader); +MRCP_DECLARE(mrcp_resource_factory_t*) mrcp_resource_factory_get(const mrcp_resource_loader_t *loader); APT_END_EXTERN_C -#endif /*__MRCP_RESOURCE_LOADER_H__*/ +#endif /* MRCP_RESOURCE_LOADER_H */ diff --git a/libs/unimrcp/libs/mrcp/control/include/mrcp_stream.h b/libs/unimrcp/libs/mrcp/control/include/mrcp_stream.h index 3cc9d38511..ab5c4c6fa5 100644 --- a/libs/unimrcp/libs/mrcp/control/include/mrcp_stream.h +++ b/libs/unimrcp/libs/mrcp/control/include/mrcp_stream.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,68 +12,58 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_stream.h 1660 2010-04-19 18:29:06Z achaloyan $ */ -#ifndef __MRCP_STREAM_H__ -#define __MRCP_STREAM_H__ +#ifndef MRCP_STREAM_H +#define MRCP_STREAM_H /** * @file mrcp_stream.h * @brief MRCP Stream Parser and Generator */ -#include "apt_text_stream.h" +#include "apt_text_message.h" #include "mrcp_types.h" APT_BEGIN_EXTERN_C -/** Status of MRCP stream processing (parse/generate) */ -typedef enum { - MRCP_STREAM_STATUS_COMPLETE, - MRCP_STREAM_STATUS_INCOMPLETE, - MRCP_STREAM_STATUS_INVALID -} mrcp_stream_status_e; /** Opaque MRCP parser declaration */ typedef struct mrcp_parser_t mrcp_parser_t; /** Opaque MRCP generator declaration */ typedef struct mrcp_generator_t mrcp_generator_t; -/** MRCP message handler */ -typedef apt_bool_t (*mrcp_message_handler_f)(void *obj, mrcp_message_t *message, mrcp_stream_status_e status); - -/** Parse MRCP message (excluding message body) */ -MRCP_DECLARE(apt_bool_t) mrcp_message_parse(mrcp_resource_factory_t *resource_factory, mrcp_message_t *message, apt_text_stream_t *stream); - -/** Generate MRCP message (excluding message body) */ -MRCP_DECLARE(apt_bool_t) mrcp_message_generate(mrcp_resource_factory_t *resource_factory, mrcp_message_t *message, apt_text_stream_t *stream); - /** Create MRCP stream parser */ -MRCP_DECLARE(mrcp_parser_t*) mrcp_parser_create(mrcp_resource_factory_t *resource_factory, apr_pool_t *pool); +MRCP_DECLARE(mrcp_parser_t*) mrcp_parser_create(const mrcp_resource_factory_t *resource_factory, apr_pool_t *pool); -/** Set resource name to be used while parsing (MRCPv1 only) */ -MRCP_DECLARE(void) mrcp_parser_resource_name_set(mrcp_parser_t *parser, const apt_str_t *resource_name); +/** Set resource by name to be used for parsing of MRCPv1 messages */ +MRCP_DECLARE(void) mrcp_parser_resource_set(mrcp_parser_t *parser, const apt_str_t *resource_name); + +/** Set verbose mode for the parser */ +MRCP_DECLARE(void) mrcp_parser_verbose_set(mrcp_parser_t *parser, apt_bool_t verbose); /** Parse MRCP stream */ -MRCP_DECLARE(mrcp_stream_status_e) mrcp_parser_run(mrcp_parser_t *parser, apt_text_stream_t *stream); +MRCP_DECLARE(apt_message_status_e) mrcp_parser_run(mrcp_parser_t *parser, apt_text_stream_t *stream, mrcp_message_t **message); -/** Get parsed MRCP message */ -MRCP_DECLARE(mrcp_message_t*) mrcp_parser_message_get(const mrcp_parser_t *parser); /** Create MRCP stream generator */ -MRCP_DECLARE(mrcp_generator_t*) mrcp_generator_create(mrcp_resource_factory_t *resource_factory, apr_pool_t *pool); +MRCP_DECLARE(mrcp_generator_t*) mrcp_generator_create(const mrcp_resource_factory_t *resource_factory, apr_pool_t *pool); -/** Set MRCP message to generate */ -MRCP_DECLARE(apt_bool_t) mrcp_generator_message_set(mrcp_generator_t *generator, mrcp_message_t *message); +/** Set verbose mode for the generator */ +MRCP_DECLARE(void) mrcp_generator_verbose_set(mrcp_generator_t *generator, apt_bool_t verbose); /** Generate MRCP stream */ -MRCP_DECLARE(mrcp_stream_status_e) mrcp_generator_run(mrcp_generator_t *generator, apt_text_stream_t *stream); +MRCP_DECLARE(apt_message_status_e) mrcp_generator_run(mrcp_generator_t *generator, mrcp_message_t *message, apt_text_stream_t *stream); + + +/** Generate MRCP message (excluding message body) */ +MRCP_DECLARE(apt_bool_t) mrcp_message_generate(const mrcp_resource_factory_t *resource_factory, mrcp_message_t *message, apt_text_stream_t *stream); -/** Walk through MRCP stream and call message handler for each parsed message */ -MRCP_DECLARE(apt_bool_t) mrcp_stream_walk(mrcp_parser_t *parser, apt_text_stream_t *stream, mrcp_message_handler_f handler, void *obj); APT_END_EXTERN_C -#endif /*__MRCP_STREAM_H__*/ +#endif /* MRCP_STREAM_H */ diff --git a/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_factory.c b/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_factory.c index 894f89f158..21c6d341e6 100644 --- a/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_factory.c +++ b/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_factory.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_resource_factory.c 1632 2010-03-30 20:46:25Z achaloyan $ */ #include @@ -80,7 +82,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_resource_register(mrcp_resource_factory_t *resourc } /** Get MRCP resource by resource id */ -MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_get(mrcp_resource_factory_t *resource_factory, mrcp_resource_id resource_id) +MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_get(const mrcp_resource_factory_t *resource_factory, mrcp_resource_id resource_id) { if(resource_id >= resource_factory->resource_count) { return NULL; @@ -89,7 +91,7 @@ MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_get(mrcp_resource_factory_t *resour } /** Find MRCP resource by resource name */ -MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_find(mrcp_resource_factory_t *resource_factory, const apt_str_t *name) +MRCP_DECLARE(mrcp_resource_t*) mrcp_resource_find(const mrcp_resource_factory_t *resource_factory, const apt_str_t *name) { if(!name->buf || !name->length) { return NULL; diff --git a/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_loader.c b/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_loader.c index c670b8ba79..2160b2a614 100644 --- a/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_loader.c +++ b/libs/unimrcp/libs/mrcp/control/src/mrcp_resource_loader.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_resource_loader.c 1764 2010-08-23 18:02:18Z achaloyan $ */ #include "mrcp_resource_loader.h" @@ -20,6 +22,7 @@ #include "mrcp_synth_resource.h" #include "mrcp_recog_resource.h" #include "mrcp_recorder_resource.h" +#include "mrcp_verifier_resource.h" #include "apt_log.h" /** Resource loader */ @@ -28,11 +31,12 @@ struct mrcp_resource_loader_t { apr_pool_t *pool; }; -/** String table of MRCPv2 resources (mrcp_resource_types_e) */ +/** String table of MRCPv2 resources (mrcp_resource_type_e) */ static const apt_str_table_item_t mrcp_resource_string_table[] = { {{"speechsynth",11},6}, {{"speechrecog",11},6}, - {{"recorder", 8},0} + {{"recorder", 8},0}, + {{"speakverify",11},3} }; static mrcp_resource_t* mrcp_resource_create_by_id(mrcp_resource_id id, apr_pool_t *pool); @@ -106,7 +110,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_resource_load_by_id(mrcp_resource_loader_t *loader } /** Get MRCP resource factory */ -MRCP_DECLARE(mrcp_resource_factory_t*) mrcp_resource_factory_get(mrcp_resource_loader_t *loader) +MRCP_DECLARE(mrcp_resource_factory_t*) mrcp_resource_factory_get(const mrcp_resource_loader_t *loader) { return loader->factory; } @@ -124,6 +128,9 @@ static mrcp_resource_t* mrcp_resource_create_by_id(mrcp_resource_id id, apr_pool case MRCP_RECORDER_RESOURCE: resource = mrcp_recorder_resource_create(pool); break; + case MRCP_VERIFIER_RESOURCE: + resource = mrcp_verifier_resource_create(pool); + break; } if(resource) { diff --git a/libs/unimrcp/libs/mrcp/control/src/mrcp_stream.c b/libs/unimrcp/libs/mrcp/control/src/mrcp_stream.c index daef44c219..94f067240c 100644 --- a/libs/unimrcp/libs/mrcp/control/src/mrcp_stream.c +++ b/libs/unimrcp/libs/mrcp/control/src/mrcp_stream.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,399 +12,234 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_stream.c 1671 2010-04-28 19:50:29Z achaloyan $ */ #include "mrcp_stream.h" #include "mrcp_message.h" -#include "mrcp_generic_header.h" #include "mrcp_resource_factory.h" +#include "mrcp_resource.h" #include "apt_log.h" -/** Stage of MRCP stream processing (parse/generate) */ -typedef enum { - MRCP_STREAM_STAGE_NONE, - MRCP_STREAM_STAGE_START_LINE, - MRCP_STREAM_STAGE_RESOURCE, - MRCP_STREAM_STAGE_HEADER, - MRCP_STREAM_STAGE_BODY -} mrcp_stream_stage_e; /** MRCP parser */ struct mrcp_parser_t { - mrcp_resource_factory_t *resource_factory; - apt_str_t resource_name; - mrcp_stream_stage_e stage; - apt_bool_t skip_lf; - mrcp_message_t *message; - apr_pool_t *pool; + apt_message_parser_t *base; + const mrcp_resource_factory_t *resource_factory; + mrcp_resource_t *resource; }; /** MRCP generator */ struct mrcp_generator_t { - mrcp_resource_factory_t *resource_factory; - mrcp_stream_stage_e stage; - mrcp_message_t *message; - apr_pool_t *pool; + apt_message_generator_t *base; + const mrcp_resource_factory_t *resource_factory; }; +/** Create message and read start line */ +static apt_bool_t mrcp_parser_on_start(apt_message_parser_t *parser, apt_message_context_t *context, apt_text_stream_t *stream, apr_pool_t *pool); +/** Header section handler */ +static apt_bool_t mrcp_parser_on_header_complete(apt_message_parser_t *parser, apt_message_context_t *context); -/** Read MRCP message-body */ -static apt_bool_t mrcp_message_body_read(mrcp_message_t *message, apt_text_stream_t *stream) -{ - apt_bool_t status = TRUE; - if(message->body.buf) { - mrcp_generic_header_t *generic_header = mrcp_generic_header_get(message); - /* stream length available to read */ - apr_size_t stream_length = stream->text.length - (stream->pos - stream->text.buf); - /* required/remaining length to read */ - apr_size_t required_length = generic_header->content_length - message->body.length; - if(required_length > stream_length) { - required_length = stream_length; - /* not complete */ - status = FALSE; - } - memcpy(message->body.buf+message->body.length,stream->pos,required_length); - message->body.length += required_length; - stream->pos += required_length; - message->body.buf[message->body.length] = '\0'; - } - - return status; -} - -/** Write MRCP message-body */ -static apt_bool_t mrcp_message_body_write(mrcp_message_t *message, apt_text_stream_t *stream) -{ - apt_bool_t status = TRUE; - mrcp_generic_header_t *generic_header = mrcp_generic_header_get(message); - if(generic_header && message->body.length < generic_header->content_length) { - /* stream length available to write */ - apr_size_t stream_length = stream->text.length - (stream->pos - stream->text.buf); - /* required/remaining length to write */ - apr_size_t required_length = generic_header->content_length - message->body.length; - if(required_length > stream_length) { - required_length = stream_length; - /* not complete */ - status = FALSE; - } - - memcpy(stream->pos,message->body.buf+message->body.length,required_length); - message->body.length += required_length; - stream->pos += required_length; - } - - return status; -} - -/** Parse MRCP message (excluding message body) */ -MRCP_DECLARE(apt_bool_t) mrcp_message_parse(mrcp_resource_factory_t *resource_factory, mrcp_message_t *message, apt_text_stream_t *stream) -{ - mrcp_resource_t *resource; - - /* parse start-line */ - if(mrcp_start_line_parse(&message->start_line,stream,message->pool) == FALSE) { - return FALSE; - } - - if(message->start_line.version == MRCP_VERSION_2) { - mrcp_channel_id_parse(&message->channel_id,stream,message->pool); - } - - /* find resource */ - resource = mrcp_resource_find(resource_factory,&message->channel_id.resource_name); - if(!resource) { - return FALSE; - } - - if(mrcp_message_resource_set(message,resource) == FALSE) { - return FALSE; - } - - /* parse header */ - if(mrcp_message_header_parse(&message->header,stream,message->pool) == FALSE) { - return FALSE; - } - - return TRUE; -} - -/** Generate MRCP message (excluding message body) */ -MRCP_DECLARE(apt_bool_t) mrcp_message_generate(mrcp_resource_factory_t *resource_factory, mrcp_message_t *message, apt_text_stream_t *stream) -{ - /* validate message */ - if(mrcp_message_validate(message) == FALSE) { - return FALSE; - } - - /* generate start-line */ - if(mrcp_start_line_generate(&message->start_line,stream) == FALSE) { - return FALSE; - } - - if(message->start_line.version == MRCP_VERSION_2) { - mrcp_channel_id_generate(&message->channel_id,stream); - } +static const apt_message_parser_vtable_t parser_vtable = { + mrcp_parser_on_start, + mrcp_parser_on_header_complete, + NULL +}; - /* generate header */ - if(mrcp_message_header_generate(&message->header,stream) == FALSE) { - return FALSE; - } +/** Start message generation */ +apt_bool_t mrcp_generator_on_start(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream); +/** Finalize by setting overall message length in start line */ +apt_bool_t mrcp_generator_on_header_complete(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream); - /* finalize start-line generation */ - if(mrcp_start_line_finalize(&message->start_line,message->body.length,stream) == FALSE) { - return FALSE; - } - - return TRUE; -} +static const apt_message_generator_vtable_t generator_vtable = { + mrcp_generator_on_start, + mrcp_generator_on_header_complete, + NULL +}; /** Create MRCP stream parser */ -MRCP_DECLARE(mrcp_parser_t*) mrcp_parser_create(mrcp_resource_factory_t *resource_factory, apr_pool_t *pool) +MRCP_DECLARE(mrcp_parser_t*) mrcp_parser_create(const mrcp_resource_factory_t *resource_factory, apr_pool_t *pool) { mrcp_parser_t *parser = apr_palloc(pool,sizeof(mrcp_parser_t)); + parser->base = apt_message_parser_create(parser,&parser_vtable,pool); parser->resource_factory = resource_factory; - apt_string_reset(&parser->resource_name); - parser->stage = MRCP_STREAM_STAGE_NONE; - parser->skip_lf = FALSE; - parser->message = NULL; - parser->pool = pool; + parser->resource = NULL; return parser; } -/** Set resource name to be used while parsing (MRCPv1 only) */ -MRCP_DECLARE(void) mrcp_parser_resource_name_set(mrcp_parser_t *parser, const apt_str_t *resource_name) +/** Set resource by name to be used for parsing of MRCPv1 messages */ +MRCP_DECLARE(void) mrcp_parser_resource_set(mrcp_parser_t *parser, const apt_str_t *resource_name) { if(resource_name) { - apt_string_copy(&parser->resource_name,resource_name,parser->pool); + parser->resource = mrcp_resource_find(parser->resource_factory,resource_name); } } -static mrcp_stream_status_e mrcp_parser_break(mrcp_parser_t *parser, apt_text_stream_t *stream) +/** Set verbose mode for the parser */ +MRCP_DECLARE(void) mrcp_parser_verbose_set(mrcp_parser_t *parser, apt_bool_t verbose) { - /* failed to parse message */ - if(apt_text_is_eos(stream) == TRUE) { - /* end of stream reached */ - return MRCP_STREAM_STATUS_INCOMPLETE; - } - - /* error case */ - parser->stage = MRCP_STREAM_STAGE_NONE; - return MRCP_STREAM_STATUS_INVALID; + apt_message_parser_verbose_set(parser->base,verbose); } /** Parse MRCP stream */ -MRCP_DECLARE(mrcp_stream_status_e) mrcp_parser_run(mrcp_parser_t *parser, apt_text_stream_t *stream) +MRCP_DECLARE(apt_message_status_e) mrcp_parser_run(mrcp_parser_t *parser, apt_text_stream_t *stream, mrcp_message_t **message) +{ + return apt_message_parser_run(parser->base,stream,(void**)message); +} + +/** Create message and read start line */ +static apt_bool_t mrcp_parser_on_start(apt_message_parser_t *parser, apt_message_context_t *context, apt_text_stream_t *stream, apr_pool_t *pool) { - mrcp_message_t *message = parser->message; - if(parser->stage == MRCP_STREAM_STAGE_NONE || !message) { - /* create new MRCP message */ - message = mrcp_message_create(parser->pool); - message->channel_id.resource_name = parser->resource_name; - parser->message = message; - parser->stage = MRCP_STREAM_STAGE_START_LINE; + mrcp_message_t *mrcp_message; + apt_str_t start_line; + /* read start line */ + if(apt_text_line_read(stream,&start_line) == FALSE) { + return FALSE; + } + + /* create new MRCP message */ + mrcp_message = mrcp_message_create(pool); + /* parse start-line */ + if(mrcp_start_line_parse(&mrcp_message->start_line,&start_line,mrcp_message->pool) == FALSE) { + return FALSE; } - if(parser->stage == MRCP_STREAM_STAGE_START_LINE) { - /* parse start-line */ - if(mrcp_start_line_parse(&message->start_line,stream,message->pool) == FALSE) { - return mrcp_parser_break(parser,stream); + if(mrcp_message->start_line.version == MRCP_VERSION_1) { + mrcp_parser_t *mrcp_parser = apt_message_parser_object_get(parser); + if(!mrcp_parser->resource) { + return FALSE; + } + apt_string_copy( + &mrcp_message->channel_id.resource_name, + &mrcp_parser->resource->name, + pool); + + if(mrcp_message_resource_set(mrcp_message,mrcp_parser->resource) == FALSE) { + return FALSE; } - parser->stage = MRCP_STREAM_STAGE_RESOURCE; } - if(parser->stage == MRCP_STREAM_STAGE_RESOURCE) { + context->message = mrcp_message; + context->header = &mrcp_message->header.header_section; + context->body = &mrcp_message->body; + return TRUE; +} + +/** Header section handler */ +static apt_bool_t mrcp_parser_on_header_complete(apt_message_parser_t *parser, apt_message_context_t *context) +{ + mrcp_message_t *mrcp_message = context->message; + if(mrcp_message->start_line.version == MRCP_VERSION_2) { mrcp_resource_t *resource; - - if(message->start_line.version == MRCP_VERSION_2) { - mrcp_channel_id_parse(&message->channel_id,stream,message->pool); + mrcp_parser_t *mrcp_parser; + if(mrcp_channel_id_parse(&mrcp_message->channel_id,&mrcp_message->header,mrcp_message->pool) == FALSE) { + return FALSE; } - + mrcp_parser = apt_message_parser_object_get(parser); /* find resource */ - resource = mrcp_resource_find(parser->resource_factory,&message->channel_id.resource_name); + resource = mrcp_resource_find(mrcp_parser->resource_factory,&mrcp_message->channel_id.resource_name); if(!resource) { - return mrcp_parser_break(parser,stream); + return FALSE; } - if(mrcp_message_resource_set(message,resource) == FALSE) { - return mrcp_parser_break(parser,stream); + if(mrcp_message_resource_set(mrcp_message,resource) == FALSE) { + return FALSE; } - parser->stage = MRCP_STREAM_STAGE_HEADER; } - if(parser->stage == MRCP_STREAM_STAGE_HEADER) { - /* parse header */ - if(mrcp_message_header_parse(&message->header,stream,message->pool) == FALSE) { - return mrcp_parser_break(parser,stream); - } - - parser->stage = MRCP_STREAM_STAGE_NONE; - if(mrcp_generic_header_property_check(message,GENERIC_HEADER_CONTENT_LENGTH) == TRUE) { - mrcp_generic_header_t *generic_header = mrcp_generic_header_get(message); - if(generic_header && generic_header->content_length) { - apt_str_t *body = &message->body; - body->buf = apr_palloc(message->pool,generic_header->content_length+1); - body->length = 0; - parser->stage = MRCP_STREAM_STAGE_BODY; - } - } + if(mrcp_header_fields_parse(&mrcp_message->header,mrcp_message->pool) == FALSE) { + return FALSE; } - if(parser->stage == MRCP_STREAM_STAGE_BODY) { - if(mrcp_message_body_read(message,stream) == FALSE) { - return mrcp_parser_break(parser,stream); + if(context->body && mrcp_generic_header_property_check(mrcp_message,GENERIC_HEADER_CONTENT_LENGTH) == TRUE) { + mrcp_generic_header_t *generic_header = mrcp_generic_header_get(mrcp_message); + if(generic_header && generic_header->content_length) { + context->body->length = generic_header->content_length; } - parser->stage = MRCP_STREAM_STAGE_NONE; - } - - /* in the worst case message segmentation may occur between and - of the final empty header */ - if(!message->body.length && *(stream->pos-1)== APT_TOKEN_CR) { - /* if this is the case be prepared to skip */ - parser->skip_lf = TRUE; } - return MRCP_STREAM_STATUS_COMPLETE; -} - -/** Get parsed MRCP message */ -MRCP_DECLARE(mrcp_message_t*) mrcp_parser_message_get(const mrcp_parser_t *parser) -{ - return parser->message; + return TRUE; } /** Create MRCP stream generator */ -MRCP_DECLARE(mrcp_generator_t*) mrcp_generator_create(mrcp_resource_factory_t *resource_factory, apr_pool_t *pool) +MRCP_DECLARE(mrcp_generator_t*) mrcp_generator_create(const mrcp_resource_factory_t *resource_factory, apr_pool_t *pool) { mrcp_generator_t *generator = apr_palloc(pool,sizeof(mrcp_generator_t)); + generator->base = apt_message_generator_create(generator,&generator_vtable,pool); generator->resource_factory = resource_factory; - generator->stage = MRCP_STREAM_STAGE_NONE; - generator->message = NULL; - generator->pool = pool; return generator; } -/** Set MRCP message to generate */ -MRCP_DECLARE(apt_bool_t) mrcp_generator_message_set(mrcp_generator_t *generator, mrcp_message_t *message) +/** Set verbose mode for the generator */ +MRCP_DECLARE(void) mrcp_generator_verbose_set(mrcp_generator_t *generator, apt_bool_t verbose) { - if(!message) { - return FALSE; - } - generator->message = message; - return TRUE; + apt_message_generator_verbose_set(generator->base,verbose); } -static mrcp_stream_status_e mrcp_generator_break(mrcp_generator_t *generator, apt_text_stream_t *stream) +/** Generate MRCP stream */ +MRCP_DECLARE(apt_message_status_e) mrcp_generator_run(mrcp_generator_t *generator, mrcp_message_t *message, apt_text_stream_t *stream) { - /* failed to generate message */ - if(apt_text_is_eos(stream) == TRUE) { - /* end of stream reached */ - return MRCP_STREAM_STATUS_INCOMPLETE; - } - - /* error case */ - generator->stage = MRCP_STREAM_STAGE_NONE; - return MRCP_STREAM_STATUS_INVALID; + return apt_message_generator_run(generator->base,message,stream); } -/** Generate MRCP stream */ -MRCP_DECLARE(mrcp_stream_status_e) mrcp_generator_run(mrcp_generator_t *generator, apt_text_stream_t *stream) +/** Initialize by generating message start line and return header section and body */ +apt_bool_t mrcp_generator_on_start(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream) { - mrcp_message_t *message = generator->message; - if(!message) { - return MRCP_STREAM_STATUS_INVALID; - } - - if(generator->stage == MRCP_STREAM_STAGE_NONE) { - /* validate message */ - if(mrcp_message_validate(message) == FALSE) { - return MRCP_STREAM_STATUS_INVALID; - } - generator->stage = MRCP_STREAM_STAGE_START_LINE; + mrcp_message_t *mrcp_message = context->message; + /* validate message */ + if(mrcp_message_validate(mrcp_message) == FALSE) { + return FALSE; } - - if(generator->stage == MRCP_STREAM_STAGE_START_LINE) { - /* generate start-line */ - if(mrcp_start_line_generate(&message->start_line,stream) == FALSE) { - return mrcp_generator_break(generator,stream); - } - - if(message->start_line.version == MRCP_VERSION_2) { - mrcp_channel_id_generate(&message->channel_id,stream); - } - - /* generate header */ - if(mrcp_message_header_generate(&message->header,stream) == FALSE) { - return mrcp_generator_break(generator,stream); - } - - /* finalize start-line generation */ - if(mrcp_start_line_finalize(&message->start_line,message->body.length,stream) == FALSE) { - return mrcp_generator_break(generator,stream); - } - - generator->stage = MRCP_STREAM_STAGE_NONE; - if(mrcp_generic_header_property_check(message,GENERIC_HEADER_CONTENT_LENGTH) == TRUE) { - mrcp_generic_header_t *generic_header = mrcp_generic_header_get(message); - if(generic_header && generic_header->content_length) { - apt_str_t *body = &message->body; - body->length = 0; - generator->stage = MRCP_STREAM_STAGE_BODY; - } - } + /* generate start-line */ + if(mrcp_start_line_generate(&mrcp_message->start_line,stream) == FALSE) { + return FALSE; } - - if(generator->stage == MRCP_STREAM_STAGE_BODY) { - if(mrcp_message_body_write(message,stream) == FALSE) { - return mrcp_generator_break(generator,stream); - } - generator->stage = MRCP_STREAM_STAGE_NONE; + if(mrcp_message->start_line.version == MRCP_VERSION_2) { + mrcp_channel_id_generate(&mrcp_message->channel_id,stream); } - return MRCP_STREAM_STATUS_COMPLETE; + context->header = &mrcp_message->header.header_section; + context->body = &mrcp_message->body; + return TRUE; } +/** Finalize by setting overall message length in start line */ +apt_bool_t mrcp_generator_on_header_complete(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream) +{ + mrcp_message_t *mrcp_message = context->message; + /* finalize start-line generation */ + return mrcp_start_line_finalize(&mrcp_message->start_line,mrcp_message->body.length,stream); +} -/** Walk through MRCP stream and invoke message handler for each parsed message */ -MRCP_DECLARE(apt_bool_t) mrcp_stream_walk(mrcp_parser_t *parser, apt_text_stream_t *stream, mrcp_message_handler_f handler, void *obj) +/** Generate MRCP message (excluding message body) */ +MRCP_DECLARE(apt_bool_t) mrcp_message_generate(const mrcp_resource_factory_t *resource_factory, mrcp_message_t *message, apt_text_stream_t *stream) { - mrcp_stream_status_e status; - if(parser->skip_lf == TRUE) { - /* skip occurred as a result of message segmentation between and */ - apt_text_char_skip(stream,APT_TOKEN_LF); - parser->skip_lf = FALSE; + /* validate message */ + if(mrcp_message_validate(message) == FALSE) { + return FALSE; } - do { - status = mrcp_parser_run(parser,stream); - if(status == MRCP_STREAM_STATUS_COMPLETE) { - /* message is completely parsed */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Parsed MRCP Message [%lu]", stream->pos - stream->text.buf); - /* invoke message handler */ - handler(obj,parser->message,status); - } - else if(status == MRCP_STREAM_STATUS_INCOMPLETE) { - /* message is partially parsed, to be continued */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Truncated MRCP Message [%lu]", stream->pos - stream->text.buf); - /* prepare stream for further processing */ - if(apt_text_stream_scroll(stream) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Scroll MRCP Stream", stream->text.buf); - } - return TRUE; - } - else if(status == MRCP_STREAM_STATUS_INVALID){ - /* error case */ - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse MRCP Message"); - /* invoke message handler */ - handler(obj,parser->message,status); - /* reset stream pos */ - stream->pos = stream->text.buf; - return FALSE; - } + + /* generate start-line */ + if(mrcp_start_line_generate(&message->start_line,stream) == FALSE) { + return FALSE; + } + + if(message->start_line.version == MRCP_VERSION_2) { + mrcp_channel_id_generate(&message->channel_id,stream); + } + + /* generate header section */ + if(apt_header_section_generate(&message->header.header_section,stream) == FALSE) { + return FALSE; + } + + /* finalize start-line generation */ + if(mrcp_start_line_finalize(&message->start_line,message->body.length,stream) == FALSE) { + return FALSE; } - while(apt_text_is_eos(stream) == FALSE); - /* reset stream pos */ - apt_text_stream_reset(stream); return TRUE; } diff --git a/libs/unimrcp/libs/mrcp/include/mrcp.h b/libs/unimrcp/libs/mrcp/include/mrcp.h index 0140a1bfe8..9425954a78 100644 --- a/libs/unimrcp/libs/mrcp/include/mrcp.h +++ b/libs/unimrcp/libs/mrcp/include/mrcp.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_H__ -#define __MRCP_H__ +#ifndef MRCP_H +#define MRCP_H /** * @file mrcp.h @@ -40,4 +42,4 @@ #define MRCP_DECLARE(type) type #endif -#endif /*__MRCP_H__*/ +#endif /* MRCP_H */ diff --git a/libs/unimrcp/libs/mrcp/include/mrcp_types.h b/libs/unimrcp/libs/mrcp/include/mrcp_types.h index 3177077b39..7509f01888 100644 --- a/libs/unimrcp/libs/mrcp/include/mrcp_types.h +++ b/libs/unimrcp/libs/mrcp/include/mrcp_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_types.h 1753 2010-08-16 20:46:45Z achaloyan $ */ -#ifndef __MRCP_TYPES_H__ -#define __MRCP_TYPES_H__ +#ifndef MRCP_TYPES_H +#define MRCP_TYPES_H /** * @file mrcp_types.h @@ -39,6 +41,7 @@ typedef enum { MRCP_SYNTHESIZER_RESOURCE, /**< Synthesizer resource */ MRCP_RECOGNIZER_RESOURCE, /**< Recognizer resource */ MRCP_RECORDER_RESOURCE, /**< Recorder resource */ + MRCP_VERIFIER_RESOURCE, /**< Verifier resource */ MRCP_RESOURCE_TYPE_COUNT /**< Number of resources */ } mrcp_resource_type_e; @@ -77,4 +80,4 @@ typedef struct mrcp_resource_factory_t mrcp_resource_factory_t; APT_END_EXTERN_C -#endif /*__MRCP_TYPES_H__*/ +#endif /* MRCP_TYPES_H */ diff --git a/libs/unimrcp/libs/mrcp/message/include/mrcp_generic_header.h b/libs/unimrcp/libs/mrcp/message/include/mrcp_generic_header.h index fb8ebf852f..10b3d98917 100644 --- a/libs/unimrcp/libs/mrcp/message/include/mrcp_generic_header.h +++ b/libs/unimrcp/libs/mrcp/message/include/mrcp_generic_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_generic_header.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __MRCP_GENERIC_HEADER_H__ -#define __MRCP_GENERIC_HEADER_H__ +#ifndef MRCP_GENERIC_HEADER_H +#define MRCP_GENERIC_HEADER_H /** * @file mrcp_generic_header.h @@ -27,7 +29,7 @@ APT_BEGIN_EXTERN_C -/** Enumeration of MRCP generic headers */ +/** Enumeration of MRCP generic header fields */ typedef enum { GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST, GENERIC_HEADER_PROXY_SYNC_ID, @@ -42,7 +44,7 @@ typedef enum { GENERIC_HEADER_LOGGING_TAG, GENERIC_HEADER_VENDOR_SPECIFIC_PARAMS, - /** Additional headers for MRCP v2 */ + /** Additional header fields for MRCP v2 */ GENERIC_HEADER_ACCEPT, GENERIC_HEADER_FETCH_TIMEOUT, GENERIC_HEADER_SET_COOKIE, @@ -65,7 +67,7 @@ struct mrcp_request_id_list_t { /** Array of request identifiers */ mrcp_request_id ids[MAX_ACTIVE_REQUEST_ID_COUNT]; /** Number of request identifiers */ - size_t count; + apr_size_t count; }; @@ -97,7 +99,7 @@ struct mrcp_generic_header_t { /** Specifies the vendor specific parameters used by the media server */ apt_pair_arr_t *vendor_specific_params; - /** Additional headers for MRCP v2 */ + /** Additional header fields for MRCP v2 */ /** Specifies the acceptable media types set for entities returned in the response or events associated with this request */ apt_str_t accept; /** Defines the timeout for content that the server may need to fetch over the network */ @@ -115,9 +117,9 @@ MRCP_DECLARE(const mrcp_header_vtable_t*) mrcp_generic_header_vtable_get(mrcp_ve /** Append active request id list */ MRCP_DECLARE(apt_bool_t) active_request_id_list_append(mrcp_generic_header_t *generic_header, mrcp_request_id request_id); /** Find request id in active request id list */ -MRCP_DECLARE(apt_bool_t) active_request_id_list_find(mrcp_generic_header_t *generic_header, mrcp_request_id request_id); +MRCP_DECLARE(apt_bool_t) active_request_id_list_find(const mrcp_generic_header_t *generic_header, mrcp_request_id request_id); APT_END_EXTERN_C -#endif /*__MRCP_GENERIC_HEADER_H__*/ +#endif /* MRCP_GENERIC_HEADER_H */ diff --git a/libs/unimrcp/libs/mrcp/message/include/mrcp_header.h b/libs/unimrcp/libs/mrcp/message/include/mrcp_header.h new file mode 100644 index 0000000000..91655864c9 --- /dev/null +++ b/libs/unimrcp/libs/mrcp/message/include/mrcp_header.h @@ -0,0 +1,121 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: mrcp_header.h 1648 2010-04-12 20:03:59Z achaloyan $ + */ + +#ifndef MRCP_HEADER_H +#define MRCP_HEADER_H + +/** + * @file mrcp_header.h + * @brief MRCP Message Header Definition + */ + +#include "mrcp_header_accessor.h" + +APT_BEGIN_EXTERN_C + +/** + * Allows external applications to trigger whether + * transaprent header fields are supported or not + */ +#define TRANSPARENT_HEADER_FIELDS_SUPPORT + +/** MRCP message header declaration */ +typedef struct mrcp_message_header_t mrcp_message_header_t; +/** MRCP channel-id declaration */ +typedef struct mrcp_channel_id mrcp_channel_id; + + +/** MRCP message-header */ +struct mrcp_message_header_t { + /** MRCP generic-header */ + mrcp_header_accessor_t generic_header_accessor; + /** MRCP resource specific header */ + mrcp_header_accessor_t resource_header_accessor; + + /** Header section (collection of header fields)*/ + apt_header_section_t header_section; +}; + +/** MRCP channel-identifier */ +struct mrcp_channel_id { + /** Unambiguous string identifying the MRCP session */ + apt_str_t session_id; + /** MRCP resource name */ + apt_str_t resource_name; +}; + + +/** Initialize MRCP message-header */ +static APR_INLINE void mrcp_message_header_init(mrcp_message_header_t *header) +{ + mrcp_header_accessor_init(&header->generic_header_accessor); + mrcp_header_accessor_init(&header->resource_header_accessor); + apt_header_section_init(&header->header_section); +} + +/** Allocate MRCP message-header data */ +MRCP_DECLARE(apt_bool_t) mrcp_message_header_data_alloc( + mrcp_message_header_t *header, + const mrcp_header_vtable_t *generic_header_vtable, + const mrcp_header_vtable_t *resource_header_vtable, + apr_pool_t *pool); + +/** Create MRCP message-header */ +MRCP_DECLARE(mrcp_message_header_t*) mrcp_message_header_create( + const mrcp_header_vtable_t *generic_header_vtable, + const mrcp_header_vtable_t *resource_header_vtable, + apr_pool_t *pool); + +/** Destroy MRCP message-header */ +static APR_INLINE void mrcp_message_header_destroy(mrcp_message_header_t *header) +{ + mrcp_header_destroy(&header->generic_header_accessor); + mrcp_header_destroy(&header->resource_header_accessor); +} + +/** Add MRCP header field */ +MRCP_DECLARE(apt_bool_t) mrcp_header_field_add(mrcp_message_header_t *header, apt_header_field_t *header_field, apr_pool_t *pool); + + +/** Set (copy) MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_set(mrcp_message_header_t *header, const mrcp_message_header_t *src_header, apr_pool_t *pool); + +/** Get (copy) MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_get(mrcp_message_header_t *header, const mrcp_message_header_t *src_header, apr_pool_t *pool); + +/** Inherit (copy) MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_inherit(mrcp_message_header_t *header, const mrcp_message_header_t *src_header, apr_pool_t *pool); + +/** Parse MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_parse(mrcp_message_header_t *header, apr_pool_t *pool); + + +/** Initialize MRCP channel-identifier */ +MRCP_DECLARE(void) mrcp_channel_id_init(mrcp_channel_id *channel_id); + +/** Parse MRCP channel-identifier */ +MRCP_DECLARE(apt_bool_t) mrcp_channel_id_parse(mrcp_channel_id *channel_id, mrcp_message_header_t *header, apr_pool_t *pool); + +/** Generate MRCP channel-identifier */ +MRCP_DECLARE(apt_bool_t) mrcp_channel_id_generate(mrcp_channel_id *channel_id, apt_text_stream_t *text_stream); + + + +APT_END_EXTERN_C + +#endif /* MRCP_HEADER_H */ diff --git a/libs/unimrcp/libs/mrcp/message/include/mrcp_header_accessor.h b/libs/unimrcp/libs/mrcp/message/include/mrcp_header_accessor.h index dbd52d2d47..e2c7590f0d 100644 --- a/libs/unimrcp/libs/mrcp/message/include/mrcp_header_accessor.h +++ b/libs/unimrcp/libs/mrcp/message/include/mrcp_header_accessor.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,18 +12,20 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_header_accessor.h 1632 2010-03-30 20:46:25Z achaloyan $ */ -#ifndef __MRCP_HEADER_ACCESSOR_H__ -#define __MRCP_HEADER_ACCESSOR_H__ +#ifndef MRCP_HEADER_ACCESSOR_H +#define MRCP_HEADER_ACCESSOR_H /** * @file mrcp_header_accessor.h * @brief Abstract MRCP Header Accessor */ -#include "apt_string_table.h" #include "apt_text_stream.h" +#include "apt_header_field.h" #include "mrcp.h" APT_BEGIN_EXTERN_C @@ -40,12 +42,12 @@ struct mrcp_header_vtable_t { /** Destroy header data */ void (*destroy)(mrcp_header_accessor_t *accessor); - /** Parse header field */ + /** Parse header field value */ apt_bool_t (*parse_field)(mrcp_header_accessor_t *accessor, apr_size_t id, const apt_str_t *value, apr_pool_t *pool); - /** Generate header field */ - apt_bool_t (*generate_field)(mrcp_header_accessor_t *accessor, apr_size_t id, apt_text_stream_t *value); - /** Duplicate header field */ - apt_bool_t (*duplicate_field)(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, apr_pool_t *pool); + /** Generate header field value */ + apt_bool_t (*generate_field)(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_str_t *value, apr_pool_t *pool); + /** Duplicate header field value */ + apt_bool_t (*duplicate_field)(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, const apt_str_t *value, apr_pool_t *pool); /** Table of fields */ const apt_str_table_item_t *field_table; @@ -53,6 +55,15 @@ struct mrcp_header_vtable_t { apr_size_t field_count; }; +/** MRCP header accessor */ +struct mrcp_header_accessor_t { + /** Actual header data allocated by accessor */ + void *data; + /** Header accessor interface */ + const mrcp_header_vtable_t *vtable; +}; + + /** Initialize header vtable */ static APR_INLINE void mrcp_header_vtable_init(mrcp_header_vtable_t *vtable) @@ -76,30 +87,13 @@ static APR_INLINE apt_bool_t mrcp_header_vtable_validate(const mrcp_header_vtabl } -/** MRCP header accessor */ -struct mrcp_header_accessor_t { - /** Actual header data allocated by accessor */ - void *data; - - /** Array properties (mrcp_header_property_e) */ - char *properties; - /** Number of filled properties (header fields) */ - apr_size_t counter; - - /** Header accessor interface */ - const mrcp_header_vtable_t *vtable; -}; - /** Initialize header accessor */ static APR_INLINE void mrcp_header_accessor_init(mrcp_header_accessor_t *accessor) { accessor->data = NULL; - accessor->properties = NULL; - accessor->counter = 0; accessor->vtable = NULL; } - /** Allocate header data */ static APR_INLINE void* mrcp_header_allocate(mrcp_header_accessor_t *accessor, apr_pool_t *pool) { @@ -109,8 +103,6 @@ static APR_INLINE void* mrcp_header_allocate(mrcp_header_accessor_t *accessor, a if(!accessor->vtable || !accessor->vtable->allocate) { return NULL; } - accessor->properties = (char*)apr_pcalloc(pool,sizeof(char)*accessor->vtable->field_count); - accessor->counter = 0; return accessor->vtable->allocate(accessor,pool); } @@ -124,35 +116,16 @@ static APR_INLINE void mrcp_header_destroy(mrcp_header_accessor_t *accessor) } -/** Parse header */ -MRCP_DECLARE(apt_bool_t) mrcp_header_parse(mrcp_header_accessor_t *accessor, const apt_pair_t *pair, apr_pool_t *pool); - -/** Generate header */ -MRCP_DECLARE(apt_bool_t) mrcp_header_generate(mrcp_header_accessor_t *accessor, apt_text_stream_t *text_stream); - -/** Set header */ -MRCP_DECLARE(apt_bool_t) mrcp_header_set(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, const mrcp_header_accessor_t *mask, apr_pool_t *pool); - -/** Inherit header */ -MRCP_DECLARE(apt_bool_t) mrcp_header_inherit(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *parent, apr_pool_t *pool); - - -/** Add name:value property */ -MRCP_DECLARE(void) mrcp_header_property_add(mrcp_header_accessor_t *accessor, apr_size_t id); - -/** Remove property */ -MRCP_DECLARE(void) mrcp_header_property_remove(mrcp_header_accessor_t *accessor, apr_size_t id); - -/** Check the property */ -MRCP_DECLARE(apt_bool_t) mrcp_header_property_check(mrcp_header_accessor_t *accessor, apr_size_t id); +/** Parse header field value */ +MRCP_DECLARE(apt_bool_t) mrcp_header_field_value_parse(mrcp_header_accessor_t *accessor, apt_header_field_t *header_field, apr_pool_t *pool); -/** Add name only property */ -MRCP_DECLARE(void) mrcp_header_name_property_add(mrcp_header_accessor_t *accessor, apr_size_t id); +/** Generate header field value */ +MRCP_DECLARE(apt_header_field_t*) mrcp_header_field_value_generate(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_bool_t empty_value, apr_pool_t *pool); +/** Duplicate header field value */ +MRCP_DECLARE(apt_bool_t) mrcp_header_field_value_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src_accessor, apr_size_t id, const apt_str_t *value, apr_pool_t *pool); -/** Generate completion-cause */ -MRCP_DECLARE(apt_bool_t) mrcp_completion_cause_generate(const apt_str_table_item_t table[], apr_size_t size, apr_size_t cause, apt_text_stream_t *stream); APT_END_EXTERN_C -#endif /*__MRCP_HEADER_ACCESSOR_H__*/ +#endif /* MRCP_HEADER_ACCESSOR_H */ diff --git a/libs/unimrcp/libs/mrcp/message/include/mrcp_message.h b/libs/unimrcp/libs/mrcp/message/include/mrcp_message.h index 497a14d7c3..3bfe453882 100644 --- a/libs/unimrcp/libs/mrcp/message/include/mrcp_message.h +++ b/libs/unimrcp/libs/mrcp/message/include/mrcp_message.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_message.h 1721 2010-06-01 05:45:46Z achaloyan $ */ -#ifndef __MRCP_MESSAGE_H__ -#define __MRCP_MESSAGE_H__ +#ifndef MRCP_MESSAGE_H +#define MRCP_MESSAGE_H /** * @file mrcp_message.h @@ -24,176 +26,228 @@ #include "mrcp_types.h" #include "mrcp_start_line.h" -#include "mrcp_header_accessor.h" +#include "mrcp_header.h" +#include "mrcp_generic_header.h" APT_BEGIN_EXTERN_C -/** MRCP channel-id declaration */ -typedef struct mrcp_channel_id mrcp_channel_id; -/** MRCP message header declaration */ -typedef struct mrcp_message_header_t mrcp_message_header_t; - -/** MRCP channel-identifier */ -struct mrcp_channel_id { - /** Unambiguous string identifying the MRCP session */ - apt_str_t session_id; - /** MRCP resource name */ - apt_str_t resource_name; -}; - -/** Initialize MRCP channel-identifier */ -MRCP_DECLARE(void) mrcp_channel_id_init(mrcp_channel_id *channel_id); - -/** Parse MRCP channel-identifier */ -MRCP_DECLARE(apt_bool_t) mrcp_channel_id_parse(mrcp_channel_id *channel_id, apt_text_stream_t *text_stream, apr_pool_t *pool); - -/** Generate MRCP channel-identifier */ -MRCP_DECLARE(apt_bool_t) mrcp_channel_id_generate(mrcp_channel_id *channel_id, apt_text_stream_t *text_stream); - - -/** MRCP message-header */ -struct mrcp_message_header_t { - /** MRCP generic-header */ - mrcp_header_accessor_t generic_header_accessor; - /** MRCP resource specific header */ - mrcp_header_accessor_t resource_header_accessor; -}; - -/** Initialize MRCP message-header */ -static APR_INLINE void mrcp_message_header_init(mrcp_message_header_t *message_header) -{ - mrcp_header_accessor_init(&message_header->generic_header_accessor); - mrcp_header_accessor_init(&message_header->resource_header_accessor); -} - -/** Destroy MRCP message-header */ -static APR_INLINE void mrcp_message_header_destroy(mrcp_message_header_t *message_header) -{ - mrcp_header_destroy(&message_header->generic_header_accessor); - mrcp_header_destroy(&message_header->resource_header_accessor); -} - - -/** Parse MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_parse(mrcp_message_header_t *message_header, apt_text_stream_t *text_stream, apr_pool_t *pool); - -/** Generate MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_generate(mrcp_message_header_t *message_header, apt_text_stream_t *text_stream); - -/** Set MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_set(mrcp_message_header_t *message_header, const mrcp_message_header_t *src, apr_pool_t *pool); - -/** Get MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_get(mrcp_message_header_t *message_header, const mrcp_message_header_t *src, apr_pool_t *pool); - -/** Inherit MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_inherit(mrcp_message_header_t *message_header, const mrcp_message_header_t *parent, apr_pool_t *pool); - - +/** Macro to log channel identifier of the message */ +#define MRCP_MESSAGE_SIDRES(message) \ + (message)->channel_id.session_id.buf, (message)->channel_id.resource_name.buf /** MRCP message */ struct mrcp_message_t { /** Start-line of MRCP message */ - mrcp_start_line_t start_line; + mrcp_start_line_t start_line; /** Channel-identifier of MRCP message */ - mrcp_channel_id channel_id; + mrcp_channel_id channel_id; /** Header of MRCP message */ - mrcp_message_header_t header; + mrcp_message_header_t header; /** Body of MRCP message */ - apt_str_t body; + apt_str_t body; /** Associated MRCP resource */ - mrcp_resource_t *resource; - /** Memory pool MRCP message is allocated from */ - apr_pool_t *pool; + const mrcp_resource_t *resource; + /** Memory pool to allocate memory from */ + apr_pool_t *pool; }; -/** Create MRCP message */ +/** + * Create an MRCP message. + * @param pool the pool to allocate memory from + */ MRCP_DECLARE(mrcp_message_t*) mrcp_message_create(apr_pool_t *pool); -/** Create MRCP request message */ -MRCP_DECLARE(mrcp_message_t*) mrcp_request_create(mrcp_resource_t *resource, mrcp_version_e version, mrcp_method_id method_id, apr_pool_t *pool); -/** Create MRCP response message */ +/** + * Create an MRCP request message. + * @param resource the MRCP resource to use + * @param version the MRCP version to use + * @param method_id the MRCP resource specific method identifier + * @param pool the pool to allocate memory from + */ +MRCP_DECLARE(mrcp_message_t*) mrcp_request_create( + const mrcp_resource_t *resource, + mrcp_version_e version, + mrcp_method_id method_id, + apr_pool_t *pool); + +/** + * Create an MRCP response message based on given request message. + * @param request_message the MRCP request message to create a response for + * @param pool the pool to allocate memory from + */ MRCP_DECLARE(mrcp_message_t*) mrcp_response_create(const mrcp_message_t *request_message, apr_pool_t *pool); -/** Create MRCP event message */ -MRCP_DECLARE(mrcp_message_t*) mrcp_event_create(const mrcp_message_t *request_message, mrcp_method_id event_id, apr_pool_t *pool); -/** Associate MRCP resource specific data by resource name */ -MRCP_DECLARE(apt_bool_t) mrcp_message_resource_set(mrcp_message_t *message, mrcp_resource_t *resource); +/** + * Create an MRCP event message based on given requuest message. + * @param request_message the MRCP request message to create an event for + * @param event_id the MRCP resource specific event identifier + * @param pool the pool to allocate memory from + */ +MRCP_DECLARE(mrcp_message_t*) mrcp_event_create( + const mrcp_message_t *request_message, + mrcp_method_id event_id, + apr_pool_t *pool); -/** Validate MRCP message */ +/** + * Associate MRCP resource with message. + * @param message the message to associate resource with + * @param resource the resource to associate + */ +MRCP_DECLARE(apt_bool_t) mrcp_message_resource_set(mrcp_message_t *message, const mrcp_resource_t *resource); + +/** + * Validate MRCP message. + * @param message the message to validate + */ MRCP_DECLARE(apt_bool_t) mrcp_message_validate(mrcp_message_t *message); -/** Destroy MRCP message */ +/** + * Destroy MRCP message. + * @param message the message to destroy + */ MRCP_DECLARE(void) mrcp_message_destroy(mrcp_message_t *message); -/** Parse MRCP message-body */ -MRCP_DECLARE(apt_bool_t) mrcp_body_parse(mrcp_message_t *message, apt_text_stream_t *text_stream, apr_pool_t *pool); -/** Generate MRCP message-body */ -MRCP_DECLARE(apt_bool_t) mrcp_body_generate(mrcp_message_t *message, apt_text_stream_t *text_stream); - -/** Get MRCP generic-header */ -static APR_INLINE void* mrcp_generic_header_get(mrcp_message_t *mrcp_message) +/** + * Get MRCP generic header. + * @param message the message to get generic header from + */ +static APR_INLINE mrcp_generic_header_t* mrcp_generic_header_get(const mrcp_message_t *message) { - return mrcp_message->header.generic_header_accessor.data; + return (mrcp_generic_header_t*) message->header.generic_header_accessor.data; } -/** Prepare MRCP generic-header */ -static APR_INLINE void* mrcp_generic_header_prepare(mrcp_message_t *mrcp_message) +/** + * Allocate (if not allocated) and get MRCP generic header. + * @param message the message to prepare generic header for + */ +static APR_INLINE mrcp_generic_header_t* mrcp_generic_header_prepare(mrcp_message_t *message) { - return mrcp_header_allocate(&mrcp_message->header.generic_header_accessor,mrcp_message->pool); + return (mrcp_generic_header_t*) mrcp_header_allocate(&message->header.generic_header_accessor,message->pool); } -/** Add MRCP generic-header proprerty */ -static APR_INLINE void mrcp_generic_header_property_add(mrcp_message_t *mrcp_message, size_t id) -{ - mrcp_header_property_add(&mrcp_message->header.generic_header_accessor,id); -} +/** + * Add MRCP generic header field by specified property (numeric identifier). + * @param message the message to add property for + * @param id the numeric identifier to add + */ +MRCP_DECLARE(apt_bool_t) mrcp_generic_header_property_add(mrcp_message_t *message, apr_size_t id); -/** Add MRCP generic-header name only proprerty (should be used to construct empty headers in case of GET-PARAMS request) */ -static APR_INLINE void mrcp_generic_header_name_property_add(mrcp_message_t *mrcp_message, size_t id) +/** + * Add only the name of MRCP generic header field specified by property (numeric identifier). + * @param message the message to add property for + * @param id the numeric identifier to add + * @remark Should be used to construct empty header fiedls for GET-PARAMS requests + */ +MRCP_DECLARE(apt_bool_t) mrcp_generic_header_name_property_add(mrcp_message_t *message, apr_size_t id); + +/** + * Remove MRCP generic header field by specified property (numeric identifier). + * @param message the message to remove property from + * @param id the numeric identifier to remove + */ +static APR_INLINE apt_bool_t mrcp_generic_header_property_remove(mrcp_message_t *message, apr_size_t id) { - mrcp_header_name_property_add(&mrcp_message->header.generic_header_accessor,id); + apt_header_field_t *header_field = apt_header_section_field_get(&message->header.header_section,id); + if(header_field) { + return apt_header_section_field_remove(&message->header.header_section,header_field); + } + return FALSE; } -/** Check MRCP generic-header proprerty */ -static APR_INLINE apt_bool_t mrcp_generic_header_property_check(mrcp_message_t *mrcp_message, size_t id) +/** + * Check whether specified by property (numeric identifier) MRCP generic header field is set or not. + * @param message the message to use + * @param id the numeric identifier to check + */ +static APR_INLINE apt_bool_t mrcp_generic_header_property_check(const mrcp_message_t *message, apr_size_t id) { - return mrcp_header_property_check(&mrcp_message->header.generic_header_accessor,id); + return apt_header_section_field_check(&message->header.header_section,id); } -/** Get MRCP resource-header */ -static APR_INLINE void* mrcp_resource_header_get(const mrcp_message_t *mrcp_message) +/** + * Get MRCP resource header. + * @param message the message to get resource header from + */ +static APR_INLINE void* mrcp_resource_header_get(const mrcp_message_t *message) { - return mrcp_message->header.resource_header_accessor.data; + return message->header.resource_header_accessor.data; } -/** Prepare MRCP resource-header */ +/** + * Allocate (if not allocated) and get MRCP resource header. + * @param message the message to prepare resource header for + */ static APR_INLINE void* mrcp_resource_header_prepare(mrcp_message_t *mrcp_message) { return mrcp_header_allocate(&mrcp_message->header.resource_header_accessor,mrcp_message->pool); } -/** Add MRCP resource-header proprerty */ -static APR_INLINE void mrcp_resource_header_property_add(mrcp_message_t *mrcp_message, size_t id) +/** + * Add MRCP resource header field by specified property (numeric identifier). + * @param message the message to add property for + * @param id the numeric identifier to add + */ +MRCP_DECLARE(apt_bool_t) mrcp_resource_header_property_add(mrcp_message_t *message, apr_size_t id); + +/** + * Add only the name of MRCP resource header field specified by property (numeric identifier). + * @param message the message to add property for + * @param id the numeric identifier to add + * @remark Should be used to construct empty header fiedls for GET-PARAMS requests + */ +MRCP_DECLARE(apt_bool_t) mrcp_resource_header_name_property_add(mrcp_message_t *message, apr_size_t id); + +/** + * Remove MRCP resource header field by specified property (numeric identifier). + * @param message the message to remove property from + * @param id the numeric identifier to remove + */ +static APR_INLINE apt_bool_t mrcp_resource_header_property_remove(mrcp_message_t *message, apr_size_t id) { - mrcp_header_property_add(&mrcp_message->header.resource_header_accessor,id); + apt_header_field_t *header_field = apt_header_section_field_get(&message->header.header_section,id + GENERIC_HEADER_COUNT); + if(header_field) { + return apt_header_section_field_remove(&message->header.header_section,header_field); + } + return FALSE; } -/** Add MRCP resource-header name only proprerty (should be used to construct empty headers in case of GET-PARAMS request) */ -static APR_INLINE void mrcp_resource_header_name_property_add(mrcp_message_t *mrcp_message, size_t id) +/** + * Check whether specified by property (numeric identifier) MRCP resource header field is set or not. + * @param message the message to use + * @param id the numeric identifier to check + */ +static APR_INLINE apt_bool_t mrcp_resource_header_property_check(const mrcp_message_t *message, apr_size_t id) { - mrcp_header_name_property_add(&mrcp_message->header.resource_header_accessor,id); + return apt_header_section_field_check(&message->header.header_section,id + GENERIC_HEADER_COUNT); } -/** Check MRCP resource-header proprerty */ -static APR_INLINE apt_bool_t mrcp_resource_header_property_check(mrcp_message_t *mrcp_message, size_t id) +/** + * Add MRCP header field. + * @param message the message to add header field for + * @param header_field the header field to add + */ +static APR_INLINE apt_bool_t mrcp_message_header_field_add(mrcp_message_t *message, apt_header_field_t *header_field) { - return mrcp_header_property_check(&mrcp_message->header.resource_header_accessor,id); + return mrcp_header_field_add(&message->header,header_field,message->pool); } +/** + * Get the next MRCP header field. + * @param message the message to use + * @param header_field current header field + * @remark Should be used to iterate on header fields + * + * apt_header_field_t *header_field = NULL; + * while( (header_field = mrcp_message_next_header_field_get(message,header_field)) != NULL ) { + * } + */ +MRCP_DECLARE(apt_header_field_t*) mrcp_message_next_header_field_get( + const mrcp_message_t *message, + apt_header_field_t *header_field); + APT_END_EXTERN_C -#endif /*__MRCP_MESSAGE_H__*/ +#endif /* MRCP_MESSAGE_H */ diff --git a/libs/unimrcp/libs/mrcp/message/include/mrcp_start_line.h b/libs/unimrcp/libs/mrcp/message/include/mrcp_start_line.h index 1c6db22d40..0273229b75 100644 --- a/libs/unimrcp/libs/mrcp/message/include/mrcp_start_line.h +++ b/libs/unimrcp/libs/mrcp/message/include/mrcp_start_line.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_start_line.h 1632 2010-03-30 20:46:25Z achaloyan $ */ -#ifndef __MRCP_START_LINE_H__ -#define __MRCP_START_LINE_H__ +#ifndef MRCP_START_LINE_H +#define MRCP_START_LINE_H /** * @file mrcp_start_line.h @@ -59,6 +61,7 @@ typedef enum { MRCP_STATUS_CODE_METHOD_FAILED = 407, MRCP_STATUS_CODE_UNRECOGNIZED_MESSAGE = 408, MRCP_STATUS_CODE_UNSUPPORTED_PARAM_VALUE = 409, + MRCP_STATUS_CODE_OUT_OF_ORDER = 410, MRCP_STATUS_CODE_RESOURCE_SPECIFIC_FAILURE = 421 } mrcp_status_code_e; @@ -97,7 +100,7 @@ struct mrcp_start_line_t { /** Initialize MRCP start-line */ MRCP_DECLARE(void) mrcp_start_line_init(mrcp_start_line_t *start_line); /** Parse MRCP start-line */ -MRCP_DECLARE(apt_bool_t) mrcp_start_line_parse(mrcp_start_line_t *start_line, apt_text_stream_t *text_stream, apr_pool_t *pool); +MRCP_DECLARE(apt_bool_t) mrcp_start_line_parse(mrcp_start_line_t *start_line, apt_str_t *str, apr_pool_t *pool); /** Generate MRCP start-line */ MRCP_DECLARE(apt_bool_t) mrcp_start_line_generate(mrcp_start_line_t *start_line, apt_text_stream_t *text_stream); /** Finalize MRCP start-line generation */ @@ -111,4 +114,4 @@ MRCP_DECLARE(apt_bool_t) mrcp_request_id_generate(mrcp_request_id request_id, ap APT_END_EXTERN_C -#endif /*__MRCP_START_LINE_H__*/ +#endif /* MRCP_START_LINE_H */ diff --git a/libs/unimrcp/libs/mrcp/message/src/mrcp_generic_header.c b/libs/unimrcp/libs/mrcp/message/src/mrcp_generic_header.c index 1b1d1a7d7f..dc8878b446 100644 --- a/libs/unimrcp/libs/mrcp/message/src/mrcp_generic_header.c +++ b/libs/unimrcp/libs/mrcp/message/src/mrcp_generic_header.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_generic_header.c 1710 2010-05-24 17:36:19Z achaloyan $ */ #include "mrcp_generic_header.h" @@ -56,15 +58,20 @@ static apt_bool_t mrcp_request_id_list_parse(mrcp_request_id_list_t *request_id_ } /** Generate mrcp request-id list */ -static apt_bool_t mrcp_request_id_list_generate(mrcp_request_id_list_t *request_id_list, apt_text_stream_t *stream) +static apt_bool_t mrcp_request_id_list_generate(mrcp_request_id_list_t *request_id_list, apt_str_t *str, apr_pool_t *pool) { - size_t i; + apr_size_t i; + char buf[256]; + apt_text_stream_t stream; + apt_text_stream_init(&stream,buf,sizeof(buf)); for(i=0; icount; i++) { - mrcp_request_id_generate(request_id_list->ids[i],stream); + mrcp_request_id_generate(request_id_list->ids[i],&stream); if(i < request_id_list->count-1) { - *stream->pos++ = ','; + *stream.pos++ = ','; } } + + apt_string_assign_n(str,stream.text.buf, stream.pos - stream.text.buf, pool); return TRUE; } @@ -84,7 +91,7 @@ static void mrcp_generic_header_init(mrcp_generic_header_t *generic_header) apt_string_reset(&generic_header->cache_control); apt_string_reset(&generic_header->logging_tag); generic_header->vendor_specific_params = NULL; - /* initializes additionnal MRCP V2 generic headers */ + /* initializes additionnal MRCP v2 generic header fields */ apt_string_reset(&generic_header->accept); generic_header->fetch_timeout = 0; apt_string_reset(&generic_header->set_cookie); @@ -111,34 +118,34 @@ static apt_bool_t mrcp_generic_header_parse(mrcp_header_accessor_t *accessor, si mrcp_request_id_list_parse(&generic_header->active_request_id_list,value); break; case GENERIC_HEADER_PROXY_SYNC_ID: - apt_string_copy(&generic_header->proxy_sync_id,value,pool); + generic_header->proxy_sync_id = *value; break; case GENERIC_HEADER_ACCEPT_CHARSET: - apt_string_copy(&generic_header->accept_charset,value,pool); + generic_header->accept_charset = *value; break; case GENERIC_HEADER_CONTENT_TYPE: - apt_string_copy(&generic_header->content_type,value,pool); + generic_header->content_type = *value; break; case GENERIC_HEADER_CONTENT_ID: - apt_string_copy(&generic_header->content_id,value,pool); + generic_header->content_id = *value; break; case GENERIC_HEADER_CONTENT_BASE: - apt_string_copy(&generic_header->content_base,value,pool); + generic_header->content_base = *value; break; case GENERIC_HEADER_CONTENT_ENCODING: - apt_string_copy(&generic_header->content_encoding,value,pool); + generic_header->content_encoding = *value; break; case GENERIC_HEADER_CONTENT_LOCATION: - apt_string_copy(&generic_header->content_location,value,pool); + generic_header->content_location = *value; break; case GENERIC_HEADER_CONTENT_LENGTH: generic_header->content_length = apt_size_value_parse(value); break; case GENERIC_HEADER_CACHE_CONTROL: - apt_string_copy(&generic_header->cache_control,value,pool); + generic_header->cache_control = *value; break; case GENERIC_HEADER_LOGGING_TAG: - apt_string_copy(&generic_header->logging_tag,value,pool); + generic_header->logging_tag = *value; break; case GENERIC_HEADER_VENDOR_SPECIFIC_PARAMS: if(!generic_header->vendor_specific_params) { @@ -147,16 +154,16 @@ static apt_bool_t mrcp_generic_header_parse(mrcp_header_accessor_t *accessor, si apt_pair_array_parse(generic_header->vendor_specific_params,value,pool); break; case GENERIC_HEADER_ACCEPT: - apt_string_copy(&generic_header->accept,value,pool); + generic_header->accept = *value; break; case GENERIC_HEADER_FETCH_TIMEOUT: generic_header->fetch_timeout = apt_size_value_parse(value); break; case GENERIC_HEADER_SET_COOKIE: - apt_string_copy(&generic_header->set_cookie,value,pool); + generic_header->set_cookie = *value; break; case GENERIC_HEADER_SET_COOKIE2: - apt_string_copy(&generic_header->set_cookie2,value,pool); + generic_header->set_cookie2 = *value; break; default: status = FALSE; @@ -165,57 +172,57 @@ static apt_bool_t mrcp_generic_header_parse(mrcp_header_accessor_t *accessor, si } /** Generate generic-header */ -static apt_bool_t mrcp_generic_header_generate(mrcp_header_accessor_t *accessor, size_t id, apt_text_stream_t *value) +static apt_bool_t mrcp_generic_header_generate(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_str_t *value, apr_pool_t *pool) { mrcp_generic_header_t *generic_header = accessor->data; switch(id) { case GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST: - mrcp_request_id_list_generate(&generic_header->active_request_id_list,value); + mrcp_request_id_list_generate(&generic_header->active_request_id_list,value,pool); break; case GENERIC_HEADER_PROXY_SYNC_ID: - apt_string_value_generate(&generic_header->proxy_sync_id,value); + *value = generic_header->proxy_sync_id; break; case GENERIC_HEADER_ACCEPT_CHARSET: - apt_string_value_generate(&generic_header->accept_charset,value); + *value = generic_header->accept_charset; break; case GENERIC_HEADER_CONTENT_TYPE: - apt_string_value_generate(&generic_header->content_type,value); + *value = generic_header->content_type; break; case GENERIC_HEADER_CONTENT_ID: - apt_string_value_generate(&generic_header->content_id,value); + *value = generic_header->content_id; break; case GENERIC_HEADER_CONTENT_BASE: - apt_string_value_generate(&generic_header->content_base,value); + *value = generic_header->content_base; break; case GENERIC_HEADER_CONTENT_ENCODING: - apt_string_value_generate(&generic_header->content_encoding,value); + *value = generic_header->content_encoding; break; case GENERIC_HEADER_CONTENT_LOCATION: - apt_string_value_generate(&generic_header->content_location,value); + *value = generic_header->content_location; break; case GENERIC_HEADER_CONTENT_LENGTH: - apt_size_value_generate(generic_header->content_length,value); + apt_size_value_generate(generic_header->content_length,value,pool); break; case GENERIC_HEADER_CACHE_CONTROL: - apt_string_value_generate(&generic_header->cache_control,value); + *value = generic_header->cache_control; break; case GENERIC_HEADER_LOGGING_TAG: - apt_string_value_generate(&generic_header->logging_tag,value); + *value = generic_header->logging_tag; break; case GENERIC_HEADER_VENDOR_SPECIFIC_PARAMS: - apt_pair_array_generate(generic_header->vendor_specific_params,value); + apt_pair_array_generate(generic_header->vendor_specific_params,value,pool); break; case GENERIC_HEADER_ACCEPT: - apt_string_value_generate(&generic_header->accept,value); + *value = generic_header->accept; break; case GENERIC_HEADER_FETCH_TIMEOUT: - apt_size_value_generate(generic_header->fetch_timeout,value); + apt_size_value_generate(generic_header->fetch_timeout,value,pool); break; case GENERIC_HEADER_SET_COOKIE: - apt_string_value_generate(&generic_header->set_cookie,value); + *value = generic_header->set_cookie; break; case GENERIC_HEADER_SET_COOKIE2: - apt_string_value_generate(&generic_header->set_cookie2,value); + *value = generic_header->set_cookie2; break; default: break; @@ -224,7 +231,7 @@ static apt_bool_t mrcp_generic_header_generate(mrcp_header_accessor_t *accessor, } /** Duplicate generic-header */ -static apt_bool_t mrcp_generic_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, size_t id, apr_pool_t *pool) +static apt_bool_t mrcp_generic_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, const apt_str_t *value, apr_pool_t *pool) { mrcp_generic_header_t *generic_header = accessor->data; const mrcp_generic_header_t *src_generic_header = src->data; @@ -238,49 +245,49 @@ static apt_bool_t mrcp_generic_header_duplicate(mrcp_header_accessor_t *accessor case GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST: break; case GENERIC_HEADER_PROXY_SYNC_ID: - apt_string_copy(&generic_header->proxy_sync_id,&src_generic_header->proxy_sync_id,pool); + generic_header->proxy_sync_id = *value; break; case GENERIC_HEADER_ACCEPT_CHARSET: - apt_string_copy(&generic_header->accept_charset,&src_generic_header->accept_charset,pool); + generic_header->accept_charset = *value; break; case GENERIC_HEADER_CONTENT_TYPE: - apt_string_copy(&generic_header->content_type,&src_generic_header->content_type,pool); + generic_header->content_type = *value; break; case GENERIC_HEADER_CONTENT_ID: - apt_string_copy(&generic_header->content_id,&src_generic_header->content_id,pool); + generic_header->content_id = *value; break; case GENERIC_HEADER_CONTENT_BASE: - apt_string_copy(&generic_header->content_base,&src_generic_header->content_base,pool); + generic_header->content_base = *value; break; case GENERIC_HEADER_CONTENT_ENCODING: - apt_string_copy(&generic_header->content_encoding,&src_generic_header->content_encoding,pool); + generic_header->content_encoding = *value; break; case GENERIC_HEADER_CONTENT_LOCATION: - apt_string_copy(&generic_header->content_location,&src_generic_header->content_location,pool); + generic_header->content_location = *value; break; case GENERIC_HEADER_CONTENT_LENGTH: generic_header->content_length = src_generic_header->content_length; break; case GENERIC_HEADER_CACHE_CONTROL: - apt_string_copy(&generic_header->cache_control,&src_generic_header->cache_control,pool); + generic_header->cache_control = *value; break; case GENERIC_HEADER_LOGGING_TAG: - apt_string_copy(&generic_header->logging_tag,&src_generic_header->logging_tag,pool); + generic_header->logging_tag = *value; break; case GENERIC_HEADER_VENDOR_SPECIFIC_PARAMS: generic_header->vendor_specific_params = apt_pair_array_copy(src_generic_header->vendor_specific_params,pool); break; case GENERIC_HEADER_ACCEPT: - apt_string_copy(&generic_header->accept,&src_generic_header->accept,pool); + generic_header->accept = *value; break; case GENERIC_HEADER_FETCH_TIMEOUT: generic_header->fetch_timeout = src_generic_header->fetch_timeout; break; case GENERIC_HEADER_SET_COOKIE: - apt_string_copy(&generic_header->set_cookie,&src_generic_header->set_cookie,pool); + generic_header->set_cookie = *value; break; case GENERIC_HEADER_SET_COOKIE2: - apt_string_copy(&generic_header->set_cookie2,&src_generic_header->set_cookie2,pool); + generic_header->set_cookie2 = *value; break; default: status = FALSE; @@ -317,10 +324,10 @@ MRCP_DECLARE(apt_bool_t) active_request_id_list_append(mrcp_generic_header_t *ge } /** Find request id in active request id list */ -MRCP_DECLARE(apt_bool_t) active_request_id_list_find(mrcp_generic_header_t *generic_header, mrcp_request_id request_id) +MRCP_DECLARE(apt_bool_t) active_request_id_list_find(const mrcp_generic_header_t *generic_header, mrcp_request_id request_id) { size_t i; - mrcp_request_id_list_t *request_id_list = &generic_header->active_request_id_list; + const mrcp_request_id_list_t *request_id_list = &generic_header->active_request_id_list; for(i=0; icount; i++) { if(request_id_list->ids[i] == request_id) { return TRUE; diff --git a/libs/unimrcp/libs/mrcp/message/src/mrcp_header.c b/libs/unimrcp/libs/mrcp/message/src/mrcp_header.c new file mode 100644 index 0000000000..864baedc42 --- /dev/null +++ b/libs/unimrcp/libs/mrcp/message/src/mrcp_header.c @@ -0,0 +1,267 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: mrcp_header.c 1737 2010-06-15 18:29:17Z achaloyan $ + */ + +#include "mrcp_header.h" +#include "mrcp_generic_header.h" +#include "apt_text_message.h" +#include "apt_log.h" + +#define MRCP_CHANNEL_ID "Channel-Identifier" +#define MRCP_CHANNEL_ID_LENGTH (sizeof(MRCP_CHANNEL_ID)-1) + + +/** Allocate MRCP message-header data */ +MRCP_DECLARE(apt_bool_t) mrcp_message_header_data_alloc( + mrcp_message_header_t *header, + const mrcp_header_vtable_t *generic_header_vtable, + const mrcp_header_vtable_t *resource_header_vtable, + apr_pool_t *pool) +{ + if(!generic_header_vtable || !resource_header_vtable) { + return FALSE; + } + + header->generic_header_accessor.data = NULL; + header->generic_header_accessor.vtable = generic_header_vtable; + + header->resource_header_accessor.data = NULL; + header->resource_header_accessor.vtable = resource_header_vtable; + + apt_header_section_array_alloc( + &header->header_section, + header->generic_header_accessor.vtable->field_count + + header->resource_header_accessor.vtable->field_count, + pool); + + mrcp_header_allocate(&header->generic_header_accessor,pool); + mrcp_header_allocate(&header->resource_header_accessor,pool); + return TRUE; +} + +MRCP_DECLARE(mrcp_message_header_t*) mrcp_message_header_create( + const mrcp_header_vtable_t *generic_header_vtable, + const mrcp_header_vtable_t *resource_header_vtable, + apr_pool_t *pool) +{ + mrcp_message_header_t *header = apr_palloc(pool,sizeof(mrcp_message_header_t)); + apt_header_section_init(&header->header_section); + mrcp_message_header_data_alloc(header,generic_header_vtable,resource_header_vtable,pool); + return header; +} + +/** Add MRCP header field */ +MRCP_DECLARE(apt_bool_t) mrcp_header_field_add(mrcp_message_header_t *header, apt_header_field_t *header_field, apr_pool_t *pool) +{ + apt_bool_t status = FALSE; + if(apt_string_is_empty(&header_field->name) == FALSE) { + /* normal header */ + if(mrcp_header_field_value_parse(&header->resource_header_accessor,header_field,pool) == TRUE) { + header_field->id += GENERIC_HEADER_COUNT; + } + else if(mrcp_header_field_value_parse(&header->generic_header_accessor,header_field,pool) == TRUE) { + status = apt_header_section_field_add(&header->header_section,header_field); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Unknown MRCP header field: %s",header_field->name.buf); + } + status = apt_header_section_field_add(&header->header_section,header_field); + } + return status; +} + +/** Parse MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_parse(mrcp_message_header_t *header, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + for(header_field = APR_RING_FIRST(&header->header_section.ring); + header_field != APR_RING_SENTINEL(&header->header_section.ring, apt_header_field_t, link); + header_field = APR_RING_NEXT(header_field, link)) { + + if(mrcp_header_field_value_parse(&header->resource_header_accessor,header_field,pool) == TRUE) { + header_field->id += GENERIC_HEADER_COUNT; + apt_header_section_field_set(&header->header_section,header_field); + } + else if(mrcp_header_field_value_parse(&header->generic_header_accessor,header_field,pool) == TRUE) { + apt_header_section_field_set(&header->header_section,header_field); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown MRCP header field: %s",header_field->name.buf); + } + } + + return TRUE; +} + +/** Set (copy) MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_set(mrcp_message_header_t *header, const mrcp_message_header_t *src_header, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + const apt_header_field_t *src_header_field; + for(src_header_field = APR_RING_FIRST(&src_header->header_section.ring); + src_header_field != APR_RING_SENTINEL(&src_header->header_section.ring, apt_header_field_t, link); + src_header_field = APR_RING_NEXT(src_header_field, link)) { + + header_field = apt_header_field_copy(src_header_field,pool); + if(header_field->id < GENERIC_HEADER_COUNT) { + if(mrcp_header_field_value_duplicate( + &header->generic_header_accessor, + &src_header->generic_header_accessor, + header_field->id, + &header_field->value, + pool) == TRUE) { + apt_header_section_field_add(&header->header_section,header_field); + } + } + else { + if(mrcp_header_field_value_duplicate( + &header->resource_header_accessor, + &src_header->resource_header_accessor, + header_field->id - GENERIC_HEADER_COUNT, + &header_field->value, + pool) == TRUE) { + apt_header_section_field_add(&header->header_section,header_field); + } + } + } + + return TRUE; +} + +/** Get (copy) MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_get(mrcp_message_header_t *header, const mrcp_message_header_t *src_header, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + const apt_header_field_t *src_header_field; + for(header_field = APR_RING_FIRST(&header->header_section.ring); + header_field != APR_RING_SENTINEL(&header->header_section.ring, apt_header_field_t, link); + header_field = APR_RING_NEXT(header_field, link)) { + + src_header_field = apt_header_section_field_get(&src_header->header_section,header_field->id); + if(src_header_field) { + if(header_field->id < GENERIC_HEADER_COUNT) { + apt_string_copy(&header_field->value,&src_header_field->value,pool); + mrcp_header_field_value_duplicate( + &header->generic_header_accessor, + &src_header->generic_header_accessor, + header_field->id, + &header_field->value, + pool); + } + else { + apt_string_copy(&header_field->value,&src_header_field->value,pool); + mrcp_header_field_value_duplicate( + &header->resource_header_accessor, + &src_header->resource_header_accessor, + header_field->id - GENERIC_HEADER_COUNT, + &header_field->value, + pool); + } + } + } + + return TRUE; +} + +/** Inherit (copy) MRCP header fields */ +MRCP_DECLARE(apt_bool_t) mrcp_header_fields_inherit(mrcp_message_header_t *header, const mrcp_message_header_t *src_header, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + const apt_header_field_t *src_header_field; + for(src_header_field = APR_RING_FIRST(&src_header->header_section.ring); + src_header_field != APR_RING_SENTINEL(&src_header->header_section.ring, apt_header_field_t, link); + src_header_field = APR_RING_NEXT(src_header_field, link)) { + + header_field = apt_header_section_field_get(&header->header_section,src_header_field->id); + if(!header_field) { + header_field = apt_header_field_copy(src_header_field,pool); + if(header_field->id < GENERIC_HEADER_COUNT) { + if(mrcp_header_field_value_duplicate( + &header->generic_header_accessor, + &src_header->generic_header_accessor, + header_field->id, + &header_field->value, + pool) == TRUE) { + apt_header_section_field_add(&header->header_section,header_field); + } + } + else { + if(mrcp_header_field_value_duplicate( + &header->resource_header_accessor, + &src_header->resource_header_accessor, + header_field->id - GENERIC_HEADER_COUNT, + &header_field->value, + pool) == TRUE) { + apt_header_section_field_add(&header->header_section,header_field); + } + } + } + } + return TRUE; +} + + +/** Initialize MRCP channel-identifier */ +MRCP_DECLARE(void) mrcp_channel_id_init(mrcp_channel_id *channel_id) +{ + apt_string_reset(&channel_id->session_id); + apt_string_reset(&channel_id->resource_name); +} + +/** Parse MRCP channel-identifier */ +MRCP_DECLARE(apt_bool_t) mrcp_channel_id_parse(mrcp_channel_id *channel_id, mrcp_message_header_t *header, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + for(header_field = APR_RING_FIRST(&header->header_section.ring); + header_field != APR_RING_SENTINEL(&header->header_section.ring, apt_header_field_t, link); + header_field = APR_RING_NEXT(header_field, link)) { + + if(header_field->value.length && strncasecmp(header_field->name.buf,MRCP_CHANNEL_ID,MRCP_CHANNEL_ID_LENGTH) == 0) { + apt_id_resource_parse(&header_field->value,'@',&channel_id->session_id,&channel_id->resource_name,pool); + apt_header_section_field_remove(&header->header_section,header_field); + return TRUE; + } + } + return FALSE; +} + +/** Generate MRCP channel-identifier */ +MRCP_DECLARE(apt_bool_t) mrcp_channel_id_generate(mrcp_channel_id *channel_id, apt_text_stream_t *stream) +{ + apt_str_t *str; + char *pos = stream->pos; + if(pos + MRCP_CHANNEL_ID_LENGTH + 2 + channel_id->session_id.length + 1 + + channel_id->resource_name.length >= stream->end) { + return FALSE; + } + memcpy(pos,MRCP_CHANNEL_ID,MRCP_CHANNEL_ID_LENGTH); + pos += MRCP_CHANNEL_ID_LENGTH; + *pos++ = ':'; + *pos++ = APT_TOKEN_SP; + + str = &channel_id->session_id; + memcpy(pos,str->buf,str->length); + pos += str->length; + *pos++ = '@'; + + str = &channel_id->resource_name; + memcpy(pos,str->buf,str->length); + pos += str->length; + + stream->pos = pos; + return apt_text_eol_insert(stream); +} diff --git a/libs/unimrcp/libs/mrcp/message/src/mrcp_header_accessor.c b/libs/unimrcp/libs/mrcp/message/src/mrcp_header_accessor.c index ae80b1aa50..c7148129cd 100644 --- a/libs/unimrcp/libs/mrcp/message/src/mrcp_header_accessor.c +++ b/libs/unimrcp/libs/mrcp/message/src/mrcp_header_accessor.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,202 +12,73 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_header_accessor.c 1737 2010-06-15 18:29:17Z achaloyan $ */ -#include #include "mrcp_header_accessor.h" -typedef enum { - MRCP_HEADER_FIELD_NONE = 0x0, - MRCP_HEADER_FIELD_NAME = 0x1, - MRCP_HEADER_FIELD_VALUE = 0x2, - MRCP_HEADER_FIELD_NAME_VALUE = MRCP_HEADER_FIELD_NAME | MRCP_HEADER_FIELD_VALUE -} mrcp_header_property_e; - -MRCP_DECLARE(apt_bool_t) mrcp_header_parse(mrcp_header_accessor_t *accessor, const apt_pair_t *pair, apr_pool_t *pool) +/** Parse header field value */ +MRCP_DECLARE(apt_bool_t) mrcp_header_field_value_parse(mrcp_header_accessor_t *accessor, apt_header_field_t *header_field, apr_pool_t *pool) { - size_t id; + apr_size_t id; if(!accessor->vtable) { return FALSE; } - id = apt_string_table_id_find(accessor->vtable->field_table,accessor->vtable->field_count,&pair->name); + id = apt_string_table_id_find(accessor->vtable->field_table,accessor->vtable->field_count,&header_field->name); if(id >= accessor->vtable->field_count) { return FALSE; } + header_field->id = id; - if(!pair->value.length) { - mrcp_header_name_property_add(accessor,id); - return TRUE; - } - - if(accessor->vtable->parse_field(accessor,id,&pair->value,pool) == FALSE) { - return FALSE; + if(header_field->value.length) { + if(accessor->vtable->parse_field(accessor,header_field->id,&header_field->value,pool) == FALSE) { + return FALSE; + } } - mrcp_header_property_add(accessor,id); return TRUE; } -MRCP_DECLARE(apt_bool_t) mrcp_header_generate(mrcp_header_accessor_t *accessor, apt_text_stream_t *text_stream) +/** Generate header field value */ +MRCP_DECLARE(apt_header_field_t*) mrcp_header_field_value_generate(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_bool_t empty_value, apr_pool_t *pool) { + apt_header_field_t *header_field; const apt_str_t *name; - apr_size_t i,j; - char prop; if(!accessor->vtable) { - return FALSE; - } - - for(i=0, j=0; ivtable->field_count && jcounter; i++) { - prop = accessor->properties[i]; - if((prop & MRCP_HEADER_FIELD_NAME) == MRCP_HEADER_FIELD_NAME) { - j++; - name = apt_string_table_str_get(accessor->vtable->field_table,accessor->vtable->field_count,i); - if(!name) continue; - - apt_text_header_name_generate(name,text_stream); - if((prop & MRCP_HEADER_FIELD_VALUE) == MRCP_HEADER_FIELD_VALUE) { - accessor->vtable->generate_field(accessor,i,text_stream); - } - apt_text_eol_insert(text_stream); - } + return NULL; } - - return TRUE; -} - -MRCP_DECLARE(void) mrcp_header_property_add(mrcp_header_accessor_t *accessor, apr_size_t id) -{ - if(!accessor->vtable) { - return; - } - - if(id < accessor->vtable->field_count) { - char *prop = &accessor->properties[id]; - if((*prop & MRCP_HEADER_FIELD_NAME) != MRCP_HEADER_FIELD_NAME) { - accessor->counter++; - } - *prop = MRCP_HEADER_FIELD_NAME_VALUE; - } -} - -MRCP_DECLARE(void) mrcp_header_name_property_add(mrcp_header_accessor_t *accessor, apr_size_t id) -{ - if(!accessor->vtable) { - return; + + header_field = apt_header_field_alloc(pool); + name = apt_string_table_str_get(accessor->vtable->field_table,accessor->vtable->field_count,id); + if(name) { + header_field->name = *name; } - if(id < accessor->vtable->field_count) { - char *prop = &accessor->properties[id]; - if((*prop & MRCP_HEADER_FIELD_NAME) != MRCP_HEADER_FIELD_NAME) { - *prop = MRCP_HEADER_FIELD_NAME; - accessor->counter++; + if(empty_value == FALSE) { + if(accessor->vtable->generate_field(accessor,id,&header_field->value,pool) == FALSE) { + return NULL; } } -} - - -MRCP_DECLARE(void) mrcp_header_property_remove(mrcp_header_accessor_t *accessor, apr_size_t id) -{ - if(!accessor->vtable) { - return; - } - if(id < accessor->vtable->field_count) { - char *prop = &accessor->properties[id]; - if((*prop & MRCP_HEADER_FIELD_NAME) == MRCP_HEADER_FIELD_NAME) { - accessor->counter--; - } - *prop = MRCP_HEADER_FIELD_NONE; - } + return header_field; } -MRCP_DECLARE(apt_bool_t) mrcp_header_property_check(mrcp_header_accessor_t *accessor, apr_size_t id) +/** Duplicate header field value */ +MRCP_DECLARE(apt_bool_t) mrcp_header_field_value_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src_accessor, apr_size_t id, const apt_str_t *value, apr_pool_t *pool) { if(!accessor->vtable) { return FALSE; } - - if((id < accessor->vtable->field_count) && accessor->properties) { - if((accessor->properties[id] & MRCP_HEADER_FIELD_NAME) == MRCP_HEADER_FIELD_NAME) { - return TRUE; - } - } - return FALSE; -} - - -MRCP_DECLARE(apt_bool_t) mrcp_header_set(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, const mrcp_header_accessor_t *mask, apr_pool_t *pool) -{ - apr_size_t i,j; - - if(!accessor->vtable || !src->vtable) { - return FALSE; - } - - mrcp_header_allocate(accessor,pool); - - for(i=0, j=0; i < src->vtable->field_count && j < src->counter; i++) { - if((mask->properties[i] & src->properties[i] & MRCP_HEADER_FIELD_NAME) == MRCP_HEADER_FIELD_NAME) { - j++; - if((src->properties[i] & MRCP_HEADER_FIELD_VALUE) == MRCP_HEADER_FIELD_VALUE) { - accessor->vtable->duplicate_field(accessor,src,i,pool); - mrcp_header_property_add(accessor,i); - } - else { - mrcp_header_name_property_add(accessor,i); - } - } - } - - return TRUE; -} - -MRCP_DECLARE(apt_bool_t) mrcp_header_inherit(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *parent, apr_pool_t *pool) -{ - apr_size_t i,j; - - if(!accessor->vtable || !parent->vtable) { - return FALSE; - } - - mrcp_header_allocate(accessor,pool); - - for(i=0, j=0; ivtable->field_count && j < parent->counter; i++) { - if((parent->properties[i] & MRCP_HEADER_FIELD_NAME) == MRCP_HEADER_FIELD_NAME) { - j++; - if((accessor->properties[i] & MRCP_HEADER_FIELD_NAME) != MRCP_HEADER_FIELD_NAME) { - if((parent->properties[i] & MRCP_HEADER_FIELD_VALUE) == MRCP_HEADER_FIELD_VALUE) { - accessor->vtable->duplicate_field(accessor,parent,i,pool); - mrcp_header_property_add(accessor,i); - } - else { - mrcp_header_name_property_add(accessor,i); - } - } + + if(value->length) { + if(accessor->vtable->duplicate_field(accessor,src_accessor,id,value,pool) == FALSE) { + return FALSE; } } return TRUE; } - -/** Generate completion-cause */ -MRCP_DECLARE(apt_bool_t) mrcp_completion_cause_generate(const apt_str_table_item_t table[], apr_size_t size, apr_size_t cause, apt_text_stream_t *stream) -{ - int length; - const apt_str_t *name = apt_string_table_str_get(table,size,cause); - if(!name) { - return FALSE; - } - length = sprintf(stream->pos,"%03"APR_SIZE_T_FMT" ",cause); - if(length <= 0) { - return FALSE; - } - stream->pos += length; - - memcpy(stream->pos,name->buf,name->length); - stream->pos += name->length; - return TRUE; -} diff --git a/libs/unimrcp/libs/mrcp/message/src/mrcp_message.c b/libs/unimrcp/libs/mrcp/message/src/mrcp_message.c index 96b52784f5..3a37b2900f 100644 --- a/libs/unimrcp/libs/mrcp/message/src/mrcp_message.c +++ b/libs/unimrcp/libs/mrcp/message/src/mrcp_message.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,214 +12,29 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_message.c 1701 2010-05-22 16:38:10Z achaloyan $ */ #include "mrcp_message.h" #include "mrcp_generic_header.h" #include "mrcp_resource.h" +#include "apt_text_message.h" #include "apt_log.h" -#define MRCP_CHANNEL_ID "Channel-Identifier" -#define MRCP_CHANNEL_ID_LENGTH (sizeof(MRCP_CHANNEL_ID)-1) - -/** Initialize MRCP channel-identifier */ -MRCP_DECLARE(void) mrcp_channel_id_init(mrcp_channel_id *channel_id) -{ - apt_string_reset(&channel_id->session_id); - apt_string_reset(&channel_id->resource_name); -} - -/** Parse MRCP channel-identifier */ -MRCP_DECLARE(apt_bool_t) mrcp_channel_id_parse(mrcp_channel_id *channel_id, apt_text_stream_t *text_stream, apr_pool_t *pool) -{ - apt_bool_t match = FALSE; - apt_pair_t pair; - do { - if(apt_text_header_read(text_stream,&pair) == TRUE) { - if(pair.name.length) { - if(pair.value.length && strncasecmp(pair.name.buf,MRCP_CHANNEL_ID,MRCP_CHANNEL_ID_LENGTH) == 0) { - match = TRUE; - apt_id_resource_parse(&pair.value,'@',&channel_id->session_id,&channel_id->resource_name,pool); - break; - } - /* skip this header, expecting channel identifier first */ - } - else { - /* empty header */ - break; - } - } - } - while(apt_text_is_eos(text_stream) == FALSE); - return match; -} - -/** Generate MRCP channel-identifier */ -MRCP_DECLARE(apt_bool_t) mrcp_channel_id_generate(mrcp_channel_id *channel_id, apt_text_stream_t *text_stream) -{ - apt_str_t *str; - char *pos = text_stream->pos; - - memcpy(pos,MRCP_CHANNEL_ID,MRCP_CHANNEL_ID_LENGTH); - pos += MRCP_CHANNEL_ID_LENGTH; - *pos++ = ':'; - *pos++ = ' '; - - str = &channel_id->session_id; - memcpy(pos,str->buf,str->length); - pos += str->length; - *pos++ = '@'; - - str = &channel_id->resource_name; - memcpy(pos,str->buf,str->length); - pos += str->length; - - text_stream->pos = pos; - apt_text_eol_insert(text_stream); - return TRUE; -} - -/** Parse MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_parse(mrcp_message_header_t *message_header, apt_text_stream_t *text_stream, apr_pool_t *pool) -{ - apt_pair_t pair; - apt_bool_t result = FALSE; - - mrcp_header_allocate(&message_header->generic_header_accessor,pool); - mrcp_header_allocate(&message_header->resource_header_accessor,pool); - - do { - if(apt_text_header_read(text_stream,&pair) == TRUE) { - if(pair.name.length) { - /* normal header */ - if(mrcp_header_parse(&message_header->resource_header_accessor,&pair,pool) != TRUE) { - if(mrcp_header_parse(&message_header->generic_header_accessor,&pair,pool) != TRUE) { - /* unknown MRCP header */ - } - } - } - else { - /* empty header -> exit */ - result = TRUE; - break; - } - } - else { - /* malformed header, skip to the next one */ - } - } - while(apt_text_is_eos(text_stream) == FALSE); - - return result; -} - -/** Generate MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_generate(mrcp_message_header_t *message_header, apt_text_stream_t *text_stream) -{ - mrcp_header_generate(&message_header->resource_header_accessor,text_stream); - mrcp_header_generate(&message_header->generic_header_accessor,text_stream); - apt_text_eol_insert(text_stream); - return TRUE; -} - -/** Set MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_set(mrcp_message_header_t *message_header, const mrcp_message_header_t *src, apr_pool_t *pool) -{ - mrcp_header_set( - &message_header->resource_header_accessor, - &src->resource_header_accessor, - &src->resource_header_accessor,pool); - mrcp_header_set( - &message_header->generic_header_accessor, - &src->generic_header_accessor, - &src->generic_header_accessor,pool); - return TRUE; -} - -/** Get MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_get(mrcp_message_header_t *message_header, const mrcp_message_header_t *src, apr_pool_t *pool) -{ - mrcp_header_set( - &message_header->resource_header_accessor, - &src->resource_header_accessor, - &message_header->resource_header_accessor, - pool); - mrcp_header_set( - &message_header->generic_header_accessor, - &src->generic_header_accessor, - &message_header->generic_header_accessor, - pool); - return TRUE; -} - -/** Inherit MRCP message-header */ -MRCP_DECLARE(apt_bool_t) mrcp_message_header_inherit(mrcp_message_header_t *message_header, const mrcp_message_header_t *parent, apr_pool_t *pool) -{ - mrcp_header_inherit(&message_header->resource_header_accessor,&parent->resource_header_accessor,pool); - mrcp_header_inherit(&message_header->generic_header_accessor,&parent->generic_header_accessor,pool); - return TRUE; -} - - -/** Parse MRCP message-body */ -MRCP_DECLARE(apt_bool_t) mrcp_body_parse(mrcp_message_t *message, apt_text_stream_t *text_stream, apr_pool_t *pool) -{ - if(mrcp_generic_header_property_check(message,GENERIC_HEADER_CONTENT_LENGTH) == TRUE) { - mrcp_generic_header_t *generic_header = mrcp_generic_header_get(message); - if(generic_header && generic_header->content_length) { - apt_str_t *body = &message->body; - body->length = generic_header->content_length; - if(body->length > (text_stream->text.length - (text_stream->pos - text_stream->text.buf))) { - body->length = text_stream->text.length - (text_stream->pos - text_stream->text.buf); - } - body->buf = apr_pstrmemdup(pool,text_stream->pos,body->length); - text_stream->pos += body->length; - } - } - return TRUE; -} - -/** Generate MRCP message-body */ -MRCP_DECLARE(apt_bool_t) mrcp_body_generate(mrcp_message_t *message, apt_text_stream_t *text_stream) -{ - apt_str_t *body = &message->body; - if(body->length) { - memcpy(text_stream->pos,body->buf,body->length); - text_stream->pos += body->length; - } - return TRUE; -} - -/** Initialize MRCP message */ -static void mrcp_message_init(mrcp_message_t *message, apr_pool_t *pool) -{ - mrcp_start_line_init(&message->start_line); - mrcp_channel_id_init(&message->channel_id); - mrcp_message_header_init(&message->header); - apt_string_reset(&message->body); - message->resource = NULL; - message->pool = pool; -} - -/** Set header accessor interface */ -static APR_INLINE void mrcp_generic_header_accessor_set(mrcp_message_t *message) -{ - message->header.generic_header_accessor.vtable = mrcp_generic_header_vtable_get(message->start_line.version); -} - -/** Associate MRCP resource specific data by resource identifier */ -MRCP_DECLARE(apt_bool_t) mrcp_message_resource_set_by_id(mrcp_message_t *message, mrcp_resource_t *resource) +/** Associate MRCP resource with message */ +static apt_bool_t mrcp_message_resource_set_by_id(mrcp_message_t *message, const mrcp_resource_t *resource) { if(!resource) { return FALSE; } message->resource = resource; - message->channel_id.resource_name = resource->name; - - mrcp_generic_header_accessor_set(message); - message->header.resource_header_accessor.vtable = - resource->get_resource_header_vtable(message->start_line.version); + mrcp_message_header_data_alloc( + &message->header, + mrcp_generic_header_vtable_get(message->start_line.version), + resource->get_resource_header_vtable(message->start_line.version), + message->pool); /* associate method_name and method_id */ if(message->start_line.message_type == MRCP_MESSAGE_TYPE_REQUEST) { @@ -247,16 +62,17 @@ MRCP_DECLARE(apt_bool_t) mrcp_message_resource_set_by_id(mrcp_message_t *message } /** Associate MRCP resource specific data by resource name */ -MRCP_DECLARE(apt_bool_t) mrcp_message_resource_set(mrcp_message_t *message, mrcp_resource_t *resource) +MRCP_DECLARE(apt_bool_t) mrcp_message_resource_set(mrcp_message_t *message, const mrcp_resource_t *resource) { if(!resource) { return FALSE; } message->resource = resource; - - mrcp_generic_header_accessor_set(message); - message->header.resource_header_accessor.vtable = - resource->get_resource_header_vtable(message->start_line.version); + mrcp_message_header_data_alloc( + &message->header, + mrcp_generic_header_vtable_get(message->start_line.version), + resource->get_resource_header_vtable(message->start_line.version), + message->pool); /* associate method_name and method_id */ if(message->start_line.message_type == MRCP_MESSAGE_TYPE_REQUEST) { @@ -281,16 +97,21 @@ MRCP_DECLARE(apt_bool_t) mrcp_message_resource_set(mrcp_message_t *message, mrcp return TRUE; } -/** Create MRCP message */ +/** Create an MRCP message */ MRCP_DECLARE(mrcp_message_t*) mrcp_message_create(apr_pool_t *pool) { mrcp_message_t *message = apr_palloc(pool,sizeof(mrcp_message_t)); - mrcp_message_init(message,pool); + mrcp_start_line_init(&message->start_line); + mrcp_channel_id_init(&message->channel_id); + mrcp_message_header_init(&message->header); + apt_string_reset(&message->body); + message->resource = NULL; + message->pool = pool; return message; } -/** Create MRCP request message */ -MRCP_DECLARE(mrcp_message_t*) mrcp_request_create(mrcp_resource_t *resource, mrcp_version_e version, mrcp_method_id method_id, apr_pool_t *pool) +/** Create an MRCP request message */ +MRCP_DECLARE(mrcp_message_t*) mrcp_request_create(const mrcp_resource_t *resource, mrcp_version_e version, mrcp_method_id method_id, apr_pool_t *pool) { mrcp_message_t *request_message = mrcp_message_create(pool); request_message->start_line.message_type = MRCP_MESSAGE_TYPE_REQUEST; @@ -300,7 +121,7 @@ MRCP_DECLARE(mrcp_message_t*) mrcp_request_create(mrcp_resource_t *resource, mrc return request_message; } -/** Create MRCP response message */ +/** Create an MRCP response message */ MRCP_DECLARE(mrcp_message_t*) mrcp_response_create(const mrcp_message_t *request_message, apr_pool_t *pool) { mrcp_message_t *response_message = mrcp_message_create(pool); @@ -312,12 +133,13 @@ MRCP_DECLARE(mrcp_message_t*) mrcp_response_create(const mrcp_message_t *request response_message->start_line.request_id = request_message->start_line.request_id; response_message->start_line.version = request_message->start_line.version; response_message->start_line.method_id = request_message->start_line.method_id; + response_message->start_line.method_name = request_message->start_line.method_name; mrcp_message_resource_set_by_id(response_message,request_message->resource); } return response_message; } -/** Create MRCP event message */ +/** Create an MRCP event message */ MRCP_DECLARE(mrcp_message_t*) mrcp_event_create(const mrcp_message_t *request_message, mrcp_method_id event_id, apr_pool_t *pool) { mrcp_message_t *event_message = mrcp_message_create(pool); @@ -357,3 +179,81 @@ MRCP_DECLARE(apt_bool_t) mrcp_message_validate(mrcp_message_t *message) return TRUE; } + +/** Add MRCP generic header field by specified property (numeric identifier) */ +MRCP_DECLARE(apt_bool_t) mrcp_generic_header_property_add(mrcp_message_t *message, apr_size_t id) +{ + apt_header_field_t *header_field = mrcp_header_field_value_generate( + &message->header.generic_header_accessor, + id, + FALSE, + message->pool); + if(!header_field) { + return FALSE; + } + header_field->id = id; + return apt_header_section_field_add(&message->header.header_section,header_field); +} + +/** Add only the name of MRCP generic header field specified by property (numeric identifier) */ +MRCP_DECLARE(apt_bool_t) mrcp_generic_header_name_property_add(mrcp_message_t *message, apr_size_t id) +{ + apt_header_field_t *header_field = mrcp_header_field_value_generate( + &message->header.generic_header_accessor, + id, + TRUE, + message->pool); + if(!header_field) { + return FALSE; + } + header_field->id = id; + return apt_header_section_field_add(&message->header.header_section,header_field); +} + +/** Add MRCP resource header field by specified property (numeric identifier) */ +MRCP_DECLARE(apt_bool_t) mrcp_resource_header_property_add(mrcp_message_t *message, apr_size_t id) +{ + apt_header_field_t *header_field = mrcp_header_field_value_generate( + &message->header.resource_header_accessor, + id, + FALSE, + message->pool); + if(!header_field) { + return FALSE; + } + header_field->id = id + GENERIC_HEADER_COUNT; + return apt_header_section_field_add(&message->header.header_section,header_field); +} + +/** Add only the name of MRCP resource header field specified by property (numeric identifier) */ +MRCP_DECLARE(apt_bool_t) mrcp_resource_header_name_property_add(mrcp_message_t *message, apr_size_t id) +{ + apt_header_field_t *header_field = mrcp_header_field_value_generate( + &message->header.resource_header_accessor, + id, + TRUE, + message->pool); + if(!header_field) { + return FALSE; + } + header_field->id = id + GENERIC_HEADER_COUNT; + return apt_header_section_field_add(&message->header.header_section,header_field); +} + +/** Get the next MRCP header field */ +MRCP_DECLARE(apt_header_field_t*) mrcp_message_next_header_field_get(const mrcp_message_t *message, apt_header_field_t *header_field) +{ + const apt_header_section_t *header_section = &message->header.header_section; + if(header_field) { + apt_header_field_t *next = APR_RING_NEXT(header_field,link); + if(next == APR_RING_SENTINEL(&header_section->ring,apt_header_field_t,link)) { + return NULL; + } + return next; + } + + if(APR_RING_EMPTY(&header_section->ring,apt_header_field_t,link)) { + return NULL; + } + return APR_RING_FIRST(&header_section->ring); +} diff --git a/libs/unimrcp/libs/mrcp/message/src/mrcp_start_line.c b/libs/unimrcp/libs/mrcp/message/src/mrcp_start_line.c index 2a406663fa..f2a36b0351 100644 --- a/libs/unimrcp/libs/mrcp/message/src/mrcp_start_line.c +++ b/libs/unimrcp/libs/mrcp/message/src/mrcp_start_line.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_start_line.c 1671 2010-04-28 19:50:29Z achaloyan $ */ #include @@ -65,10 +67,20 @@ static mrcp_version_e mrcp_version_parse(const apt_str_t *field) /** Generate MRCP version */ static apt_bool_t mrcp_version_generate(mrcp_version_e version, apt_text_stream_t *stream) { + if(stream->pos + MRCP_NAME_LENGTH + 1 >= stream->end) { + return FALSE; + } memcpy(stream->pos,MRCP_NAME,MRCP_NAME_LENGTH); stream->pos += MRCP_NAME_LENGTH; *stream->pos++ = MRCP_NAME_VERSION_SEPARATOR; - apt_size_value_generate(version,stream); + + if(apt_text_size_value_insert(stream,version) == FALSE) { + return FALSE; + } + + if(stream->pos + 2 >= stream->end) { + return FALSE; + } *stream->pos++ = MRCP_VERSION_MAJOR_MINOR_SEPARATOR; *stream->pos++ = '0'; return TRUE; @@ -102,7 +114,7 @@ static APR_INLINE mrcp_status_code_e mrcp_status_code_parse(const apt_str_t *fie /** Generate MRCP status-code */ static APR_INLINE size_t mrcp_status_code_generate(mrcp_status_code_e status_code, apt_text_stream_t *stream) { - return apt_size_value_generate(status_code,stream); + return apt_text_size_value_insert(stream,status_code); } @@ -318,18 +330,14 @@ MRCP_DECLARE(void) mrcp_start_line_init(mrcp_start_line_t *start_line) } /** Parse MRCP start-line */ -MRCP_DECLARE(apt_bool_t) mrcp_start_line_parse(mrcp_start_line_t *start_line, apt_text_stream_t *text_stream, apr_pool_t *pool) +MRCP_DECLARE(apt_bool_t) mrcp_start_line_parse(mrcp_start_line_t *start_line, apt_str_t *str, apr_pool_t *pool) { apt_text_stream_t line; apt_str_t field; apt_bool_t status = TRUE; + start_line->message_type = MRCP_MESSAGE_TYPE_UNKNOWN; - if(apt_text_line_read(text_stream,&line.text) == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse MRCP start-line"); - return FALSE; - } - - apt_text_stream_reset(&line); + apt_text_stream_init(&line,str->buf,str->length); if(apt_text_field_read(&line,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot read the first field in start-line"); return FALSE; @@ -383,11 +391,11 @@ MRCP_DECLARE(apt_bool_t) mrcp_start_line_generate(mrcp_start_line_t *start_line, status = mrcp_v2_start_line_generate(start_line,text_stream); } - if(status == TRUE) { - apt_text_eol_insert(text_stream); + if(status == FALSE) { + return FALSE; } - - return status; + + return apt_text_eol_insert(text_stream); } /** Finalize MRCP start-line generation */ diff --git a/libs/unimrcp/libs/mrcp/mrcp.2008.vcproj b/libs/unimrcp/libs/mrcp/mrcp.2008.vcproj deleted file mode 100644 index ae656d2749..0000000000 --- a/libs/unimrcp/libs/mrcp/mrcp.2008.vcproj +++ /dev/null @@ -1,422 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/mrcp/mrcp.2010.vcxproj b/libs/unimrcp/libs/mrcp/mrcp.2010.vcxproj deleted file mode 100644 index e525a96146..0000000000 --- a/libs/unimrcp/libs/mrcp/mrcp.2010.vcxproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mrcp - {1C320193-46A6-4B34-9C56-8AB584FC1B56} - mrcp - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - %(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - %(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - ProgramDatabase - - - - - %(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - %(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcp/mrcp.2010.vcxproj.filters b/libs/unimrcp/libs/mrcp/mrcp.2010.vcxproj.filters deleted file mode 100644 index 119921b34b..0000000000 --- a/libs/unimrcp/libs/mrcp/mrcp.2010.vcxproj.filters +++ /dev/null @@ -1,133 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {19ad4bde-c4f4-4937-9073-ca2780341d76} - - - {8ec996ac-8a0a-4bf0-9b3c-535616585109} - h;hpp;hxx;hm;inl;inc;xsd - - - {5ba77874-7c17-4748-b5ba-b07b7f0a2169} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {f30fd049-a10d-4aea-b4bb-3eb674690fdd} - - - {7e71717b-6f22-4c59-ba50-7b5a15516b2f} - h;hpp;hxx;hm;inl;inc;xsd - - - {c66dbb84-ce9d-4408-b54d-4d0ec51069fb} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {f20cfd62-4bb9-42de-bf1c-d578c8cd1a18} - - - {039a4834-7ddb-40e7-9177-55d11ef1e733} - h;hpp;hxx;hm;inl;inc;xsd - - - {dc087d31-8ecf-473c-baa1-f3091e16014d} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - message\include - - - message\include - - - message\include - - - message\include - - - control\include - - - control\include - - - control\include - - - control\include - - - resources\include - - - resources\include - - - resources\include - - - resources\include - - - resources\include - - - resources\include - - - - - message\src - - - message\src - - - message\src - - - message\src - - - control\src - - - control\src - - - control\src - - - resources\src - - - resources\src - - - resources\src - - - resources\src - - - resources\src - - - resources\src - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcp/mrcp.vcproj b/libs/unimrcp/libs/mrcp/mrcp.vcproj index de0721096c..dc421663c7 100644 --- a/libs/unimrcp/libs/mrcp/mrcp.vcproj +++ b/libs/unimrcp/libs/mrcp/mrcp.vcproj @@ -264,6 +264,10 @@ RelativePath=".\message\include\mrcp_generic_header.h" > + + @@ -285,6 +289,10 @@ RelativePath=".\message\src\mrcp_generic_header.c" > + + @@ -372,6 +380,14 @@ RelativePath=".\resources\include\mrcp_synth_resource.h" > + + + + + + + + diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_header.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_header.h index 4b2192b399..40556d5790 100644 --- a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_header.h +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recog_header.h 1736 2010-06-14 20:16:22Z achaloyan $ */ -#ifndef __MRCP_RECOG_HEADER_H__ -#define __MRCP_RECOG_HEADER_H__ +#ifndef MRCP_RECOG_HEADER_H +#define MRCP_RECOG_HEADER_H /** * @file mrcp_recog_header.h @@ -27,7 +29,7 @@ APT_BEGIN_EXTERN_C -/** MRCP recognizer headers */ +/** MRCP recognizer header fields */ typedef enum { RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD, RECOGNIZER_HEADER_SENSITIVITY_LEVEL, @@ -50,7 +52,7 @@ typedef enum { RECOGNIZER_HEADER_NEW_AUDIO_CHANNEL, RECOGNIZER_HEADER_SPEECH_LANGUAGE, - /** Additional headers for MRCP v2 */ + /** Additional header fields for MRCP v2 */ RECOGNIZER_HEADER_INPUT_TYPE, RECOGNIZER_HEADER_INPUT_WAVEFORM_URI, RECOGNIZER_HEADER_COMPLETION_REASON, @@ -64,6 +66,18 @@ typedef enum { RECOGNIZER_HEADER_DTMF_BUFFER_TIME, RECOGNIZER_HEADER_CLEAR_DTMF_BUFFER, RECOGNIZER_HEADER_EARLY_NO_MATCH, + RECOGNIZER_HEADER_NUM_MIN_CONSISTENT_PRONUNCIATIONS, + RECOGNIZER_HEADER_CONSISTENCY_THRESHOLD, + RECOGNIZER_HEADER_CLASH_THRESHOLD, + RECOGNIZER_HEADER_PERSONAL_GRAMMAR_URI, + RECOGNIZER_HEADER_ENROLL_UTTERANCE, + RECOGNIZER_HEADER_PHRASE_ID, + RECOGNIZER_HEADER_PHRASE_NL, + RECOGNIZER_HEADER_WEIGHT, + RECOGNIZER_HEADER_SAVE_BEST_WAVEFORM, + RECOGNIZER_HEADER_NEW_PHRASE_ID, + RECOGNIZER_HEADER_CONFUSABLE_PHRASES_URI, + RECOGNIZER_HEADER_ABORT_PHRASE_ENROLLMENT, RECOGNIZER_HEADER_COUNT } mrcp_recognizer_header_id; @@ -160,7 +174,7 @@ struct mrcp_recog_header_t { a session or request, if it is not specified within the data */ apt_str_t speech_language; - /** Additional headers for MRCP v2 */ + /** Additional header fields for MRCP v2 */ /** Specifies if the input that caused a barge-in was DTMF or speech */ apt_str_t input_type; /** Optional header specifies a URI pointing to audio content to be @@ -169,10 +183,10 @@ struct mrcp_recog_header_t { /** MAY be specified in a RECOGNITION-COMPLETE event coming from the recognizer resource to the client */ apt_str_t completion_reason; - /** tells the server resource the Media Type in which to store captured + /** Tells the server resource the Media Type in which to store captured audio such as the one captured and returned by the Waveform-URI header */ apt_str_t media_type; - /** lets the client request the server to buffer the + /** Lets the client request the server to buffer the utterance associated with this recognition request into a buffer available to a co-resident verification resource */ apt_bool_t ver_buffer_utterance; @@ -202,6 +216,49 @@ struct mrcp_recog_header_t { tell the recognizer that it MUST not wait for the end of speech before processing the collected speech to match active grammars */ apt_bool_t early_no_match; + /** MAY be specified in a START-PHRASE-ENROLLMENT, "SET-PARAMS", or + "GET-PARAMS" method and is used to specify the minimum number of + consistent pronunciations that must be obtained to voice enroll a new phrase */ + apr_size_t num_min_consistent_pronunciations; + /** MAY be sent as part of the START-PHRASE-ENROLLMENT,"SET-PARAMS", or + "GET-PARAMS" method and is used during voice-enrollment to specify how similar + to a previously enrolled pronunciation of the same phrase an utterance needs + to be in order to be considered "consistent" */ + float consistency_threshold; + /** MAY be sent as part of the START-PHRASE-ENROLLMENT, SET-PARAMS, or + "GET-PARAMS" method and is used during voice-enrollment to specify + how similar the pronunciations of two different phrases can be + before they are considered to be clashing */ + float clash_threshold; + /** Specifies the speaker-trained grammar to be used or + referenced during enrollment operations */ + apt_str_t personal_grammar_uri; + /** MAY be specified in the RECOGNIZE method. If this header + is set to "true" and an Enrollment is active, the RECOGNIZE command + MUST add the collected utterance to the personal grammar that is + being enrolled */ + apt_bool_t enroll_utterance; + /** Identifies a phrase in an existing personal grammar for which + enrollment is desired. It is also returned to the client in the + RECOGNIZE complete event */ + apt_str_t phrase_id; + /** Specifies the interpreted text to be returned when the + phrase is recognized */ + apt_str_t phrase_nl; + /** Represents the occurrence likelihood of a phrase in an enrolled grammar */ + float weight; + /** Allows the client to request the recognizer resource to + save the audio stream for the best repetition of the phrase that was + used during the enrollment session */ + apt_bool_t save_best_waveform; + /** Replaces the id used to identify the phrase in a personal grammar */ + apt_str_t new_phrase_id; + /** Specifies a grammar that defines invalid phrases for enrollment */ + apt_str_t confusable_phrases_uri; + /** Can optionally be specified in the END-PHRASE-ENROLLMENT + method to abort the phrase enrollment, rather than committing the + phrase to the personal grammar */ + apt_bool_t abort_phrase_enrollment; }; @@ -213,4 +270,4 @@ MRCP_DECLARE(const apt_str_t*) mrcp_recog_completion_cause_get(mrcp_recog_comple APT_END_EXTERN_C -#endif /*__MRCP_RECOG_HEADER_H__*/ +#endif /* MRCP_RECOG_HEADER_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_resource.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_resource.h index 0131e9caed..64eddd9290 100644 --- a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_resource.h +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_resource.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recog_resource.h 1781 2010-09-01 07:33:00Z achaloyan $ */ -#ifndef __MRCP_RECOG_RESOURCE_H__ -#define __MRCP_RECOG_RESOURCE_H__ +#ifndef MRCP_RECOG_RESOURCE_H +#define MRCP_RECOG_RESOURCE_H /** * @file mrcp_recog_resource.h @@ -32,9 +34,15 @@ typedef enum { RECOGNIZER_GET_PARAMS, RECOGNIZER_DEFINE_GRAMMAR, RECOGNIZER_RECOGNIZE, + RECOGNIZER_INTERPRET, RECOGNIZER_GET_RESULT, RECOGNIZER_START_INPUT_TIMERS, RECOGNIZER_STOP, + RECOGNIZER_START_PHRASE_ENROLLMENT, + RECOGNIZER_ENROLLMENT_ROLLBACK, + RECOGNIZER_END_PHRASE_ENROLLMENT, + RECOGNIZER_MODIFY_PHRASE, + RECOGNIZER_DELETE_PHRASE, RECOGNIZER_METHOD_COUNT } mrcp_recognizer_method_id; @@ -43,6 +51,7 @@ typedef enum { typedef enum { RECOGNIZER_START_OF_INPUT, RECOGNIZER_RECOGNITION_COMPLETE, + RECOGNIZER_INTERPRETATION_COMPLETE, RECOGNIZER_EVENT_COUNT } mrcp_recognizer_event_id; @@ -52,4 +61,4 @@ MRCP_DECLARE(mrcp_resource_t*) mrcp_recog_resource_create(apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__MRCP_RECOG_RESOURCE_H__*/ +#endif /* MRCP_RECOG_RESOURCE_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_header.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_header.h index af1772337a..2fadba5ea8 100644 --- a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_header.h +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recorder_header.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RECORDER_HEADER_H__ -#define __MRCP_RECORDER_HEADER_H__ +#ifndef MRCP_RECORDER_HEADER_H +#define MRCP_RECORDER_HEADER_H /** * @file mrcp_recorder_header.h @@ -133,4 +135,4 @@ MRCP_DECLARE(const apt_str_t*) mrcp_recorder_completion_cause_get( APT_END_EXTERN_C -#endif /*__MRCP_RECORDER_HEADER_H__*/ +#endif /* MRCP_RECORDER_HEADER_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_resource.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_resource.h index b9afa34999..090992ba62 100644 --- a/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_resource.h +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_recorder_resource.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recorder_resource.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_RECORDER_RESOURCE_H__ -#define __MRCP_RECORDER_RESOURCE_H__ +#ifndef MRCP_RECORDER_RESOURCE_H +#define MRCP_RECORDER_RESOURCE_H /** * @file mrcp_recorder_resource.h @@ -50,4 +52,4 @@ MRCP_DECLARE(mrcp_resource_t*) mrcp_recorder_resource_create(apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__MRCP_RECORDER_RESOURCE_H__*/ +#endif /* MRCP_RECORDER_RESOURCE_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_header.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_header.h index 359af6bd59..c711414471 100644 --- a/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_header.h +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_synth_header.h 1643 2010-04-08 13:40:09Z achaloyan $ */ -#ifndef __MRCP_SYNTH_HEADER_H__ -#define __MRCP_SYNTH_HEADER_H__ +#ifndef MRCP_SYNTH_HEADER_H +#define MRCP_SYNTH_HEADER_H /** * @file mrcp_synth_header.h @@ -27,7 +29,7 @@ APT_BEGIN_EXTERN_C -/** MRCP synthesizer headers */ +/** MRCP synthesizer header fields */ typedef enum { SYNTHESIZER_HEADER_JUMP_SIZE, SYNTHESIZER_HEADER_KILL_ON_BARGE_IN, @@ -248,9 +250,9 @@ struct mrcp_synth_header_t { /** MAY be specified in a "SPEAK-COMPLETE" event coming from the synthesizer resource to the client */ apt_str_t completion_reason; - /** This set of headers defines the voice of the speaker */ + /** This set of header fields defines the voice of the speaker */ mrcp_voice_param_t voice_param; - /** This set of headers defines the prosody of the speech */ + /** This set of header fields defines the prosody of the speech */ mrcp_prosody_param_t prosody_param; /** Contains timestamp information in a "timestamp" field */ apt_str_t speech_marker; @@ -285,7 +287,7 @@ struct mrcp_synth_header_t { mrcp_speech_length_value_t speak_length; /** Used to indicate whether a lexicon has to be loaded or unloaded */ apt_bool_t load_lexicon; - /** used to specify a list of active Lexicon URIs and the + /** Used to specify a list of active Lexicon URIs and the search order among the active lexicons */ apt_str_t lexicon_search_order; }; @@ -299,4 +301,4 @@ MRCP_DECLARE(const apt_str_t*) mrcp_synth_completion_cause_get(mrcp_synth_comple APT_END_EXTERN_C -#endif /*__MRCP_SYNTH_HEADER_H__*/ +#endif /* MRCP_SYNTH_HEADER_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_resource.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_resource.h index d63fbdbfe3..256be1ac3c 100644 --- a/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_resource.h +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_resource.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_synth_resource.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_SYNTH_RESOURCE_H__ -#define __MRCP_SYNTH_RESOURCE_H__ +#ifndef MRCP_SYNTH_RESOURCE_H +#define MRCP_SYNTH_RESOURCE_H /** * @file mrcp_synth_resource.h @@ -55,4 +57,4 @@ MRCP_DECLARE(mrcp_resource_t*) mrcp_synth_resource_create(apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__MRCP_SYNTH_RESOURCE_H__*/ +#endif /* MRCP_SYNTH_RESOURCE_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_verifier_header.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_verifier_header.h new file mode 100644 index 0000000000..cac29e01d1 --- /dev/null +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_verifier_header.h @@ -0,0 +1,162 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: + */ + +#ifndef MRCP_VERIFIER_HEADER_H +#define MRCP_VERIFIER_HEADER_H + +/** + * @file mrcp_verifier_header.h + * @brief MRCP Verifier Header + */ + +#include "mrcp_types.h" +#include "mrcp_header_accessor.h" + +APT_BEGIN_EXTERN_C + +/** MRCP verifier header fields */ +typedef enum { + VERIFIER_HEADER_REPOSITORY_URI, + VERIFIER_HEADER_VOICEPRINT_IDENTIFIER, + VERIFIER_HEADER_VERIFICATION_MODE, + VERIFIER_HEADER_ADAPT_MODEL, + VERIFIER_HEADER_ABORT_MODEL, + VERIFIER_HEADER_MIN_VERIFICATION_SCORE, + VERIFIER_HEADER_NUM_MIN_VERIFICATION_PHRASES, + VERIFIER_HEADER_NUM_MAX_VERIFICATION_PHRASES, + VERIFIER_HEADER_NO_INPUT_TIMEOUT, + VERIFIER_HEADER_SAVE_WAVEFORM, + VERIFIER_HEADER_MEDIA_TYPE, + VERIFIER_HEADER_WAVEFORM_URI, + VERIFIER_HEADER_VOICEPRINT_EXISTS, + VERIFIER_HEADER_VER_BUFFER_UTTERANCE, + VERIFIER_HEADER_INPUT_WAVEFORM_URI, + VERIFIER_HEADER_COMPLETION_CAUSE, + VERIFIER_HEADER_COMPLETION_REASON, + VERIFIER_HEADER_SPEECH_COMPLETE_TIMEOUT, + VERIFIER_HEADER_NEW_AUDIO_CHANNEL, + VERIFIER_HEADER_ABORT_VERIFICATION, + VERIFIER_HEADER_START_INPUT_TIMERS, + + VERIFIER_HEADER_COUNT +} mrcp_verifier_header_id; + + +/** MRCP verifier completion-cause */ +typedef enum { + VERIFIER_COMPLETION_CAUSE_SUCCESS = 0, + VERIFIER_COMPLETION_CAUSE_ERROR = 1, + VERIFIER_COMPLETION_CAUSE_NO_INPUT_TIMEOUT = 2, + VERIFIER_COMPLETION_CAUSE_TOO_MUCH_SPEECH_TIMEOUT = 3, + VERIFIER_COMPLETION_CAUSE_SPEECH_TOO_EARLY = 4, + VERIFIER_COMPLETION_CAUSE_BUFFER_EMPTY = 5, + VERIFIER_COMPLETION_CAUSE_OUT_OF_SEQUENCE = 6, + VERIFIER_COMPLETION_CAUSE_REPOSITORY_URI_FAILURE = 7, + VERIFIER_COMPLETION_CAUSE_REPOSITORY_URI_MISSING = 8, + VERIFIER_COMPLETION_CAUSE_VOICEPRINT_ID_MISSING = 9, + VERIFIER_COMPLETION_CAUSE_VOICEPRINT_ID_NOT_EXIST = 10, + VERIFIER_COMPLETION_CAUSE_SPEECH_NOT_USABLE = 11, + + VERIFIER_COMPLETION_CAUSE_COUNT = 12, + VERIFIER_COMPLETION_CAUSE_UNKNOWN = VERIFIER_COMPLETION_CAUSE_COUNT +} mrcp_verifier_completion_cause_e; + + + +/** MRCP verifier-header declaration */ +typedef struct mrcp_verifier_header_t mrcp_verifier_header_t; + +/** MRCP verifier-header */ +struct mrcp_verifier_header_t { + /** Specifies the voiceprint repository to be used or referenced during + speaker verification or identification operations */ + apt_str_t repository_uri; + /** Specifies the claimed identity for verification applications */ + apt_str_t voiceprint_identifier; + /** Specifies the mode of the verification resource */ + apt_str_t verification_mode; + /** Indicates the desired behavior of the verification resource + after a successful verification operation */ + apt_bool_t adapt_model; + /** Indicates the desired behavior of the verification resource + upon session termination */ + apt_bool_t abort_model; + /** Determines the minimum verification score for which a verification + decision of "accepted" may be declared by the server */ + float min_verification_score; + /** Specifies the minimum number of valid utterances + before a positive decision is given for verification */ + apr_size_t num_min_verification_phrases; + /** Specifies the number of valid utterances required + before a decision is forced for verification */ + apr_size_t num_max_verification_phrases; + /** Sets the length of time from the start of the verification timers + (see START-INPUT-TIMERS) until the declaration of a no-input event + in the VERIFICATION-COMPLETE server event message */ + apr_size_t no_input_timeout; + /** Allows the client to request the verification resource to save + the audio stream that was used for verification/identification */ + apt_bool_t save_waveform; + /** Tells the server resource the Media Type of the captured audio or video + such as the one captured and returned by the Waveform-URI header field */ + apt_str_t media_type; + /** If the Save-Waveform header field is set to true, the verification resource + MUST attempt to record the incoming audio stream of the verification into + a file and provide a URI for the client to access it */ + apt_str_t waveform_uri; + /** Shows the status of the voiceprint specified + in the QUERY-VOICEPRINT method */ + apt_bool_t voiceprint_exists; + /** Indicates that this utterance could be + later considered for Speaker Verification */ + apt_bool_t ver_buffer_utterance; + /** Specifies stored audio content that the client requests the server + to fetch and process according to the current verification mode, + either to train the voiceprint or verify a claimed identity */ + apt_str_t input_waveform_uri; + /** Indicates the cause of VERIFY or VERIFY-FROM-BUFFER method completion */ + mrcp_verifier_completion_cause_e completion_cause; + /** MAY be specified in a VERIFICATION-COMPLETE event + coming from the verifier resource to the client */ + apt_str_t completion_reason; + /** Specifies the length of silence required following user + speech before the speech verifier finalizes a result */ + apr_size_t speech_complete_timeout; + /** MAY be specified in a VERIFIER request and allows the + client to tell the server that, from this point on, further input + audio comes from a different audio source */ + apt_bool_t new_audio_channel; + /** MUST be sent in a STOP request to indicate + whether or not to abort a VERIFY method in progress */ + apt_bool_t abort_verification; + /** MAY be sent as part of a VERIFY request. A value of false + tells the verification resource to start the VERIFY operation, + but not to start the no-input timer yet */ + apt_bool_t start_input_timers; +}; + + +/** Get verifier header vtable */ +const mrcp_header_vtable_t* mrcp_verifier_header_vtable_get(mrcp_version_e version); + +/** Get verifier completion cause string */ +MRCP_DECLARE(const apt_str_t*) mrcp_verifier_completion_cause_get(mrcp_verifier_completion_cause_e completion_cause, mrcp_version_e version); + +APT_END_EXTERN_C + +#endif /* MRCP_VERIFIER_HEADER_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/include/mrcp_verifier_resource.h b/libs/unimrcp/libs/mrcp/resources/include/mrcp_verifier_resource.h new file mode 100644 index 0000000000..5fcfaef2ce --- /dev/null +++ b/libs/unimrcp/libs/mrcp/resources/include/mrcp_verifier_resource.h @@ -0,0 +1,63 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: + */ + +#ifndef MRCP_VERIFIER_RESOURCE_H +#define MRCP_VERIFIER_RESOURCE_H + +/** + * @file mrcp_verifier_resource.h + * @brief MRCP Verifier Resource + */ + +#include "mrcp_types.h" + +APT_BEGIN_EXTERN_C + +/** MRCP verifier methods */ +typedef enum { + VERIFIER_SET_PARAMS, + VERIFIER_GET_PARAMS, + VERIFIER_START_SESSION, + VERIFIER_END_SESSION, + VERIFIER_QUERY_VOICEPRINT, + VERIFIER_DELETE_VOICEPRINT, + VERIFIER_VERIFY, + VERIFIER_VERIFY_FROM_BUFFER, + VERIFIER_VERIFY_ROLLBACK, + VERIFIER_STOP, + VERIFIER_CLEAR_BUFFER, + VERIFIER_START_INPUT_TIMERS, + VERIFIER_GET_INTERMIDIATE_RESULT, + + VERIFIER_METHOD_COUNT +} mrcp_verifier_method_id; + +/** MRCP verifier events */ +typedef enum { + VERIFIER_START_OF_INPUT, + VERIFIER_VERIFICATION_COMPLETE, + + VERIFIER_EVENT_COUNT +} mrcp_verifier_event_id; + +/** Create MRCP verifier resource */ +MRCP_DECLARE(mrcp_resource_t*) mrcp_verifier_resource_create(apr_pool_t *pool); + +APT_END_EXTERN_C + +#endif /* MRCP_VERIFIER_RESOURCE_H */ diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_header.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_header.c index 4bfbcbe16e..81ae07507d 100644 --- a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_header.c +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_header.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,82 +12,108 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recog_header.c 1736 2010-06-14 20:16:22Z achaloyan $ */ #include "mrcp_recog_header.h" -/** String table of MRCPv1 recognizer headers (mrcp_recog_header_id) */ +/** String table of MRCPv1 recognizer header fields (mrcp_recog_header_id) */ static const apt_str_table_item_t v1_recog_header_string_table[] = { - {{"Confidence-Threshold", 20},7}, - {{"Sensitivity-Level", 17},3}, - {{"Speed-Vs-Accuracy", 17},4}, - {{"N-Best-List-Length", 18},1}, - {{"No-Input-Timeout", 16},2}, - {{"Recognition-Timeout", 19},16}, - {{"Waveform-Url", 12},0}, - {{"Completion-Cause", 16},16}, - {{"Recognizer-Context-Block", 24},12}, - {{"Recognizer-Start-Timers", 23},11}, - {{"Speech-Complete-Timeout", 23},7}, - {{"Speech-Incomplete-Timeout", 25},8}, - {{"DTMF-Interdigit-Timeout", 23},5}, - {{"DTMF-Term-Timeout", 17},14}, - {{"DTMF-Term-Char", 14},14}, - {{"Failed-Uri", 10},10}, - {{"Failed-Uri-Cause", 16},16}, - {{"Save-Waveform", 13},5}, - {{"New-Audio-Channel", 17},2}, - {{"Speech-Language", 15},8}, - {{"Input-Type", 10},10}, - {{"Input-Waveform-Uri", 18},6}, - {{"Completion-Reason", 17},15}, - {{"Media-Type", 10},0}, - {{"Ver-Buffer-Utterance", 20},0}, - {{"Recognition-Mode", 16},14}, - {{"Cancel-If-Queue", 15},3}, - {{"Hotword-Max-Duration", 20},10}, - {{"Hotword-Min-Duration", 20},20}, - {{"Interpret-Text", 14},7}, - {{"DTMF-Buffer-Time", 16},5}, - {{"Clear-DTMF-Buffer", 17},1}, - {{"Early-No-Match", 14},0} + {{"Confidence-Threshold", 20},16}, + {{"Sensitivity-Level", 17},14}, + {{"Speed-Vs-Accuracy", 17},4}, + {{"N-Best-List-Length", 18},1}, + {{"No-Input-Timeout", 16},2}, + {{"Recognition-Timeout", 19},19}, + {{"Waveform-Url", 12},4}, + {{"Completion-Cause", 16},16}, + {{"Recognizer-Context-Block", 24},16}, + {{"Recognizer-Start-Timers", 23},18}, + {{"Speech-Complete-Timeout", 23},7}, + {{"Speech-Incomplete-Timeout", 25},12}, + {{"DTMF-Interdigit-Timeout", 23},10}, + {{"DTMF-Term-Timeout", 17},14}, + {{"DTMF-Term-Char", 14},14}, + {{"Failed-Uri", 10},10}, + {{"Failed-Uri-Cause", 16},16}, + {{"Save-Waveform", 13},5}, + {{"New-Audio-Channel", 17},17}, + {{"Speech-Language", 15},8}, + {{"Input-Type", 10},10}, + {{"Input-Waveform-Uri", 18},6}, + {{"Completion-Reason", 17},17}, + {{"Media-Type", 10},0}, + {{"Ver-Buffer-Utterance", 20},0}, + {{"Recognition-Mode", 16},16}, + {{"Cancel-If-Queue", 15},3}, + {{"Hotword-Max-Duration", 20},10}, + {{"Hotword-Min-Duration", 20},20}, + {{"Interpret-Text", 14},12}, + {{"DTMF-Buffer-Time", 16},16}, + {{"Clear-DTMF-Buffer", 17},11}, + {{"Early-No-Match", 14},4}, + {{"Num-Min-Consistent-Pronunciations",33},1}, + {{"Consistency-Threshold", 21},16}, + {{"Clash-Threshold", 15},2}, + {{"Personal-Grammar-URI", 20},9}, + {{"Enroll-Utterance", 16},10}, + {{"Phrase-ID", 9},8}, + {{"Phrase-NL", 9},9}, + {{"Weight", 6},3}, + {{"Save-Best-Waveform", 18},10}, + {{"New-Phrase-ID", 13},4}, + {{"Confusable-Phrases-URI", 22},4}, + {{"Abort-Phrase-Enrollment", 23},0} }; -/** String table of MRCPv2 recognizer headers (mrcp_recog_header_id) */ +/** String table of MRCPv2 recognizer header fields (mrcp_recog_header_id) */ static const apt_str_table_item_t v2_recog_header_string_table[] = { - {{"Confidence-Threshold", 20},8}, - {{"Sensitivity-Level", 17},3}, - {{"Speed-Vs-Accuracy", 17},4}, - {{"N-Best-List-Length", 18},1}, - {{"No-Input-Timeout", 16},2}, - {{"Recognition-Timeout", 19},16}, - {{"Waveform-Uri", 12},0}, - {{"Completion-Cause", 16},16}, - {{"Recognizer-Context-Block", 24},7}, - {{"Start-Input-Timers", 18},2}, - {{"Speech-Complete-Timeout", 23},7}, - {{"Speech-Incomplete-Timeout", 25},8}, - {{"DTMF-Interdigit-Timeout", 23},5}, - {{"DTMF-Term-Timeout", 17},14}, - {{"DTMF-Term-Char", 14},14}, - {{"Failed-Uri", 10},10}, - {{"Failed-Uri-Cause", 16},16}, - {{"Save-Waveform", 13},5}, - {{"New-Audio-Channel", 17},2}, - {{"Speech-Language", 15},8}, - {{"Input-Type", 10},10}, - {{"Input-Waveform-Uri", 18},6}, - {{"Completion-Reason", 17},13}, - {{"Media-Type", 10},0}, - {{"Ver-Buffer-Utterance", 20},0}, - {{"Recognition-Mode", 16},14}, - {{"Cancel-If-Queue", 15},3}, - {{"Hotword-Max-Duration", 20},10}, - {{"Hotword-Min-Duration", 20},20}, - {{"Interpret-Text", 14},7}, - {{"DTMF-Buffer-Time", 16},5}, - {{"Clear-DTMF-Buffer", 17},1}, - {{"Early-No-Match", 14},0} + {{"Confidence-Threshold", 20},16}, + {{"Sensitivity-Level", 17},14}, + {{"Speed-Vs-Accuracy", 17},4}, + {{"N-Best-List-Length", 18},1}, + {{"No-Input-Timeout", 16},2}, + {{"Recognition-Timeout", 19},19}, + {{"Waveform-Uri", 12},4}, + {{"Completion-Cause", 16},16}, + {{"Recognizer-Context-Block", 24},7}, + {{"Start-Input-Timers", 18},18}, + {{"Speech-Complete-Timeout", 23},7}, + {{"Speech-Incomplete-Timeout", 25},12}, + {{"DTMF-Interdigit-Timeout", 23},10}, + {{"DTMF-Term-Timeout", 17},14}, + {{"DTMF-Term-Char", 14},14}, + {{"Failed-Uri", 10},10}, + {{"Failed-Uri-Cause", 16},16}, + {{"Save-Waveform", 13},5}, + {{"New-Audio-Channel", 17},17}, + {{"Speech-Language", 15},8}, + {{"Input-Type", 10},10}, + {{"Input-Waveform-Uri", 18},6}, + {{"Completion-Reason", 17},13}, + {{"Media-Type", 10},0}, + {{"Ver-Buffer-Utterance", 20},0}, + {{"Recognition-Mode", 16},16}, + {{"Cancel-If-Queue", 15},3}, + {{"Hotword-Max-Duration", 20},10}, + {{"Hotword-Min-Duration", 20},20}, + {{"Interpret-Text", 14},12}, + {{"DTMF-Buffer-Time", 16},16}, + {{"Clear-DTMF-Buffer", 17},11}, + {{"Early-No-Match", 14},4}, + {{"Num-Min-Consistent-Pronunciations",33},1}, + {{"Consistency-Threshold", 21},16}, + {{"Clash-Threshold", 15},15}, + {{"Personal-Grammar-URI", 20},9}, + {{"Enroll-Utterance", 16},10}, + {{"Phrase-ID", 9},8}, + {{"Phrase-NL", 9},9}, + {{"Weight", 6},3}, + {{"Save-Best-Waveform", 18},10}, + {{"New-Phrase-ID", 13},4}, + {{"Confusable-Phrases-URI", 22},4}, + {{"Abort-Phrase-Enrollment", 23},0} }; /** String table of MRCPv1 recognizer completion-cause fields (mrcp_recog_completion_cause_e) */ @@ -156,7 +182,7 @@ static void mrcp_recog_header_init(mrcp_recog_header_t *recog_header) recog_header->save_waveform = FALSE; recog_header->new_audio_channel = FALSE; apt_string_reset(&recog_header->speech_language); - /* initializes additionnal MRCPV2 recog headers */ + /* initializes additionnal MRCPV2 recog header fields */ apt_string_reset(&recog_header->input_type); apt_string_reset(&recog_header->input_waveform_uri); apt_string_reset(&recog_header->completion_reason); @@ -170,6 +196,18 @@ static void mrcp_recog_header_init(mrcp_recog_header_t *recog_header) recog_header->dtmf_buffer_time = 0; recog_header->clear_dtmf_buffer = FALSE; recog_header->early_no_match = FALSE; + recog_header->num_min_consistent_pronunciations = 0; + recog_header->consistency_threshold = 0.0; + recog_header->clash_threshold = 0.0; + apt_string_reset(&recog_header->personal_grammar_uri); + recog_header->enroll_utterance = FALSE; + apt_string_reset(&recog_header->phrase_id); + apt_string_reset(&recog_header->phrase_nl); + recog_header->weight = 0.0; + recog_header->save_best_waveform = FALSE; + apt_string_reset(&recog_header->new_phrase_id); + apt_string_reset(&recog_header->confusable_phrases_uri); + recog_header->abort_phrase_enrollment = FALSE; } /** Allocate MRCP recognizer header */ @@ -196,13 +234,13 @@ static apt_bool_t mrcp_recog_header_parse(mrcp_recog_header_t *recog_header, apr recog_header->recognition_timeout = apt_size_value_parse(value); break; case RECOGNIZER_HEADER_WAVEFORM_URI: - apt_string_copy(&recog_header->waveform_uri,value,pool); + recog_header->waveform_uri = *value; break; case RECOGNIZER_HEADER_COMPLETION_CAUSE: recog_header->completion_cause = apt_size_value_parse(value); break; case RECOGNIZER_HEADER_RECOGNIZER_CONTEXT_BLOCK: - apt_string_copy(&recog_header->recognizer_context_block,value,pool); + recog_header->recognizer_context_block = *value; break; case RECOGNIZER_HEADER_START_INPUT_TIMERS: apt_boolean_value_parse(value,&recog_header->start_input_timers); @@ -223,10 +261,10 @@ static apt_bool_t mrcp_recog_header_parse(mrcp_recog_header_t *recog_header, apr recog_header->dtmf_term_char = *value->buf; break; case RECOGNIZER_HEADER_FAILED_URI: - apt_string_copy(&recog_header->failed_uri,value,pool); + recog_header->failed_uri = *value; break; case RECOGNIZER_HEADER_FAILED_URI_CAUSE: - apt_string_copy(&recog_header->failed_uri_cause,value,pool); + recog_header->failed_uri_cause = *value; break; case RECOGNIZER_HEADER_SAVE_WAVEFORM: apt_boolean_value_parse(value,&recog_header->save_waveform); @@ -235,25 +273,25 @@ static apt_bool_t mrcp_recog_header_parse(mrcp_recog_header_t *recog_header, apr apt_boolean_value_parse(value,&recog_header->new_audio_channel); break; case RECOGNIZER_HEADER_SPEECH_LANGUAGE: - apt_string_copy(&recog_header->speech_language,value,pool); + recog_header->speech_language = *value; break; case RECOGNIZER_HEADER_INPUT_TYPE: - apt_string_copy(&recog_header->input_type,value,pool); + recog_header->input_type = *value; break; case RECOGNIZER_HEADER_MEDIA_TYPE: - apt_string_copy(&recog_header->media_type,value,pool); + recog_header->media_type = *value; break; case RECOGNIZER_HEADER_INPUT_WAVEFORM_URI: - apt_string_copy(&recog_header->input_waveform_uri,value,pool); + recog_header->input_waveform_uri = *value; break; case RECOGNIZER_HEADER_COMPLETION_REASON: - apt_string_copy(&recog_header->completion_reason,value,pool); + recog_header->completion_reason = *value; break; case RECOGNIZER_HEADER_VER_BUFFER_UTTERANCE: apt_boolean_value_parse(value,&recog_header->ver_buffer_utterance); break; case RECOGNIZER_HEADER_RECOGNITION_MODE: - apt_string_copy(&recog_header->recognition_mode,value,pool); + recog_header->recognition_mode = *value; break; case RECOGNIZER_HEADER_CANCEL_IF_QUEUE: apt_boolean_value_parse(value,&recog_header->cancel_if_queue); @@ -265,7 +303,7 @@ static apt_bool_t mrcp_recog_header_parse(mrcp_recog_header_t *recog_header, apr recog_header->hotword_min_duration = apt_size_value_parse(value); break; case RECOGNIZER_HEADER_INTERPRET_TEXT: - apt_string_copy(&recog_header->interpret_text,value,pool); + recog_header->interpret_text = *value; break; case RECOGNIZER_HEADER_DTMF_BUFFER_TIME: recog_header->dtmf_buffer_time = apt_size_value_parse(value); @@ -276,6 +314,42 @@ static apt_bool_t mrcp_recog_header_parse(mrcp_recog_header_t *recog_header, apr case RECOGNIZER_HEADER_EARLY_NO_MATCH: apt_boolean_value_parse(value,&recog_header->early_no_match); break; + case RECOGNIZER_HEADER_NUM_MIN_CONSISTENT_PRONUNCIATIONS: + recog_header->num_min_consistent_pronunciations = apt_size_value_parse(value); + break; + case RECOGNIZER_HEADER_CONSISTENCY_THRESHOLD: + recog_header->consistency_threshold = apt_float_value_parse(value); + break; + case RECOGNIZER_HEADER_CLASH_THRESHOLD: + recog_header->clash_threshold = apt_float_value_parse(value); + break; + case RECOGNIZER_HEADER_PERSONAL_GRAMMAR_URI: + recog_header->personal_grammar_uri = *value; + break; + case RECOGNIZER_HEADER_ENROLL_UTTERANCE: + apt_boolean_value_parse(value,&recog_header->enroll_utterance); + break; + case RECOGNIZER_HEADER_PHRASE_ID: + recog_header->phrase_id = *value; + break; + case RECOGNIZER_HEADER_PHRASE_NL: + recog_header->phrase_nl = *value; + break; + case RECOGNIZER_HEADER_WEIGHT: + recog_header->weight = apt_float_value_parse(value); + break; + case RECOGNIZER_HEADER_SAVE_BEST_WAVEFORM: + apt_boolean_value_parse(value,&recog_header->save_best_waveform); + break; + case RECOGNIZER_HEADER_NEW_PHRASE_ID: + recog_header->new_phrase_id = *value; + break; + case RECOGNIZER_HEADER_CONFUSABLE_PHRASES_URI: + recog_header->confusable_phrases_uri = *value; + break; + case RECOGNIZER_HEADER_ABORT_PHRASE_ENROLLMENT: + apt_boolean_value_parse(value,&recog_header->abort_phrase_enrollment); + break; default: status = FALSE; } @@ -288,10 +362,10 @@ static APR_INLINE float apt_size_value_parse_as_float(const apt_str_t *value) return f / 100; } -static APR_INLINE apt_bool_t apt_size_value_generate_from_float(float value, apt_text_stream_t *stream) +static APR_INLINE apt_bool_t apt_size_value_generate_from_float(float value, apt_str_t *str, apr_pool_t *pool) { apr_size_t s = (apr_size_t)((value + 0.001f) * 100); - return apt_size_value_generate(s,stream); + return apt_size_value_generate(s,str,pool); } /** Parse MRCPv1 recognizer header */ @@ -333,95 +407,133 @@ static apt_bool_t mrcp_v2_recog_header_parse(mrcp_header_accessor_t *accessor, a } /** Generate MRCP recognizer header */ -static apt_bool_t mrcp_recog_header_generate(mrcp_recog_header_t *recog_header, apr_size_t id, apt_text_stream_t *value) +static apt_bool_t mrcp_recog_header_generate(const mrcp_recog_header_t *recog_header, apr_size_t id, apt_str_t *value, apr_pool_t *pool) { switch(id) { case RECOGNIZER_HEADER_N_BEST_LIST_LENGTH: - apt_size_value_generate(recog_header->n_best_list_length,value); + apt_size_value_generate(recog_header->n_best_list_length,value,pool); break; case RECOGNIZER_HEADER_NO_INPUT_TIMEOUT: - apt_size_value_generate(recog_header->no_input_timeout,value); + apt_size_value_generate(recog_header->no_input_timeout,value,pool); break; case RECOGNIZER_HEADER_RECOGNITION_TIMEOUT: - apt_size_value_generate(recog_header->recognition_timeout,value); + apt_size_value_generate(recog_header->recognition_timeout,value,pool); break; case RECOGNIZER_HEADER_WAVEFORM_URI: - apt_string_value_generate(&recog_header->waveform_uri,value); + *value = recog_header->waveform_uri; break; case RECOGNIZER_HEADER_RECOGNIZER_CONTEXT_BLOCK: - apt_string_value_generate(&recog_header->recognizer_context_block,value); + *value = recog_header->recognizer_context_block; break; case RECOGNIZER_HEADER_START_INPUT_TIMERS: - apt_boolean_value_generate(recog_header->start_input_timers,value); + apt_boolean_value_generate(recog_header->start_input_timers,value,pool); break; case RECOGNIZER_HEADER_SPEECH_COMPLETE_TIMEOUT: - apt_size_value_generate(recog_header->speech_complete_timeout,value); + apt_size_value_generate(recog_header->speech_complete_timeout,value,pool); break; case RECOGNIZER_HEADER_SPEECH_INCOMPLETE_TIMEOUT: - apt_size_value_generate(recog_header->speech_incomplete_timeout,value); + apt_size_value_generate(recog_header->speech_incomplete_timeout,value,pool); break; case RECOGNIZER_HEADER_DTMF_INTERDIGIT_TIMEOUT: - apt_size_value_generate(recog_header->dtmf_interdigit_timeout,value); + apt_size_value_generate(recog_header->dtmf_interdigit_timeout,value,pool); break; case RECOGNIZER_HEADER_DTMF_TERM_TIMEOUT: - apt_size_value_generate(recog_header->dtmf_term_timeout,value); + apt_size_value_generate(recog_header->dtmf_term_timeout,value,pool); break; case RECOGNIZER_HEADER_DTMF_TERM_CHAR: - *value->pos++ = recog_header->dtmf_term_char; + value->length = 1; + value->buf = apr_palloc(pool,value->length); + *value->buf = recog_header->dtmf_term_char; break; case RECOGNIZER_HEADER_FAILED_URI: - apt_string_value_generate(&recog_header->failed_uri,value); + *value = recog_header->failed_uri; break; case RECOGNIZER_HEADER_FAILED_URI_CAUSE: - apt_string_value_generate(&recog_header->failed_uri_cause,value); + *value = recog_header->failed_uri_cause; break; case RECOGNIZER_HEADER_SAVE_WAVEFORM: - apt_boolean_value_generate(recog_header->save_waveform,value); + apt_boolean_value_generate(recog_header->save_waveform,value,pool); break; case RECOGNIZER_HEADER_NEW_AUDIO_CHANNEL: - apt_boolean_value_generate(recog_header->new_audio_channel,value); + apt_boolean_value_generate(recog_header->new_audio_channel,value,pool); break; case RECOGNIZER_HEADER_SPEECH_LANGUAGE: - apt_string_value_generate(&recog_header->speech_language,value); + *value = recog_header->speech_language; break; case RECOGNIZER_HEADER_INPUT_TYPE: - apt_string_value_generate(&recog_header->input_type,value); + *value = recog_header->input_type; break; case RECOGNIZER_HEADER_INPUT_WAVEFORM_URI: - apt_string_value_generate(&recog_header->input_waveform_uri,value); + *value = recog_header->input_waveform_uri; break; case RECOGNIZER_HEADER_COMPLETION_REASON: - apt_string_value_generate(&recog_header->completion_reason,value); + *value = recog_header->completion_reason; break; case RECOGNIZER_HEADER_MEDIA_TYPE: - apt_string_value_generate(&recog_header->media_type,value); + *value = recog_header->media_type; break; case RECOGNIZER_HEADER_VER_BUFFER_UTTERANCE: - apt_boolean_value_generate(recog_header->ver_buffer_utterance,value); + apt_boolean_value_generate(recog_header->ver_buffer_utterance,value,pool); break; case RECOGNIZER_HEADER_RECOGNITION_MODE: - apt_string_value_generate(&recog_header->recognition_mode,value); + *value = recog_header->recognition_mode; break; case RECOGNIZER_HEADER_CANCEL_IF_QUEUE: - apt_boolean_value_generate(recog_header->cancel_if_queue,value); + apt_boolean_value_generate(recog_header->cancel_if_queue,value,pool); break; case RECOGNIZER_HEADER_HOTWORD_MAX_DURATION: - apt_size_value_generate(recog_header->hotword_max_duration,value); + apt_size_value_generate(recog_header->hotword_max_duration,value,pool); break; case RECOGNIZER_HEADER_HOTWORD_MIN_DURATION: - apt_size_value_generate(recog_header->hotword_min_duration,value); + apt_size_value_generate(recog_header->hotword_min_duration,value,pool); break; case RECOGNIZER_HEADER_INTERPRET_TEXT: - apt_string_value_generate(&recog_header->interpret_text,value); + *value = recog_header->interpret_text; break; case RECOGNIZER_HEADER_DTMF_BUFFER_TIME: - apt_size_value_generate(recog_header->dtmf_buffer_time,value); + apt_size_value_generate(recog_header->dtmf_buffer_time,value,pool); break; case RECOGNIZER_HEADER_CLEAR_DTMF_BUFFER: - apt_boolean_value_generate(recog_header->clear_dtmf_buffer,value); + apt_boolean_value_generate(recog_header->clear_dtmf_buffer,value,pool); break; case RECOGNIZER_HEADER_EARLY_NO_MATCH: - apt_boolean_value_generate(recog_header->early_no_match,value); + apt_boolean_value_generate(recog_header->early_no_match,value,pool); + break; + case RECOGNIZER_HEADER_NUM_MIN_CONSISTENT_PRONUNCIATIONS: + apt_size_value_generate(recog_header->num_min_consistent_pronunciations,value,pool); + break; + case RECOGNIZER_HEADER_CONSISTENCY_THRESHOLD: + apt_float_value_generate(recog_header->consistency_threshold,value,pool); + break; + case RECOGNIZER_HEADER_CLASH_THRESHOLD: + apt_float_value_generate(recog_header->clash_threshold,value,pool); + break; + case RECOGNIZER_HEADER_PERSONAL_GRAMMAR_URI: + *value = recog_header->personal_grammar_uri; + break; + case RECOGNIZER_HEADER_ENROLL_UTTERANCE: + apt_boolean_value_generate(recog_header->enroll_utterance,value,pool); + break; + case RECOGNIZER_HEADER_PHRASE_ID: + *value = recog_header->phrase_id; + break; + case RECOGNIZER_HEADER_PHRASE_NL: + *value = recog_header->phrase_nl; + break; + case RECOGNIZER_HEADER_WEIGHT: + apt_float_value_generate(recog_header->weight,value,pool); + break; + case RECOGNIZER_HEADER_SAVE_BEST_WAVEFORM: + apt_boolean_value_generate(recog_header->save_best_waveform,value,pool); + break; + case RECOGNIZER_HEADER_NEW_PHRASE_ID: + *value = recog_header->new_phrase_id; + break; + case RECOGNIZER_HEADER_CONFUSABLE_PHRASES_URI: + *value = recog_header->confusable_phrases_uri; + break; + case RECOGNIZER_HEADER_ABORT_PHRASE_ENROLLMENT: + apt_boolean_value_generate(recog_header->abort_phrase_enrollment,value,pool); break; default: break; @@ -430,53 +542,55 @@ static apt_bool_t mrcp_recog_header_generate(mrcp_recog_header_t *recog_header, } /** Generate MRCPv1 recognizer header */ -static apt_bool_t mrcp_v1_recog_header_generate(mrcp_header_accessor_t *accessor, apr_size_t id, apt_text_stream_t *value) +static apt_bool_t mrcp_v1_recog_header_generate(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_str_t *value, apr_pool_t *pool) { mrcp_recog_header_t *recog_header = accessor->data; if(id == RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD) { - return apt_size_value_generate_from_float(recog_header->confidence_threshold,value); + return apt_size_value_generate_from_float(recog_header->confidence_threshold,value,pool); } else if(id == RECOGNIZER_HEADER_SENSITIVITY_LEVEL) { - return apt_size_value_generate_from_float(recog_header->sensitivity_level,value); + return apt_size_value_generate_from_float(recog_header->sensitivity_level,value,pool); } else if(id == RECOGNIZER_HEADER_SPEED_VS_ACCURACY) { - return apt_size_value_generate_from_float(recog_header->speed_vs_accuracy,value); + return apt_size_value_generate_from_float(recog_header->speed_vs_accuracy,value,pool); } else if(id == RECOGNIZER_HEADER_COMPLETION_CAUSE) { - return mrcp_completion_cause_generate( + return apt_completion_cause_generate( v1_completion_cause_string_table, RECOGNIZER_COMPLETION_CAUSE_COUNT, recog_header->completion_cause, - value); + value, + pool); } - return mrcp_recog_header_generate(recog_header,id,value); + return mrcp_recog_header_generate(recog_header,id,value,pool); } /** Generate MRCPv2 recognizer header */ -static apt_bool_t mrcp_v2_recog_header_generate(mrcp_header_accessor_t *accessor, apr_size_t id, apt_text_stream_t *value) +static apt_bool_t mrcp_v2_recog_header_generate(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_str_t *value, apr_pool_t *pool) { mrcp_recog_header_t *recog_header = accessor->data; if(id == RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD) { - return apt_float_value_generate(recog_header->confidence_threshold,value); + return apt_float_value_generate(recog_header->confidence_threshold,value,pool); } else if(id == RECOGNIZER_HEADER_SENSITIVITY_LEVEL) { - return apt_float_value_generate(recog_header->sensitivity_level,value); + return apt_float_value_generate(recog_header->sensitivity_level,value,pool); } else if(id == RECOGNIZER_HEADER_SPEED_VS_ACCURACY) { - return apt_float_value_generate(recog_header->speed_vs_accuracy,value); + return apt_float_value_generate(recog_header->speed_vs_accuracy,value,pool); } else if(id == RECOGNIZER_HEADER_COMPLETION_CAUSE) { - return mrcp_completion_cause_generate( + return apt_completion_cause_generate( v2_completion_cause_string_table, RECOGNIZER_COMPLETION_CAUSE_COUNT, recog_header->completion_cause, - value); + value, + pool); } - return mrcp_recog_header_generate(recog_header,id,value); + return mrcp_recog_header_generate(recog_header,id,value,pool); } /** Duplicate MRCP recognizer header */ -static apt_bool_t mrcp_recog_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, apr_pool_t *pool) +static apt_bool_t mrcp_recog_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, const apt_str_t *value, apr_pool_t *pool) { mrcp_recog_header_t *recog_header = accessor->data; const mrcp_recog_header_t *src_recog_header = src->data; @@ -506,13 +620,13 @@ static apt_bool_t mrcp_recog_header_duplicate(mrcp_header_accessor_t *accessor, recog_header->recognition_timeout = src_recog_header->recognition_timeout; break; case RECOGNIZER_HEADER_WAVEFORM_URI: - apt_string_copy(&recog_header->waveform_uri,&src_recog_header->waveform_uri,pool); + recog_header->waveform_uri = *value; break; case RECOGNIZER_HEADER_COMPLETION_CAUSE: recog_header->completion_cause = src_recog_header->completion_cause; break; case RECOGNIZER_HEADER_RECOGNIZER_CONTEXT_BLOCK: - apt_string_copy(&recog_header->recognizer_context_block,&src_recog_header->recognizer_context_block,pool); + recog_header->recognizer_context_block = *value; break; case RECOGNIZER_HEADER_START_INPUT_TIMERS: recog_header->start_input_timers = src_recog_header->start_input_timers; @@ -533,10 +647,10 @@ static apt_bool_t mrcp_recog_header_duplicate(mrcp_header_accessor_t *accessor, recog_header->dtmf_term_char = src_recog_header->dtmf_term_char; break; case RECOGNIZER_HEADER_FAILED_URI: - apt_string_copy(&recog_header->failed_uri,&src_recog_header->failed_uri,pool); + recog_header->failed_uri = *value; break; case RECOGNIZER_HEADER_FAILED_URI_CAUSE: - apt_string_copy(&recog_header->failed_uri_cause,&src_recog_header->failed_uri_cause,pool); + recog_header->failed_uri_cause = *value; break; case RECOGNIZER_HEADER_SAVE_WAVEFORM: recog_header->save_waveform = src_recog_header->save_waveform; @@ -545,25 +659,25 @@ static apt_bool_t mrcp_recog_header_duplicate(mrcp_header_accessor_t *accessor, recog_header->new_audio_channel = src_recog_header->new_audio_channel; break; case RECOGNIZER_HEADER_SPEECH_LANGUAGE: - apt_string_copy(&recog_header->speech_language,&src_recog_header->speech_language,pool); + recog_header->speech_language = *value; break; case RECOGNIZER_HEADER_INPUT_TYPE: - apt_string_copy(&recog_header->input_type,&src_recog_header->input_type,pool); + recog_header->input_type = *value; break; case RECOGNIZER_HEADER_INPUT_WAVEFORM_URI: - apt_string_copy(&recog_header->input_waveform_uri,&src_recog_header->input_waveform_uri,pool); + recog_header->input_waveform_uri = *value; break; case RECOGNIZER_HEADER_COMPLETION_REASON: - apt_string_copy(&recog_header->completion_reason,&src_recog_header->completion_reason,pool); + recog_header->completion_reason = *value; break; case RECOGNIZER_HEADER_MEDIA_TYPE: - apt_string_copy(&recog_header->media_type,&src_recog_header->media_type,pool); + recog_header->media_type = *value; break; case RECOGNIZER_HEADER_VER_BUFFER_UTTERANCE: recog_header->ver_buffer_utterance = src_recog_header->ver_buffer_utterance; break; case RECOGNIZER_HEADER_RECOGNITION_MODE: - apt_string_copy(&recog_header->recognition_mode,&src_recog_header->recognition_mode,pool); + recog_header->recognition_mode = *value; break; case RECOGNIZER_HEADER_CANCEL_IF_QUEUE: recog_header->cancel_if_queue = src_recog_header->cancel_if_queue; @@ -575,7 +689,7 @@ static apt_bool_t mrcp_recog_header_duplicate(mrcp_header_accessor_t *accessor, recog_header->hotword_min_duration = src_recog_header->hotword_min_duration; break; case RECOGNIZER_HEADER_INTERPRET_TEXT: - apt_string_copy(&recog_header->interpret_text,&src_recog_header->interpret_text,pool); + recog_header->interpret_text = *value; break; case RECOGNIZER_HEADER_DTMF_BUFFER_TIME: recog_header->dtmf_buffer_time = src_recog_header->dtmf_buffer_time; @@ -586,20 +700,48 @@ static apt_bool_t mrcp_recog_header_duplicate(mrcp_header_accessor_t *accessor, case RECOGNIZER_HEADER_EARLY_NO_MATCH: recog_header->early_no_match = src_recog_header->early_no_match; break; + case RECOGNIZER_HEADER_NUM_MIN_CONSISTENT_PRONUNCIATIONS: + recog_header->num_min_consistent_pronunciations = src_recog_header->num_min_consistent_pronunciations; + break; + case RECOGNIZER_HEADER_CONSISTENCY_THRESHOLD: + recog_header->consistency_threshold = src_recog_header->consistency_threshold; + break; + case RECOGNIZER_HEADER_CLASH_THRESHOLD: + recog_header->clash_threshold = src_recog_header->clash_threshold; + break; + case RECOGNIZER_HEADER_PERSONAL_GRAMMAR_URI: + recog_header->personal_grammar_uri = *value; + break; + case RECOGNIZER_HEADER_ENROLL_UTTERANCE: + recog_header->enroll_utterance = src_recog_header->enroll_utterance; + break; + case RECOGNIZER_HEADER_PHRASE_ID: + recog_header->phrase_id = *value; + break; + case RECOGNIZER_HEADER_PHRASE_NL: + recog_header->phrase_nl = *value; + break; + case RECOGNIZER_HEADER_WEIGHT: + recog_header->weight = src_recog_header->weight; + break; + case RECOGNIZER_HEADER_SAVE_BEST_WAVEFORM: + recog_header->save_best_waveform = src_recog_header->save_best_waveform; + break; + case RECOGNIZER_HEADER_NEW_PHRASE_ID: + recog_header->new_phrase_id = *value; + break; + case RECOGNIZER_HEADER_CONFUSABLE_PHRASES_URI: + recog_header->confusable_phrases_uri = *value; + break; + case RECOGNIZER_HEADER_ABORT_PHRASE_ENROLLMENT: + recog_header->abort_phrase_enrollment = src_recog_header->abort_phrase_enrollment; + break; default: status = FALSE; } return status; } -static APR_INLINE const apt_str_table_item_t* recog_header_string_table_get(mrcp_version_e version) -{ - if(version == MRCP_VERSION_1) { - return v1_recog_header_string_table; - } - return v2_recog_header_string_table; -} - static const mrcp_header_vtable_t v1_vtable = { mrcp_recog_header_allocate, NULL, /* nothing to destroy */ diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_resource.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_resource.c index bf9dc56f3a..108e1f638a 100644 --- a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_resource.c +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_resource.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recog_resource.c 1781 2010-09-01 07:33:00Z achaloyan $ */ #include "mrcp_recog_resource.h" @@ -22,34 +24,48 @@ static const apt_str_table_item_t v1_recog_method_string_table[] = { {{"SET-PARAMS", 10},10}, {{"GET-PARAMS", 10},10}, - {{"DEFINE-GRAMMAR", 14},0}, + {{"DEFINE-GRAMMAR", 14},2}, {{"RECOGNIZE", 9},7}, - {{"GET-RESULT", 10},4}, + {{"INTERPRET", 9},0}, + {{"GET-RESULT", 10},6}, {{"RECOGNITION-START-TIMERS", 24},7}, - {{"STOP", 4},1} + {{"STOP", 4},2}, + {{"START-PHRASE-ENROLLMENT", 23},2}, + {{"ENROLLMENT-ROLLBACK", 19},2}, + {{"END-PHRASE-ENROLLMENT", 21},5}, + {{"MODIFY-PHRASE", 13},0}, + {{"DELETE-PHRASE", 13},2} }; -/** String table of mrcpv2 recognizer methods (mrcp_recognizer_method_id) */ +/** String table of MRCPv2 recognizer methods (mrcp_recognizer_method_id) */ static const apt_str_table_item_t v2_recog_method_string_table[] = { {{"SET-PARAMS", 10},10}, {{"GET-PARAMS", 10},10}, - {{"DEFINE-GRAMMAR", 14},0}, - {{"RECOGNIZE", 9},7}, - {{"GET-RESULT", 10},4}, - {{"START-INPUT-TIMERS", 18},2}, - {{"STOP", 4},2} + {{"DEFINE-GRAMMAR", 14},2}, + {{"RECOGNIZE", 9},0}, + {{"INTERPRET", 9},0}, + {{"GET-RESULT", 10},6}, + {{"START-INPUT-TIMERS", 18},7}, + {{"STOP", 4},2}, + {{"START-PHRASE-ENROLLMENT", 23},6}, + {{"ENROLLMENT-ROLLBACK", 19},2}, + {{"END-PHRASE-ENROLLMENT", 21},5}, + {{"MODIFY-PHRASE", 13},0}, + {{"DELETE-PHRASE", 13},2} }; /** String table of MRCP recognizer events (mrcp_recognizer_event_id) */ static const apt_str_table_item_t v1_recog_event_string_table[] = { {{"START-OF-SPEECH", 15},0}, - {{"RECOGNITION-COMPLETE", 20},0} + {{"RECOGNITION-COMPLETE", 20},0}, + {{"INTERPRETATION-COMPLETE", 23},0} }; -/** String table of mrcpv2 recognizer events (mrcp_recognizer_event_id) */ +/** String table of MRCPv2 recognizer events (mrcp_recognizer_event_id) */ static const apt_str_table_item_t v2_recog_event_string_table[] = { {{"START-OF-INPUT", 14},0}, - {{"RECOGNITION-COMPLETE", 20},0} + {{"RECOGNITION-COMPLETE", 20},0}, + {{"INTERPRETATION-COMPLETE", 23},0} }; diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_header.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_header.c index 34902c12c8..fdfea41373 100644 --- a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_header.c +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_header.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,11 +12,13 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recorder_header.c 1632 2010-03-30 20:46:25Z achaloyan $ */ #include "mrcp_recorder_header.h" -/** String table of recorder headers (mrcp_recorder_header_id) */ +/** String table of recorder header fields (mrcp_recorder_header_id) */ static const apt_str_table_item_t recorder_header_string_table[] = { {{"Sensitivity-Level", 17},3}, {{"No-Input-Timeout", 16},2}, @@ -90,19 +92,19 @@ static apt_bool_t mrcp_recorder_header_parse(mrcp_header_accessor_t *accessor, a recorder_header->completion_cause = apt_size_value_parse(value); break; case RECORDER_HEADER_COMPLETION_REASON: - apt_string_copy(&recorder_header->completion_reason,value,pool); + recorder_header->completion_reason = *value; break; case RECORDER_HEADER_FAILED_URI: - apt_string_copy(&recorder_header->failed_uri,value,pool); + recorder_header->failed_uri = *value; break; case RECORDER_HEADER_FAILED_URI_CAUSE: - apt_string_copy(&recorder_header->failed_uri_cause,value,pool); + recorder_header->failed_uri_cause = *value; break; case RECORDER_HEADER_RECORD_URI: - apt_string_copy(&recorder_header->record_uri,value,pool); + recorder_header->record_uri = *value; break; case RECORDER_HEADER_MEDIA_TYPE: - apt_string_copy(&recorder_header->media_type,value,pool); + recorder_header->media_type = *value; break; case RECORDER_HEADER_MAX_TIME: recorder_header->max_time = apt_size_value_parse(value); @@ -132,60 +134,61 @@ static apt_bool_t mrcp_recorder_header_parse(mrcp_header_accessor_t *accessor, a } /** Generate MRCP recorder header */ -static apt_bool_t mrcp_recorder_header_generate(mrcp_header_accessor_t *accessor, apr_size_t id, apt_text_stream_t *value) +static apt_bool_t mrcp_recorder_header_generate(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_str_t *value, apr_pool_t *pool) { mrcp_recorder_header_t *recorder_header = accessor->data; switch(id) { case RECORDER_HEADER_SENSITIVITY_LEVEL: - apt_float_value_generate(recorder_header->sensitivity_level,value); + apt_float_value_generate(recorder_header->sensitivity_level,value,pool); break; case RECORDER_HEADER_NO_INPUT_TIMEOUT: - apt_size_value_generate(recorder_header->no_input_timeout,value); + apt_size_value_generate(recorder_header->no_input_timeout,value,pool); break; case RECORDER_HEADER_COMPLETION_CAUSE: { - mrcp_completion_cause_generate( + apt_completion_cause_generate( completion_cause_string_table, RECORDER_COMPLETION_CAUSE_COUNT, recorder_header->completion_cause, - value); + value, + pool); break; } case RECORDER_HEADER_COMPLETION_REASON: - apt_string_value_generate(&recorder_header->completion_reason,value); + *value = recorder_header->completion_reason; break; case RECORDER_HEADER_FAILED_URI: - apt_string_value_generate(&recorder_header->failed_uri,value); + *value = recorder_header->failed_uri; break; case RECORDER_HEADER_FAILED_URI_CAUSE: - apt_string_value_generate(&recorder_header->failed_uri_cause,value); + *value = recorder_header->failed_uri_cause; break; case RECORDER_HEADER_RECORD_URI: - apt_string_value_generate(&recorder_header->record_uri,value); + *value = recorder_header->record_uri; break; case RECORDER_HEADER_MEDIA_TYPE: - apt_string_value_generate(&recorder_header->media_type,value); + *value = recorder_header->media_type; break; case RECORDER_HEADER_MAX_TIME: - apt_size_value_generate(recorder_header->max_time,value); + apt_size_value_generate(recorder_header->max_time,value,pool); break; case RECORDER_HEADER_TRIM_LENGTH: - apt_size_value_generate(recorder_header->trim_length,value); + apt_size_value_generate(recorder_header->trim_length,value,pool); break; case RECORDER_HEADER_FINAL_SILENCE: - apt_size_value_generate(recorder_header->final_silence,value); + apt_size_value_generate(recorder_header->final_silence,value,pool); break; case RECORDER_HEADER_CAPTURE_ON_SPEECH: - apt_boolean_value_generate(recorder_header->capture_on_speech,value); + apt_boolean_value_generate(recorder_header->capture_on_speech,value,pool); break; case RECORDER_HEADER_VER_BUFFER_UTTERANCE: - apt_boolean_value_generate(recorder_header->ver_buffer_utterance,value); + apt_boolean_value_generate(recorder_header->ver_buffer_utterance,value,pool); break; case RECORDER_HEADER_START_INPUT_TIMERS: - apt_boolean_value_generate(recorder_header->start_input_timers,value); + apt_boolean_value_generate(recorder_header->start_input_timers,value,pool); break; case RECORDER_HEADER_NEW_AUDIO_CHANNEL: - apt_boolean_value_generate(recorder_header->new_audio_channel,value); + apt_boolean_value_generate(recorder_header->new_audio_channel,value,pool); break; default: break; @@ -194,7 +197,7 @@ static apt_bool_t mrcp_recorder_header_generate(mrcp_header_accessor_t *accessor } /** Duplicate MRCP recorder header */ -static apt_bool_t mrcp_recorder_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, apr_pool_t *pool) +static apt_bool_t mrcp_recorder_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, const apt_str_t *value, apr_pool_t *pool) { mrcp_recorder_header_t *recorder_header = accessor->data; const mrcp_recorder_header_t *src_recorder_header = src->data; @@ -215,19 +218,19 @@ static apt_bool_t mrcp_recorder_header_duplicate(mrcp_header_accessor_t *accesso recorder_header->completion_cause = src_recorder_header->completion_cause; break; case RECORDER_HEADER_COMPLETION_REASON: - apt_string_copy(&recorder_header->completion_reason,&src_recorder_header->completion_reason,pool); + recorder_header->completion_reason = *value; break; case RECORDER_HEADER_FAILED_URI: - apt_string_copy(&recorder_header->failed_uri,&src_recorder_header->failed_uri,pool); + recorder_header->failed_uri = *value; break; case RECORDER_HEADER_FAILED_URI_CAUSE: - apt_string_copy(&recorder_header->failed_uri_cause,&src_recorder_header->failed_uri_cause,pool); + recorder_header->failed_uri_cause = *value; break; case RECORDER_HEADER_RECORD_URI: - apt_string_copy(&recorder_header->record_uri,&src_recorder_header->record_uri,pool); + recorder_header->record_uri = *value; break; case RECORDER_HEADER_MEDIA_TYPE: - apt_string_copy(&recorder_header->media_type,&src_recorder_header->media_type,pool); + recorder_header->media_type = *value; break; case RECORDER_HEADER_MAX_TIME: recorder_header->max_time = src_recorder_header->max_time; diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_resource.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_resource.c index edb047c5a9..24254c1a7c 100644 --- a/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_resource.c +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_recorder_resource.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_recorder_resource.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mrcp_recorder_resource.h" diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_header.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_header.c index 51ec8667c7..45b88087d3 100644 --- a/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_header.c +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_header.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,11 +12,13 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_synth_header.c 1632 2010-03-30 20:46:25Z achaloyan $ */ #include "mrcp_synth_header.h" -/** String table of MRCP synthesizer headers (mrcp_synthesizer_header_id) */ +/** String table of MRCP synthesizer header fields (mrcp_synthesizer_header_id) */ static const apt_str_table_item_t synth_header_string_table[] = { {{"Jump-Size", 9},0}, {{"Kill-On-Barge-In", 16},0}, @@ -95,7 +97,7 @@ static APR_INLINE apr_size_t apt_string_table_value_parse(const apt_str_table_it return apt_string_table_id_find(string_table,count,value); } -static apt_bool_t apt_string_table_value_generate(const apt_str_table_item_t *string_table, size_t count, size_t id, apt_text_stream_t *stream) +static apt_bool_t apt_string_table_value_generate(const apt_str_table_item_t *string_table, apr_size_t count, apr_size_t id, apt_text_stream_t *stream) { const apt_str_t *name = apt_string_table_str_get(string_table,count,id); if(!name) { @@ -107,6 +109,17 @@ static apt_bool_t apt_string_table_value_generate(const apt_str_table_item_t *st return TRUE; } +static apt_bool_t apt_string_table_value_pgenerate(const apt_str_table_item_t *string_table, apr_size_t count, apr_size_t id, apt_str_t *str, apr_pool_t *pool) +{ + const apt_str_t *name = apt_string_table_str_get(string_table,count,id); + if(!name) { + return FALSE; + } + + apt_string_copy(str,name,pool); + return TRUE; +} + /** Parse MRCP prosody-rate value */ static apt_bool_t mrcp_prosody_param_rate_parse(mrcp_prosody_rate_t *prosody_rate, const apt_str_t *value, apr_pool_t *pool) { @@ -133,13 +146,18 @@ static apt_bool_t mrcp_prosody_param_rate_parse(mrcp_prosody_rate_t *prosody_rat } /** Generate MRCP prosody-rate value */ -static apt_bool_t mrcp_prosody_rate_generate(mrcp_prosody_rate_t *prosody_rate, apt_text_stream_t *stream) +static apt_bool_t mrcp_prosody_rate_generate(mrcp_prosody_rate_t *prosody_rate, apt_str_t *str, apr_pool_t *pool) { if(prosody_rate->type == PROSODY_RATE_TYPE_LABEL) { - apt_string_table_value_generate(prosody_rate_string_table,PROSODY_RATE_COUNT,prosody_rate->value.label,stream); + apt_string_table_value_pgenerate( + prosody_rate_string_table, + PROSODY_RATE_COUNT, + prosody_rate->value.label, + str, + pool); } else { - apt_float_value_generate(prosody_rate->value.relative, stream); + apt_float_value_generate(prosody_rate->value.relative,str,pool); } return TRUE; @@ -177,16 +195,21 @@ static apt_bool_t mrcp_prosody_param_volume_parse(mrcp_prosody_volume_t *prosody } /** Generate MRCP prosody-volume value */ -static apt_bool_t mrcp_prosody_volume_generate(mrcp_prosody_volume_t *prosody_volume, apt_text_stream_t *stream) +static apt_bool_t mrcp_prosody_volume_generate(mrcp_prosody_volume_t *prosody_volume, apt_str_t *str, apr_pool_t *pool) { if(prosody_volume->type == PROSODY_VOLUME_TYPE_LABEL) { - apt_string_table_value_generate(prosody_volume_string_table,PROSODY_VOLUME_COUNT,prosody_volume->value.label,stream); + apt_string_table_value_pgenerate( + prosody_volume_string_table, + PROSODY_VOLUME_COUNT, + prosody_volume->value.label, + str, + pool); } else if (prosody_volume->type == PROSODY_VOLUME_TYPE_NUMERIC) { - apt_float_value_generate(prosody_volume->value.numeric, stream); + apt_float_value_generate(prosody_volume->value.numeric,str,pool); } else { - apt_float_value_generate(prosody_volume->value.relative, stream); + apt_float_value_generate(prosody_volume->value.relative,str,pool); } return TRUE; @@ -229,25 +252,29 @@ static apt_bool_t mrcp_speech_length_value_parse(mrcp_speech_length_value_t *spe } /** Generate MRCP speech-length value */ -static apt_bool_t mrcp_speech_length_generate(mrcp_speech_length_value_t *speech_length, apt_text_stream_t *stream) +static apt_bool_t mrcp_speech_length_generate(mrcp_speech_length_value_t *speech_length, apt_str_t *str, apr_pool_t *pool) { if(speech_length->type == SPEECH_LENGTH_TYPE_TEXT) { apt_str_t *tag = &speech_length->value.tag; if(tag->length) { - memcpy(stream->pos,tag->buf,tag->length); - stream->pos += tag->length; + apt_string_copy(str,tag,pool); } } else { + char buf[256]; + apt_text_stream_t stream; + apt_text_stream_init(&stream,buf,sizeof(buf)); if(speech_length->type == SPEECH_LENGTH_TYPE_NUMERIC_POSITIVE) { - *stream->pos++ = '+'; + *stream.pos++ = '+'; } else { - *stream->pos++ = '-'; + *stream.pos++ = '-'; } - apt_size_value_generate(speech_length->value.numeric.length,stream); - *stream->pos++ = ' '; - apt_string_table_value_generate(speech_unit_string_table,SPEECH_UNIT_COUNT,speech_length->value.numeric.unit,stream); + apt_text_size_value_insert(&stream,speech_length->value.numeric.length); + *stream.pos++ = APT_TOKEN_SP; + apt_string_table_value_generate(speech_unit_string_table,SPEECH_UNIT_COUNT,speech_length->value.numeric.unit,&stream); + + apt_string_assign_n(str,stream.text.buf, stream.pos - stream.text.buf, pool); } return TRUE; } @@ -301,13 +328,13 @@ static apt_bool_t mrcp_synth_header_parse(mrcp_header_accessor_t *accessor, size apt_boolean_value_parse(value,&synth_header->kill_on_barge_in); break; case SYNTHESIZER_HEADER_SPEAKER_PROFILE: - apt_string_copy(&synth_header->speaker_profile,value,pool); + synth_header->speaker_profile = *value; break; case SYNTHESIZER_HEADER_COMPLETION_CAUSE: synth_header->completion_cause = apt_size_value_parse(value); break; case SYNTHESIZER_HEADER_COMPLETION_REASON: - apt_string_copy(&synth_header->completion_reason,value,pool); + synth_header->completion_reason = *value; break; case SYNTHESIZER_HEADER_VOICE_GENDER: synth_header->voice_param.gender = apt_string_table_value_parse(voice_gender_string_table,VOICE_GENDER_COUNT,value); @@ -319,7 +346,7 @@ static apt_bool_t mrcp_synth_header_parse(mrcp_header_accessor_t *accessor, size synth_header->voice_param.variant = apt_size_value_parse(value); break; case SYNTHESIZER_HEADER_VOICE_NAME: - apt_string_copy(&synth_header->voice_param.name,value,pool); + synth_header->voice_param.name = *value; break; case SYNTHESIZER_HEADER_PROSODY_VOLUME: mrcp_prosody_param_volume_parse(&synth_header->prosody_param.volume,value,pool); @@ -328,22 +355,22 @@ static apt_bool_t mrcp_synth_header_parse(mrcp_header_accessor_t *accessor, size mrcp_prosody_param_rate_parse(&synth_header->prosody_param.rate,value,pool); break; case SYNTHESIZER_HEADER_SPEECH_MARKER: - apt_string_copy(&synth_header->speech_marker,value,pool); + synth_header->speech_marker = *value; break; case SYNTHESIZER_HEADER_SPEECH_LANGUAGE: - apt_string_copy(&synth_header->speech_language,value,pool); + synth_header->speech_language = *value; break; case SYNTHESIZER_HEADER_FETCH_HINT: - apt_string_copy(&synth_header->fetch_hint,value,pool); + synth_header->fetch_hint = *value; break; case SYNTHESIZER_HEADER_AUDIO_FETCH_HINT: - apt_string_copy(&synth_header->audio_fetch_hint,value,pool); + synth_header->audio_fetch_hint = *value; break; case SYNTHESIZER_HEADER_FAILED_URI: - apt_string_copy(&synth_header->failed_uri,value,pool); + synth_header->failed_uri = *value; break; case SYNTHESIZER_HEADER_FAILED_URI_CAUSE: - apt_string_copy(&synth_header->failed_uri_cause,value,pool); + synth_header->failed_uri_cause = *value; break; case SYNTHESIZER_HEADER_SPEAK_RESTART: apt_boolean_value_parse(value,&synth_header->speak_restart); @@ -355,7 +382,7 @@ static apt_bool_t mrcp_synth_header_parse(mrcp_header_accessor_t *accessor, size apt_boolean_value_parse(value,&synth_header->load_lexicon); break; case SYNTHESIZER_HEADER_LEXICON_SEARCH_ORDER: - apt_string_copy(&synth_header->lexicon_search_order,value,pool); + synth_header->lexicon_search_order = *value; break; default: status = FALSE; @@ -364,76 +391,82 @@ static apt_bool_t mrcp_synth_header_parse(mrcp_header_accessor_t *accessor, size } /** Generate MRCP synthesizer header */ -static apt_bool_t mrcp_synth_header_generate(mrcp_header_accessor_t *accessor, size_t id, apt_text_stream_t *value) +static apt_bool_t mrcp_synth_header_generate(const mrcp_header_accessor_t *accessor, size_t id, apt_str_t *value, apr_pool_t *pool) { mrcp_synth_header_t *synth_header = accessor->data; switch(id) { case SYNTHESIZER_HEADER_JUMP_SIZE: - mrcp_speech_length_generate(&synth_header->jump_size,value); + mrcp_speech_length_generate(&synth_header->jump_size,value,pool); break; case SYNTHESIZER_HEADER_KILL_ON_BARGE_IN: - apt_boolean_value_generate(synth_header->kill_on_barge_in,value); + apt_boolean_value_generate(synth_header->kill_on_barge_in,value,pool); break; case SYNTHESIZER_HEADER_SPEAKER_PROFILE: - apt_string_value_generate(&synth_header->speaker_profile,value); + *value = synth_header->speaker_profile,value; break; case SYNTHESIZER_HEADER_COMPLETION_CAUSE: - mrcp_completion_cause_generate( + apt_completion_cause_generate( completion_cause_string_table, SYNTHESIZER_COMPLETION_CAUSE_COUNT, synth_header->completion_cause, - value); + value, + pool); break; case SYNTHESIZER_HEADER_COMPLETION_REASON: - apt_string_value_generate(&synth_header->completion_reason,value); + *value = synth_header->completion_reason; break; case SYNTHESIZER_HEADER_VOICE_GENDER: - apt_string_table_value_generate(voice_gender_string_table,VOICE_GENDER_COUNT,synth_header->voice_param.gender,value); + apt_string_table_value_pgenerate( + voice_gender_string_table, + VOICE_GENDER_COUNT, + synth_header->voice_param.gender, + value, + pool); break; case SYNTHESIZER_HEADER_VOICE_AGE: - apt_size_value_generate(synth_header->voice_param.age,value); + apt_size_value_generate(synth_header->voice_param.age,value,pool); break; case SYNTHESIZER_HEADER_VOICE_VARIANT: - apt_size_value_generate(synth_header->voice_param.variant,value); + apt_size_value_generate(synth_header->voice_param.variant,value,pool); break; case SYNTHESIZER_HEADER_VOICE_NAME: - apt_string_value_generate(&synth_header->voice_param.name,value); + *value = synth_header->voice_param.name,value; break; case SYNTHESIZER_HEADER_PROSODY_VOLUME: - mrcp_prosody_volume_generate(&synth_header->prosody_param.volume,value); + mrcp_prosody_volume_generate(&synth_header->prosody_param.volume,value,pool); break; case SYNTHESIZER_HEADER_PROSODY_RATE: - mrcp_prosody_rate_generate(&synth_header->prosody_param.rate,value); + mrcp_prosody_rate_generate(&synth_header->prosody_param.rate,value,pool); break; case SYNTHESIZER_HEADER_SPEECH_MARKER: - apt_string_value_generate(&synth_header->speech_marker,value); + *value = synth_header->speech_marker; break; case SYNTHESIZER_HEADER_SPEECH_LANGUAGE: - apt_string_value_generate(&synth_header->speech_language,value); + *value = synth_header->speech_language; break; case SYNTHESIZER_HEADER_FETCH_HINT: - apt_string_value_generate(&synth_header->fetch_hint,value); + *value = synth_header->fetch_hint; break; case SYNTHESIZER_HEADER_AUDIO_FETCH_HINT: - apt_string_value_generate(&synth_header->audio_fetch_hint,value); + *value = synth_header->audio_fetch_hint; break; case SYNTHESIZER_HEADER_FAILED_URI: - apt_string_value_generate(&synth_header->failed_uri,value); + *value = synth_header->failed_uri; break; case SYNTHESIZER_HEADER_FAILED_URI_CAUSE: - apt_string_value_generate(&synth_header->failed_uri_cause,value); + *value = synth_header->failed_uri_cause; break; case SYNTHESIZER_HEADER_SPEAK_RESTART: - apt_boolean_value_generate(synth_header->speak_restart,value); + apt_boolean_value_generate(synth_header->speak_restart,value,pool); break; case SYNTHESIZER_HEADER_SPEAK_LENGTH: - mrcp_speech_length_generate(&synth_header->speak_length,value); + mrcp_speech_length_generate(&synth_header->speak_length,value,pool); break; case SYNTHESIZER_HEADER_LOAD_LEXICON: - apt_boolean_value_generate(synth_header->load_lexicon,value); + apt_boolean_value_generate(synth_header->load_lexicon,value,pool); break; case SYNTHESIZER_HEADER_LEXICON_SEARCH_ORDER: - apt_string_value_generate(&synth_header->lexicon_search_order,value); + *value = synth_header->lexicon_search_order; break; default: break; @@ -442,7 +475,7 @@ static apt_bool_t mrcp_synth_header_generate(mrcp_header_accessor_t *accessor, s } /** Duplicate MRCP synthesizer header */ -static apt_bool_t mrcp_synth_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, size_t id, apr_pool_t *pool) +static apt_bool_t mrcp_synth_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, size_t id, const apt_str_t *value, apr_pool_t *pool) { mrcp_synth_header_t *synth_header = accessor->data; const mrcp_synth_header_t *src_synth_header = src->data; @@ -460,13 +493,13 @@ static apt_bool_t mrcp_synth_header_duplicate(mrcp_header_accessor_t *accessor, synth_header->kill_on_barge_in = src_synth_header->kill_on_barge_in; break; case SYNTHESIZER_HEADER_SPEAKER_PROFILE: - apt_string_copy(&synth_header->speaker_profile,&src_synth_header->speaker_profile,pool); + synth_header->speaker_profile = *value; break; case SYNTHESIZER_HEADER_COMPLETION_CAUSE: synth_header->completion_cause = src_synth_header->completion_cause; break; case SYNTHESIZER_HEADER_COMPLETION_REASON: - apt_string_copy(&synth_header->completion_reason,&src_synth_header->completion_reason,pool); + synth_header->completion_reason = *value; break; case SYNTHESIZER_HEADER_VOICE_GENDER: synth_header->voice_param.gender = src_synth_header->voice_param.gender; @@ -478,7 +511,7 @@ static apt_bool_t mrcp_synth_header_duplicate(mrcp_header_accessor_t *accessor, synth_header->voice_param.variant = src_synth_header->voice_param.variant; break; case SYNTHESIZER_HEADER_VOICE_NAME: - apt_string_copy(&synth_header->voice_param.name,&src_synth_header->voice_param.name,pool); + synth_header->voice_param.name = *value; break; case SYNTHESIZER_HEADER_PROSODY_VOLUME: synth_header->prosody_param.volume = src_synth_header->prosody_param.volume; @@ -487,22 +520,22 @@ static apt_bool_t mrcp_synth_header_duplicate(mrcp_header_accessor_t *accessor, synth_header->prosody_param.rate = src_synth_header->prosody_param.rate; break; case SYNTHESIZER_HEADER_SPEECH_MARKER: - apt_string_copy(&synth_header->speech_marker,&src_synth_header->speech_marker,pool); + synth_header->speech_marker = *value; break; case SYNTHESIZER_HEADER_SPEECH_LANGUAGE: - apt_string_copy(&synth_header->speech_language,&src_synth_header->speech_language,pool); + synth_header->speech_language = *value; break; case SYNTHESIZER_HEADER_FETCH_HINT: - apt_string_copy(&synth_header->fetch_hint,&src_synth_header->fetch_hint,pool); + synth_header->fetch_hint = *value; break; case SYNTHESIZER_HEADER_AUDIO_FETCH_HINT: - apt_string_copy(&synth_header->audio_fetch_hint,&src_synth_header->audio_fetch_hint,pool); + synth_header->audio_fetch_hint = *value; break; case SYNTHESIZER_HEADER_FAILED_URI: - apt_string_copy(&synth_header->failed_uri,&src_synth_header->failed_uri,pool); + synth_header->failed_uri = *value; break; case SYNTHESIZER_HEADER_FAILED_URI_CAUSE: - apt_string_copy(&synth_header->failed_uri_cause,&src_synth_header->failed_uri_cause,pool); + synth_header->failed_uri_cause = *value; break; case SYNTHESIZER_HEADER_SPEAK_RESTART: synth_header->speak_restart = src_synth_header->speak_restart; @@ -514,7 +547,7 @@ static apt_bool_t mrcp_synth_header_duplicate(mrcp_header_accessor_t *accessor, synth_header->load_lexicon = src_synth_header->load_lexicon; break; case SYNTHESIZER_HEADER_LEXICON_SEARCH_ORDER: - apt_string_copy(&synth_header->lexicon_search_order,&src_synth_header->lexicon_search_order,pool); + synth_header->lexicon_search_order = *value; break; default: status = FALSE; diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_resource.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_resource.c index 702af0a6e5..fb17ce67e1 100644 --- a/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_resource.c +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_resource.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_synth_resource.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "mrcp_synth_resource.h" diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_verifier_header.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_verifier_header.c new file mode 100644 index 0000000000..9a15924b43 --- /dev/null +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_verifier_header.c @@ -0,0 +1,352 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: + */ + +#include "mrcp_verifier_header.h" + +/** String table of MRCP verifier header fields (mrcp_verifier_header_id) */ +static const apt_str_table_item_t verifier_header_string_table[] = { + {{"Repository-URI", 14},0}, + {{"Voiceprint-Identifier", 21},12}, + {{"Verification-Mode", 17},6}, + {{"Adapt-Model", 11},1}, + {{"Abort-Model", 11},11}, + {{"Min-Verification-Score", 22},1}, + {{"Num-Min-Verification-Phrases",28},6}, + {{"Num-Max-Verification-Phrases",28},5}, + {{"No-Input-Timeout", 16},2}, + {{"Save-Waveform", 13},4}, + {{"Media-Type", 10},2}, + {{"Waveform-URI", 12},0}, + {{"Voiceprint-Exists", 17},11}, + {{"Ver-Buffer-Utterance", 20},4}, + {{"Input-Waveform-URI", 18},0}, + {{"Completion-Cause", 16},11}, + {{"Completion-Reason", 17},15}, + {{"Speech-Complete-Timeout", 23},1}, + {{"New-Audio-Channel", 17},2}, + {{"Abort-Verification", 18},6}, + {{"Start-Input-Timers", 18},1} +}; + +/** String table of MRCP verifier completion-cause fields (mrcp_verifier_completion_cause_e) */ +static const apt_str_table_item_t completion_cause_string_table[] = { + {{"success", 7},2}, + {{"error", 5},0}, + {{"no-input-timeout", 16},0}, + {{"too-much-speech-timeout",23},0}, + {{"speech-too-early", 16},9}, + {{"buffer-empty", 12},0}, + {{"out-of-sequence", 15},0}, + {{"repository-uri-failure", 22},15}, + {{"repository-uri-missing", 22},15}, + {{"voiceprint-id-missing", 21},14}, + {{"voiceprint-id-not-exist",23},14}, + {{"speech-not-usable", 17},7} +}; + + +/** Initialize verifier header */ +static void mrcp_verifier_header_init(mrcp_verifier_header_t *verifier_header) +{ + apt_string_reset(&verifier_header->repository_uri); + apt_string_reset(&verifier_header->voiceprint_identifier); + apt_string_reset(&verifier_header->verification_mode); + verifier_header->adapt_model = FALSE; + verifier_header->abort_model = FALSE; + verifier_header->min_verification_score = 0.0; + verifier_header->num_min_verification_phrases = 0; + verifier_header->num_max_verification_phrases = 0; + verifier_header->no_input_timeout = 0; + verifier_header->save_waveform = FALSE; + apt_string_reset(&verifier_header->media_type); + apt_string_reset(&verifier_header->waveform_uri); + verifier_header->voiceprint_exists = FALSE; + verifier_header->ver_buffer_utterance = FALSE; + apt_string_reset(&verifier_header->input_waveform_uri); + verifier_header->completion_cause = VERIFIER_COMPLETION_CAUSE_UNKNOWN; + apt_string_reset(&verifier_header->completion_reason); + verifier_header->speech_complete_timeout = 0; + verifier_header->new_audio_channel = FALSE; + verifier_header->abort_verification = FALSE; + verifier_header->start_input_timers = FALSE; +} + +/** Allocate MRCP verifier header */ +static void* mrcp_verifier_header_allocate(mrcp_header_accessor_t *accessor, apr_pool_t *pool) +{ + mrcp_verifier_header_t *verifier_header = apr_palloc(pool,sizeof(mrcp_verifier_header_t)); + mrcp_verifier_header_init(verifier_header); + accessor->data = verifier_header; + return accessor->data; +} + +/** Parse MRCP verifier header */ +static apt_bool_t mrcp_verifier_header_parse(mrcp_header_accessor_t *accessor, apr_size_t id, const apt_str_t *value, apr_pool_t *pool) +{ + mrcp_verifier_header_t *verifier_header = accessor->data; + apt_bool_t status = TRUE; + switch(id) { + case VERIFIER_HEADER_REPOSITORY_URI: + verifier_header->repository_uri = *value; + break; + case VERIFIER_HEADER_VOICEPRINT_IDENTIFIER: + verifier_header->voiceprint_identifier = *value; + break; + case VERIFIER_HEADER_VERIFICATION_MODE: + verifier_header->verification_mode = *value; + break; + case VERIFIER_HEADER_ADAPT_MODEL: + apt_boolean_value_parse(value,&verifier_header->adapt_model); + break; + case VERIFIER_HEADER_ABORT_MODEL: + apt_boolean_value_parse(value,&verifier_header->abort_model); + break; + case VERIFIER_HEADER_MIN_VERIFICATION_SCORE: + verifier_header->min_verification_score = apt_float_value_parse(value); + break; + case VERIFIER_HEADER_NUM_MIN_VERIFICATION_PHRASES: + verifier_header->num_min_verification_phrases = apt_size_value_parse(value); + break; + case VERIFIER_HEADER_NUM_MAX_VERIFICATION_PHRASES: + verifier_header->num_max_verification_phrases = apt_size_value_parse(value); + break; + case VERIFIER_HEADER_NO_INPUT_TIMEOUT: + verifier_header->no_input_timeout = apt_size_value_parse(value); + break; + case VERIFIER_HEADER_SAVE_WAVEFORM: + apt_boolean_value_parse(value,&verifier_header->save_waveform); + break; + case VERIFIER_HEADER_MEDIA_TYPE: + verifier_header->media_type = *value; + break; + case VERIFIER_HEADER_WAVEFORM_URI: + verifier_header->waveform_uri = *value; + break; + case VERIFIER_HEADER_VOICEPRINT_EXISTS: + apt_boolean_value_parse(value,&verifier_header->voiceprint_exists); + break; + case VERIFIER_HEADER_VER_BUFFER_UTTERANCE: + apt_boolean_value_parse(value,&verifier_header->ver_buffer_utterance); + break; + case VERIFIER_HEADER_INPUT_WAVEFORM_URI: + verifier_header->input_waveform_uri = *value; + break; + case VERIFIER_HEADER_COMPLETION_CAUSE: + verifier_header->completion_cause = apt_size_value_parse(value); + break; + case VERIFIER_HEADER_COMPLETION_REASON: + verifier_header->completion_reason = *value; + break; + case VERIFIER_HEADER_SPEECH_COMPLETE_TIMEOUT: + verifier_header->speech_complete_timeout = apt_size_value_parse(value); + break; + case VERIFIER_HEADER_NEW_AUDIO_CHANNEL: + apt_boolean_value_parse(value,&verifier_header->new_audio_channel); + break; + case VERIFIER_HEADER_ABORT_VERIFICATION: + apt_boolean_value_parse(value,&verifier_header->abort_verification); + break; + case VERIFIER_HEADER_START_INPUT_TIMERS: + apt_boolean_value_parse(value,&verifier_header->start_input_timers); + break; + default: + status = FALSE; + } + return status; +} + +/** Generate MRCP verifier header */ +static apt_bool_t mrcp_verifier_header_generate(const mrcp_header_accessor_t *accessor, apr_size_t id, apt_str_t *value, apr_pool_t *pool) +{ + mrcp_verifier_header_t *verifier_header = accessor->data; + switch(id) { + case VERIFIER_HEADER_REPOSITORY_URI: + *value = verifier_header->repository_uri; + break; + case VERIFIER_HEADER_VOICEPRINT_IDENTIFIER: + *value = verifier_header->voiceprint_identifier; + break; + case VERIFIER_HEADER_VERIFICATION_MODE: + *value = verifier_header->verification_mode; + break; + case VERIFIER_HEADER_ADAPT_MODEL: + apt_boolean_value_generate(verifier_header->adapt_model,value,pool); + break; + case VERIFIER_HEADER_ABORT_MODEL: + apt_boolean_value_generate(verifier_header->abort_model,value,pool); + break; + case VERIFIER_HEADER_MIN_VERIFICATION_SCORE: + apt_float_value_generate(verifier_header->min_verification_score,value,pool); + break; + case VERIFIER_HEADER_NUM_MIN_VERIFICATION_PHRASES: + apt_size_value_generate(verifier_header->num_min_verification_phrases,value,pool); + break; + case VERIFIER_HEADER_NUM_MAX_VERIFICATION_PHRASES: + apt_size_value_generate(verifier_header->num_max_verification_phrases,value,pool); + break; + case VERIFIER_HEADER_NO_INPUT_TIMEOUT: + apt_size_value_generate(verifier_header->no_input_timeout,value,pool); + break; + case VERIFIER_HEADER_SAVE_WAVEFORM: + apt_boolean_value_generate(verifier_header->save_waveform,value,pool); + break; + case VERIFIER_HEADER_MEDIA_TYPE: + *value = verifier_header->media_type; + break; + case VERIFIER_HEADER_WAVEFORM_URI: + *value = verifier_header->waveform_uri; + break; + case VERIFIER_HEADER_VOICEPRINT_EXISTS: + apt_boolean_value_generate(verifier_header->voiceprint_exists,value,pool); + break; + case VERIFIER_HEADER_VER_BUFFER_UTTERANCE: + apt_boolean_value_generate(verifier_header->ver_buffer_utterance,value,pool); + break; + case VERIFIER_HEADER_INPUT_WAVEFORM_URI: + *value = verifier_header->input_waveform_uri; + break; + case VERIFIER_HEADER_COMPLETION_CAUSE: + apt_completion_cause_generate( + completion_cause_string_table, + VERIFIER_COMPLETION_CAUSE_COUNT, + verifier_header->completion_cause, + value, + pool); + break; + case VERIFIER_HEADER_COMPLETION_REASON: + *value = verifier_header->completion_reason; + break; + case VERIFIER_HEADER_SPEECH_COMPLETE_TIMEOUT: + apt_size_value_generate(verifier_header->speech_complete_timeout,value,pool); + break; + case VERIFIER_HEADER_NEW_AUDIO_CHANNEL: + apt_boolean_value_generate(verifier_header->new_audio_channel,value,pool); + break; + case VERIFIER_HEADER_ABORT_VERIFICATION: + apt_boolean_value_generate(verifier_header->abort_verification,value,pool); + break; + case VERIFIER_HEADER_START_INPUT_TIMERS: + apt_boolean_value_generate(verifier_header->start_input_timers,value,pool); + break; + default: + break; + } + return TRUE; +} + +/** Duplicate MRCP verifier header */ +static apt_bool_t mrcp_verifier_header_duplicate(mrcp_header_accessor_t *accessor, const mrcp_header_accessor_t *src, apr_size_t id, const apt_str_t *value, apr_pool_t *pool) +{ + mrcp_verifier_header_t *verifier_header = accessor->data; + const mrcp_verifier_header_t *src_verifier_header = src->data; + apt_bool_t status = TRUE; + + if(!verifier_header || !src_verifier_header) { + return FALSE; + } + + switch(id) { + case VERIFIER_HEADER_REPOSITORY_URI: + verifier_header->repository_uri = *value; + break; + case VERIFIER_HEADER_VOICEPRINT_IDENTIFIER: + verifier_header->voiceprint_identifier = *value; + break; + case VERIFIER_HEADER_VERIFICATION_MODE: + verifier_header->verification_mode = *value; + break; + case VERIFIER_HEADER_ADAPT_MODEL: + verifier_header->adapt_model = src_verifier_header->adapt_model; + break; + case VERIFIER_HEADER_ABORT_MODEL: + verifier_header->abort_model = src_verifier_header->abort_model; + break; + case VERIFIER_HEADER_MIN_VERIFICATION_SCORE: + verifier_header->min_verification_score = src_verifier_header->min_verification_score; + break; + case VERIFIER_HEADER_NUM_MIN_VERIFICATION_PHRASES: + verifier_header->num_min_verification_phrases = src_verifier_header->num_min_verification_phrases; + break; + case VERIFIER_HEADER_NUM_MAX_VERIFICATION_PHRASES: + verifier_header->num_max_verification_phrases = src_verifier_header->num_max_verification_phrases; + break; + case VERIFIER_HEADER_NO_INPUT_TIMEOUT: + verifier_header->no_input_timeout = src_verifier_header->no_input_timeout; + break; + case VERIFIER_HEADER_SAVE_WAVEFORM: + verifier_header->save_waveform = src_verifier_header->save_waveform; + break; + case VERIFIER_HEADER_MEDIA_TYPE: + verifier_header->media_type = *value; + break; + case VERIFIER_HEADER_WAVEFORM_URI: + verifier_header->waveform_uri = *value; + break; + case VERIFIER_HEADER_VOICEPRINT_EXISTS: + verifier_header->voiceprint_exists = src_verifier_header->voiceprint_exists; + break; + case VERIFIER_HEADER_VER_BUFFER_UTTERANCE: + verifier_header->ver_buffer_utterance = src_verifier_header->ver_buffer_utterance; + break; + case VERIFIER_HEADER_INPUT_WAVEFORM_URI: + verifier_header->input_waveform_uri = *value; + break; + case VERIFIER_HEADER_COMPLETION_CAUSE: + verifier_header->completion_cause = src_verifier_header->completion_cause; + break; + case VERIFIER_HEADER_COMPLETION_REASON: + verifier_header->completion_reason = *value; + break; + case VERIFIER_HEADER_SPEECH_COMPLETE_TIMEOUT: + verifier_header->speech_complete_timeout = src_verifier_header->speech_complete_timeout; + break; + case VERIFIER_HEADER_NEW_AUDIO_CHANNEL: + verifier_header->new_audio_channel = src_verifier_header->new_audio_channel; + break; + case VERIFIER_HEADER_ABORT_VERIFICATION: + verifier_header->abort_verification = src_verifier_header->abort_verification; + break; + case VERIFIER_HEADER_START_INPUT_TIMERS: + verifier_header->start_input_timers = src_verifier_header->start_input_timers; + break; + default: + status = FALSE; + } + return status; +} + +static const mrcp_header_vtable_t header_vtable = { + mrcp_verifier_header_allocate, + NULL, /* nothing to destroy */ + mrcp_verifier_header_parse, + mrcp_verifier_header_generate, + mrcp_verifier_header_duplicate, + verifier_header_string_table, + VERIFIER_HEADER_COUNT +}; + +const mrcp_header_vtable_t* mrcp_verifier_header_vtable_get(mrcp_version_e version) +{ + return &header_vtable; +} + +MRCP_DECLARE(const apt_str_t*) mrcp_verifier_completion_cause_get(mrcp_verifier_completion_cause_e completion_cause, mrcp_version_e version) +{ + const apt_str_table_item_t *table = completion_cause_string_table; + return apt_string_table_str_get(table,VERIFIER_COMPLETION_CAUSE_COUNT,completion_cause); +} diff --git a/libs/unimrcp/libs/mrcp/resources/src/mrcp_verifier_resource.c b/libs/unimrcp/libs/mrcp/resources/src/mrcp_verifier_resource.c new file mode 100644 index 0000000000..71d6b28c1f --- /dev/null +++ b/libs/unimrcp/libs/mrcp/resources/src/mrcp_verifier_resource.c @@ -0,0 +1,68 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: + */ + +#include "mrcp_verifier_resource.h" +#include "mrcp_verifier_header.h" +#include "mrcp_resource.h" + +/** String table of MRCP verifier methods (mrcp_verifier_method_id) */ +static const apt_str_table_item_t verifier_method_string_table[] = { + {{"SET-PARAMS", 10},10}, + {{"GET-PARAMS", 10},10}, + {{"START-SESSION", 13},8}, + {{"END-SESSION", 11},0}, + {{"QUERY-VOICEPRINT", 16},0}, + {{"DELETE-VOICEPRINT", 17},0}, + {{"VERIFY", 6},6}, + {{"VERIFY-FROM-BUFFER", 18},7}, + {{"VERIFY-ROLLBACK", 15},7}, + {{"STOP", 4},2}, + {{"CLEAR-BUFFER", 12},0}, + {{"START-INPUT-TIMERS", 18},6}, + {{"GET-INTERMEDIATE-RESULT",23},4}, +}; + +/** String table of MRCP verifier events (mrcp_verifier_event_id) */ +static const apt_str_table_item_t verifier_event_string_table[] = { + {{"START-OF-INPUT", 14},0}, + {{"VERIFICATION-COMPLETE",21},0}, +}; + +static APR_INLINE const apt_str_table_item_t* verifier_method_string_table_get(mrcp_version_e version) +{ + return verifier_method_string_table; +} + +static APR_INLINE const apt_str_table_item_t* verifier_event_string_table_get(mrcp_version_e version) +{ + return verifier_event_string_table; +} + + +/** Create MRCP verifier resource */ +MRCP_DECLARE(mrcp_resource_t*) mrcp_verifier_resource_create(apr_pool_t *pool) +{ + mrcp_resource_t *resource = mrcp_resource_create(pool); + + resource->method_count = VERIFIER_METHOD_COUNT; + resource->event_count = VERIFIER_EVENT_COUNT; + resource->get_method_str_table = verifier_method_string_table_get; + resource->get_event_str_table = verifier_event_string_table_get; + resource->get_resource_header_vtable = mrcp_verifier_header_vtable_get; + return resource; +} diff --git a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_client_connection.h b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_client_connection.h index 29181692cc..b8e83f5a5d 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_client_connection.h +++ b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_client_connection.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_client_connection.h 1792 2011-01-10 21:08:52Z achaloyan $ */ -#ifndef __MRCP_CLIENT_CONNECTION_H__ -#define __MRCP_CLIENT_CONNECTION_H__ +#ifndef MRCP_CLIENT_CONNECTION_H +#define MRCP_CLIENT_CONNECTION_H /** * @file mrcp_client_connection.h @@ -29,12 +31,14 @@ APT_BEGIN_EXTERN_C /** * Create connection agent. + * @param id the identifier of the agent * @param max_connection_count the number of max MRCPv2 connections * @param offer_new_connection the connection establishment policy in o/a * @param pool the pool to allocate memory from */ MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_client_connection_agent_create( - apr_size_t max_connection_count, + const char *id, + apr_size_t max_connection_count, apt_bool_t offer_new_connection, apr_pool_t *pool); @@ -74,20 +78,51 @@ MRCP_DECLARE(void) mrcp_client_connection_agent_handler_set( * @param resource_factory the MRCP resource factory to set */ MRCP_DECLARE(void) mrcp_client_connection_resource_factory_set( - mrcp_connection_agent_t *agent, - mrcp_resource_factory_t *resource_factory); + mrcp_connection_agent_t *agent, + const mrcp_resource_factory_t *resource_factory); +/** + * Set rx buffer size. + * @param agent the agent to set buffer size for + * @param size the size of rx buffer to set + */ +MRCP_DECLARE(void) mrcp_client_connection_rx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size); + +/** + * Set tx buffer size. + * @param agent the agent to set buffer size for + * @param size the size of the rx buffer to set + */ +MRCP_DECLARE(void) mrcp_client_connection_tx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size); +/** + * Set request timeout. + * @param agent the agent to set timeout for + * @param timeout the timeout to set + */ +MRCP_DECLARE(void) mrcp_client_connection_timeout_set( + mrcp_connection_agent_t *agent, + apr_size_t timeout); /** * Get task. * @param agent the agent to get task from */ -MRCP_DECLARE(apt_task_t*) mrcp_client_connection_agent_task_get(mrcp_connection_agent_t *agent); +MRCP_DECLARE(apt_task_t*) mrcp_client_connection_agent_task_get(const mrcp_connection_agent_t *agent); /** * Get external object. * @param agent the agent to get object from */ -MRCP_DECLARE(void*) mrcp_client_connection_agent_object_get(mrcp_connection_agent_t *agent); +MRCP_DECLARE(void*) mrcp_client_connection_agent_object_get(const mrcp_connection_agent_t *agent); + +/** + * Get string identifier. + * @param agent the agent to get identifier of + */ +MRCP_DECLARE(const char*) mrcp_client_connection_agent_id_get(const mrcp_connection_agent_t *agent); /** @@ -96,21 +131,28 @@ MRCP_DECLARE(void*) mrcp_client_connection_agent_object_get(mrcp_connection_agen * @param obj the external object to associate with the control channel * @param pool the pool to allocate memory from */ -MRCP_DECLARE(mrcp_control_channel_t*) mrcp_client_control_channel_create(mrcp_connection_agent_t *agent, void *obj, apr_pool_t *pool); +MRCP_DECLARE(mrcp_control_channel_t*) mrcp_client_control_channel_create( + mrcp_connection_agent_t *agent, + void *obj, + apr_pool_t *pool); /** * Add MRCPv2 control channel. * @param channel the control channel to add * @param descriptor the control descriptor */ -MRCP_DECLARE(apt_bool_t) mrcp_client_control_channel_add(mrcp_control_channel_t *channel, mrcp_control_descriptor_t *descriptor); +MRCP_DECLARE(apt_bool_t) mrcp_client_control_channel_add( + mrcp_control_channel_t *channel, + mrcp_control_descriptor_t *descriptor); /** * Modify MRCPv2 control channel. * @param channel the control channel to modify * @param descriptor the control descriptor */ -MRCP_DECLARE(apt_bool_t) mrcp_client_control_channel_modify(mrcp_control_channel_t *channel, mrcp_control_descriptor_t *descriptor); +MRCP_DECLARE(apt_bool_t) mrcp_client_control_channel_modify( + mrcp_control_channel_t *channel, + mrcp_control_descriptor_t *descriptor); /** * Remove MRCPv2 control channel. @@ -131,7 +173,14 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_control_channel_destroy(mrcp_control_channe */ MRCP_DECLARE(apt_bool_t) mrcp_client_control_message_send(mrcp_control_channel_t *channel, mrcp_message_t *message); +/** + * Set the logger object. + * @param channel the control channel to set the object for + * @param log_obj the object to set + */ +MRCP_DECLARE(void) mrcp_client_control_channel_log_obj_set(mrcp_control_channel_t *channel, void *log_obj); + APT_END_EXTERN_C -#endif /*__MRCP_CLIENT_CONNECTION_H__*/ +#endif /* MRCP_CLIENT_CONNECTION_H */ diff --git a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection.h b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection.h index 82d44ea865..08031c3a55 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection.h +++ b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_connection.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __MRCP_CONNECTION_H__ -#define __MRCP_CONNECTION_H__ +#ifndef MRCP_CONNECTION_H +#define MRCP_CONNECTION_H /** * @file mrcp_connection.h @@ -50,6 +52,9 @@ struct mrcp_connection_t { apt_str_t remote_ip; /** String identifier used for traces */ const char *id; + /** Transparently dump whatever received/sent on transport layer, + if verbose is set to TRUE (default) */ + apt_bool_t verbose; /** Reference count */ apr_size_t access_count; @@ -62,22 +67,24 @@ struct mrcp_connection_t { apr_hash_t *channel_table; /** Rx buffer */ - char rx_buffer[MRCP_STREAM_BUFFER_SIZE]; + char *rx_buffer; + /** Rx buffer size */ + apr_size_t rx_buffer_size; /** Rx stream */ apt_text_stream_t rx_stream; /** MRCP parser to parser MRCP messages out of rx stream */ mrcp_parser_t *parser; /** Tx buffer */ - char tx_buffer[MRCP_STREAM_BUFFER_SIZE]; - /** Tx stream */ - apt_text_stream_t tx_stream; - /** MRCP generator to generate MRCP messages out of tx stream */ + char *tx_buffer; + /** Tx buffer size */ + apr_size_t tx_buffer_size; + /** MRCP generator to generate MRCP messages into tx stream */ mrcp_generator_t *generator; }; /** Create MRCP connection. */ -mrcp_connection_t* mrcp_connection_create(void); +mrcp_connection_t* mrcp_connection_create(); /** Destroy MRCP connection. */ void mrcp_connection_destroy(mrcp_connection_t *connection); @@ -86,7 +93,7 @@ void mrcp_connection_destroy(mrcp_connection_t *connection); apt_bool_t mrcp_connection_channel_add(mrcp_connection_t *connection, mrcp_control_channel_t *channel); /** Find Control Channel by Channel Identifier. */ -mrcp_control_channel_t* mrcp_connection_channel_find(mrcp_connection_t *connection, const apt_str_t *identifier); +mrcp_control_channel_t* mrcp_connection_channel_find(const mrcp_connection_t *connection, const apt_str_t *identifier); /** Remove Control Channel from MRCP connection. */ apt_bool_t mrcp_connection_channel_remove(mrcp_connection_t *connection, mrcp_control_channel_t *channel); @@ -96,4 +103,4 @@ apt_bool_t mrcp_connection_disconnect_raise(mrcp_connection_t *connection, const APT_END_EXTERN_C -#endif /*__MRCP_CONNECTION_H__*/ +#endif /* MRCP_CONNECTION_H */ diff --git a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection_types.h b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection_types.h index c7a02c0419..e61c66cafa 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection_types.h +++ b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_connection_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_connection_types.h 1792 2011-01-10 21:08:52Z achaloyan $ */ -#ifndef __MRCP_CONNECTION_TYPES_H__ -#define __MRCP_CONNECTION_TYPES_H__ +#ifndef MRCP_CONNECTION_TYPES_H +#define MRCP_CONNECTION_TYPES_H /** * @file mrcp_connection_types.h @@ -24,6 +26,7 @@ #include #include "apt_string.h" +#include "apt_timer_queue.h" #include "mrcp_types.h" APT_BEGIN_EXTERN_C @@ -63,10 +66,16 @@ struct mrcp_control_channel_t { mrcp_connection_agent_t *agent; /** MRCPv2 (shared) connection */ mrcp_connection_t *connection; + /** Request sent to the server and waiting for a response */ + mrcp_message_t *active_request; + /** Timer used for request timeouts */ + apt_timer_t *request_timer; /** Indicate removed connection (safe to destroy) */ apt_bool_t removed; /** External object associated with the channel */ void *obj; + /** External logger object associated with the channel */ + void *log_obj; /** Pool to allocate memory from */ apr_pool_t *pool; /** Channel identifier (id at resource) */ @@ -125,4 +134,4 @@ static APR_INLINE apt_bool_t mrcp_connection_message_receive( APT_END_EXTERN_C -#endif /*__MRCP_CONNECTION_TYPES_H__*/ +#endif /* MRCP_CONNECTION_TYPES_H */ diff --git a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_control_descriptor.h b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_control_descriptor.h index b5dbc44c5f..40535d4b5b 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_control_descriptor.h +++ b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_control_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_control_descriptor.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __MRCP_CONTROL_DESCRIPTOR_H__ -#define __MRCP_CONTROL_DESCRIPTOR_H__ +#ifndef MRCP_CONTROL_DESCRIPTOR_H +#define MRCP_CONTROL_DESCRIPTOR_H /** * @file mrcp_control_descriptor.h @@ -110,7 +112,7 @@ MRCP_DECLARE(mrcp_control_descriptor_t*) mrcp_control_answer_create(mrcp_control MRCP_DECLARE(void) mrcp_cmid_add(apr_array_header_t *cmid_arr, apr_size_t cmid); /** Find cmid in cmid_arr */ -MRCP_DECLARE(apt_bool_t) mrcp_cmid_find(apr_array_header_t *cmid_arr, apr_size_t cmid); +MRCP_DECLARE(apt_bool_t) mrcp_cmid_find(const apr_array_header_t *cmid_arr, apr_size_t cmid); /** Get MRCP protocol transport name by identifier */ MRCP_DECLARE(const apt_str_t*) mrcp_proto_get(mrcp_proto_type_e proto); @@ -142,4 +144,4 @@ MRCP_DECLARE(mrcp_connection_type_e) mrcp_connection_type_find(const apt_str_t * APT_END_EXTERN_C -#endif /*__MRCP_CONTROL_DESCRIPTOR_H__*/ +#endif /* MRCP_CONTROL_DESCRIPTOR_H */ diff --git a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_server_connection.h b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_server_connection.h index c72b9c5ef8..a5ee18c1a2 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_server_connection.h +++ b/libs/unimrcp/libs/mrcpv2-transport/include/mrcp_server_connection.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_server_connection.h 1721 2010-06-01 05:45:46Z achaloyan $ */ -#ifndef __MRCP_SERVER_CONNECTION_H__ -#define __MRCP_SERVER_CONNECTION_H__ +#ifndef MRCP_SERVER_CONNECTION_H +#define MRCP_SERVER_CONNECTION_H /** * @file mrcp_server_connection.h @@ -29,13 +31,15 @@ APT_BEGIN_EXTERN_C /** * Create connection agent. - * @param listen_ip the listen IP address - * @param listen_port the listen port + * @param id the identifier of the engine + * @param listen_ip the IP address to listen on + * @param listen_port the port to listen on * @param max_connection_count the number of max MRCPv2 connections - * @param force_new_connection the connection establishment policy in o/a + * @param force_new_connection the policy used in o/a for connection establishment * @param pool the pool to allocate memory from */ MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_server_connection_agent_create( + const char *id, const char *listen_ip, apr_port_t listen_port, apr_size_t max_connection_count, @@ -77,20 +81,44 @@ MRCP_DECLARE(void) mrcp_server_connection_agent_handler_set( * @param resource_factory the MRCP resource factory to set */ MRCP_DECLARE(void) mrcp_server_connection_resource_factory_set( - mrcp_connection_agent_t *agent, - mrcp_resource_factory_t *resource_factory); + mrcp_connection_agent_t *agent, + const mrcp_resource_factory_t *resource_factory); + +/** + * Set rx buffer size. + * @param agent the agent to set buffer size for + * @param size the size of rx buffer to set + */ +MRCP_DECLARE(void) mrcp_server_connection_rx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size); + +/** + * Set tx buffer size. + * @param agent the agent to set buffer size for + * @param size the size of the rx buffer to set + */ +MRCP_DECLARE(void) mrcp_server_connection_tx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size); /** * Get task. * @param agent the agent to get task from */ -MRCP_DECLARE(apt_task_t*) mrcp_server_connection_agent_task_get(mrcp_connection_agent_t *agent); +MRCP_DECLARE(apt_task_t*) mrcp_server_connection_agent_task_get(const mrcp_connection_agent_t *agent); /** * Get external object. * @param agent the agent to get object from */ -MRCP_DECLARE(void*) mrcp_server_connection_agent_object_get(mrcp_connection_agent_t *agent); +MRCP_DECLARE(void*) mrcp_server_connection_agent_object_get(const mrcp_connection_agent_t *agent); + +/** + * Get string identifier. + * @param agent the agent to get identifier of + */ +MRCP_DECLARE(const char*) mrcp_server_connection_agent_id_get(const mrcp_connection_agent_t *agent); /** @@ -99,21 +127,28 @@ MRCP_DECLARE(void*) mrcp_server_connection_agent_object_get(mrcp_connection_agen * @param obj the external object to associate with the control channel * @param pool the pool to allocate memory from */ -MRCP_DECLARE(mrcp_control_channel_t*) mrcp_server_control_channel_create(mrcp_connection_agent_t *agent, void *obj, apr_pool_t *pool); +MRCP_DECLARE(mrcp_control_channel_t*) mrcp_server_control_channel_create( + mrcp_connection_agent_t *agent, + void *obj, + apr_pool_t *pool); /** * Add MRCPv2 control channel. * @param channel the control channel to add * @param descriptor the control descriptor */ -MRCP_DECLARE(apt_bool_t) mrcp_server_control_channel_add(mrcp_control_channel_t *channel, mrcp_control_descriptor_t *descriptor); +MRCP_DECLARE(apt_bool_t) mrcp_server_control_channel_add( + mrcp_control_channel_t *channel, + mrcp_control_descriptor_t *descriptor); /** * Modify MRCPv2 control channel. * @param channel the control channel to modify * @param descriptor the control descriptor */ -MRCP_DECLARE(apt_bool_t) mrcp_server_control_channel_modify(mrcp_control_channel_t *channel, mrcp_control_descriptor_t *descriptor); +MRCP_DECLARE(apt_bool_t) mrcp_server_control_channel_modify( + mrcp_control_channel_t *channel, + mrcp_control_descriptor_t *descriptor); /** * Remove MRCPv2 control channel. @@ -137,4 +172,4 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_control_message_send(mrcp_control_channel_t APT_END_EXTERN_C -#endif /*__MRCP_SERVER_CONNECTION_H__*/ +#endif /* MRCP_SERVER_CONNECTION_H */ diff --git a/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2008.vcproj b/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2008.vcproj deleted file mode 100644 index 87ed8335a3..0000000000 --- a/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2008.vcproj +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2010.vcxproj b/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2010.vcxproj deleted file mode 100644 index 33ed618305..0000000000 --- a/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2010.vcxproj +++ /dev/null @@ -1,124 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mrcpv2transport - {A9EDAC04-6A5F-4BA7-BC0D-CCE7B255B6EA} - mrcpv2transport - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - ProgramDatabase - - - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2010.vcxproj.filters b/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2010.vcxproj.filters deleted file mode 100644 index 452f77e19d..0000000000 --- a/libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2010.vcxproj.filters +++ /dev/null @@ -1,44 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {a92d3b8c-d54d-416c-b458-dc57ac24d2e9} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - include - - - include - - - include - - - - - src - - - src - - - src - - - src - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_client_connection.c b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_client_connection.c index 94b25bad26..5d67271fa8 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_client_connection.c +++ b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_client_connection.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_client_connection.c 1792 2011-01-10 21:08:52Z achaloyan $ */ #include "mrcp_connection.h" @@ -20,27 +22,21 @@ #include "mrcp_resource_factory.h" #include "mrcp_message.h" #include "apt_text_stream.h" -#include "apt_task.h" -#include "apt_pollset.h" -#include "apt_cyclic_queue.h" +#include "apt_poller_task.h" #include "apt_log.h" -#define MRCPV2_CONNECTION_TASK_NAME "TCP/MRCPv2 Connection Agent" struct mrcp_connection_agent_t { - apr_pool_t *pool; - apt_task_t *task; + apr_pool_t *pool; + apt_poller_task_t *task; + const mrcp_resource_factory_t *resource_factory; - mrcp_resource_factory_t *resource_factory; + apt_obj_list_t *connection_list; - apt_obj_list_t *connection_list; - - apt_bool_t offer_new_connection; - apr_size_t max_connection_count; - - apr_thread_mutex_t *guard; - apt_cyclic_queue_t *msg_queue; - apt_pollset_t *pollset; + apr_uint32_t request_timeout; + apt_bool_t offer_new_connection; + apr_size_t tx_buffer_size; + apr_size_t rx_buffer_size; void *obj; const mrcp_connection_event_vtable_t *vtable; @@ -50,8 +46,7 @@ typedef enum { CONNECTION_TASK_MSG_ADD_CHANNEL, CONNECTION_TASK_MSG_MODIFY_CHANNEL, CONNECTION_TASK_MSG_REMOVE_CHANNEL, - CONNECTION_TASK_MSG_SEND_MESSAGE, - CONNECTION_TASK_MSG_TERMINATE + CONNECTION_TASK_MSG_SEND_MESSAGE } connection_task_msg_type_e; typedef struct connection_task_msg_t connection_task_msg_t; @@ -64,79 +59,75 @@ struct connection_task_msg_t { }; -static apt_bool_t mrcp_client_agent_task_run(apt_task_t *task); -static apt_bool_t mrcp_client_agent_task_terminate(apt_task_t *task); -static apt_bool_t mrcp_client_agent_task_on_destroy(apt_task_t *task); +static apt_bool_t mrcp_client_agent_msg_process(apt_task_t *task, apt_task_msg_t *task_msg); +static apt_bool_t mrcp_client_poller_signal_process(void *obj, const apr_pollfd_t *descriptor); +static void mrcp_client_timer_proc(apt_timer_t *timer, void *obj); /** Create connection agent. */ MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_client_connection_agent_create( + const char *id, apr_size_t max_connection_count, apt_bool_t offer_new_connection, apr_pool_t *pool) { + apt_task_t *task; apt_task_vtable_t *vtable; + apt_task_msg_pool_t *msg_pool; mrcp_connection_agent_t *agent; - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create "MRCPV2_CONNECTION_TASK_NAME" [%"APR_SIZE_T_FMT"]",max_connection_count); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv2 Agent [%s] [%"APR_SIZE_T_FMT"]", + id, max_connection_count); agent = apr_palloc(pool,sizeof(mrcp_connection_agent_t)); agent->pool = pool; - agent->pollset = NULL; - agent->max_connection_count = max_connection_count; + agent->request_timeout = 0; agent->offer_new_connection = offer_new_connection; + agent->rx_buffer_size = MRCP_STREAM_BUFFER_SIZE; + agent->tx_buffer_size = MRCP_STREAM_BUFFER_SIZE; - agent->task = apt_task_create(agent,NULL,pool); + msg_pool = apt_task_msg_pool_create_dynamic(sizeof(connection_task_msg_t),pool); + + agent->task = apt_poller_task_create( + max_connection_count, + mrcp_client_poller_signal_process, + agent, + msg_pool, + pool); if(!agent->task) { return NULL; } - apt_task_name_set(agent->task,MRCPV2_CONNECTION_TASK_NAME); - vtable = apt_task_vtable_get(agent->task); + task = apt_poller_task_base_get(agent->task); + if(task) { + apt_task_name_set(task,id); + } + + vtable = apt_poller_task_vtable_get(agent->task); if(vtable) { - vtable->run = mrcp_client_agent_task_run; - vtable->terminate = mrcp_client_agent_task_terminate; - vtable->destroy = mrcp_client_agent_task_on_destroy; + vtable->process_msg = mrcp_client_agent_msg_process; } - apt_task_auto_ready_set(agent->task,FALSE); agent->connection_list = apt_list_create(pool); - - agent->msg_queue = apt_cyclic_queue_create(CYCLIC_QUEUE_DEFAULT_SIZE); - apr_thread_mutex_create(&agent->guard,APR_THREAD_MUTEX_UNNESTED,pool); return agent; } -/** Virtual destroy handler. */ -static apt_bool_t mrcp_client_agent_task_on_destroy(apt_task_t *task) -{ - mrcp_connection_agent_t *agent = apt_task_object_get(task); - if(agent->guard) { - apr_thread_mutex_destroy(agent->guard); - agent->guard = NULL; - } - if(agent->msg_queue) { - apt_cyclic_queue_destroy(agent->msg_queue); - agent->msg_queue = NULL; - } - return TRUE; -} - /** Destroy connection agent. */ MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_destroy(mrcp_connection_agent_t *agent) { - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy MRCPv2 Agent"); - return apt_task_destroy(agent->task); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy MRCPv2 Agent [%s]", + mrcp_client_connection_agent_id_get(agent)); + return apt_poller_task_destroy(agent->task); } /** Start connection agent. */ MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_start(mrcp_connection_agent_t *agent) { - return apt_task_start(agent->task); + return apt_poller_task_start(agent->task); } /** Terminate connection agent. */ MRCP_DECLARE(apt_bool_t) mrcp_client_connection_agent_terminate(mrcp_connection_agent_t *agent) { - return apt_task_terminate(agent->task,TRUE); + return apt_poller_task_terminate(agent->task); } /** Set connection event handler. */ @@ -151,24 +142,61 @@ MRCP_DECLARE(void) mrcp_client_connection_agent_handler_set( /** Set MRCP resource factory */ MRCP_DECLARE(void) mrcp_client_connection_resource_factory_set( - mrcp_connection_agent_t *agent, - mrcp_resource_factory_t *resource_factroy) + mrcp_connection_agent_t *agent, + const mrcp_resource_factory_t *resource_factroy) { agent->resource_factory = resource_factroy; } +/** Set rx buffer size */ +MRCP_DECLARE(void) mrcp_client_connection_rx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size) +{ + if(size < MRCP_STREAM_BUFFER_SIZE) { + size = MRCP_STREAM_BUFFER_SIZE; + } + agent->rx_buffer_size = size; +} + +/** Set tx buffer size */ +MRCP_DECLARE(void) mrcp_client_connection_tx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size) +{ + if(size < MRCP_STREAM_BUFFER_SIZE) { + size = MRCP_STREAM_BUFFER_SIZE; + } + agent->tx_buffer_size = size; +} + +/** Set request timeout */ +MRCP_DECLARE(void) mrcp_client_connection_timeout_set( + mrcp_connection_agent_t *agent, + apr_size_t timeout) +{ + agent->request_timeout = (apr_uint32_t)timeout; +} + /** Get task */ -MRCP_DECLARE(apt_task_t*) mrcp_client_connection_agent_task_get(mrcp_connection_agent_t *agent) +MRCP_DECLARE(apt_task_t*) mrcp_client_connection_agent_task_get(const mrcp_connection_agent_t *agent) { - return agent->task; + return apt_poller_task_base_get(agent->task); } /** Get external object */ -MRCP_DECLARE(void*) mrcp_client_connection_agent_object_get(mrcp_connection_agent_t *agent) +MRCP_DECLARE(void*) mrcp_client_connection_agent_object_get(const mrcp_connection_agent_t *agent) { return agent->obj; } +/** Get string identifier */ +MRCP_DECLARE(const char*) mrcp_client_connection_agent_id_get(const mrcp_connection_agent_t *agent) +{ + apt_task_t *task = apt_poller_task_base_get(agent->task); + return apt_task_name_get(task); +} + /** Create control channel */ MRCP_DECLARE(mrcp_control_channel_t*) mrcp_client_control_channel_create(mrcp_connection_agent_t *agent, void *obj, apr_pool_t *pool) @@ -176,12 +204,27 @@ MRCP_DECLARE(mrcp_control_channel_t*) mrcp_client_control_channel_create(mrcp_co mrcp_control_channel_t *channel = apr_palloc(pool,sizeof(mrcp_control_channel_t)); channel->agent = agent; channel->connection = NULL; + channel->active_request = NULL; + channel->request_timer = NULL; channel->removed = FALSE; channel->obj = obj; + channel->log_obj = NULL; channel->pool = pool; + + channel->request_timer = apt_poller_task_timer_create( + agent->task, + mrcp_client_timer_proc, + channel, + pool); return channel; } +/** Set the logger object */ +MRCP_DECLARE(void) mrcp_client_control_channel_log_obj_set(mrcp_control_channel_t *channel, void *log_obj) +{ + channel->log_obj = log_obj; +} + /** Destroy MRCPv2 control channel */ MRCP_DECLARE(apt_bool_t) mrcp_client_control_channel_destroy(mrcp_control_channel_t *channel) { @@ -194,6 +237,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_client_control_channel_destroy(mrcp_control_channe return TRUE; } +/** Signal task message */ static apt_bool_t mrcp_client_control_message_signal( connection_task_msg_type_e type, mrcp_connection_agent_t *agent, @@ -201,22 +245,18 @@ static apt_bool_t mrcp_client_control_message_signal( mrcp_control_descriptor_t *descriptor, mrcp_message_t *message) { - apt_bool_t status; - connection_task_msg_t *msg = apr_palloc(channel->pool,sizeof(connection_task_msg_t)); - msg->type = type; - msg->agent = agent; - msg->channel = channel; - msg->descriptor = descriptor; - msg->message = message; - - apr_thread_mutex_lock(agent->guard); - status = apt_cyclic_queue_push(agent->msg_queue,msg); - apr_thread_mutex_unlock(agent->guard); - if(apt_pollset_wakeup(agent->pollset) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Control Message"); - status = FALSE; + apt_task_t *task = apt_poller_task_base_get(agent->task); + apt_task_msg_t *task_msg = apt_task_msg_get(task); + if(task_msg) { + connection_task_msg_t *msg = (connection_task_msg_t*)task_msg->data; + msg->type = type; + msg->agent = agent; + msg->channel = channel; + msg->descriptor = descriptor; + msg->message = message; + apt_task_msg_signal(task,task_msg); } - return status; + return TRUE; } /** Add MRCPv2 control channel */ @@ -247,6 +287,7 @@ static mrcp_connection_t* mrcp_client_agent_connection_create(mrcp_connection_ag { char *local_ip = NULL; char *remote_ip = NULL; + apt_pollset_t *pollset = apt_poller_task_pollset_get(agent->task); mrcp_connection_t *connection = mrcp_connection_create(); apr_sockaddr_info_get(&connection->r_sockaddr,descriptor->ip.buf,APR_INET,descriptor->port,0,connection->pool); @@ -287,7 +328,8 @@ static mrcp_connection_t* mrcp_client_agent_connection_create(mrcp_connection_ag connection->sock_pfd.reqevents = APR_POLLIN; connection->sock_pfd.desc.s = connection->sock; connection->sock_pfd.client_data = connection; - if(apt_pollset_add(agent->pollset, &connection->sock_pfd) != TRUE) { + if(apt_pollset_add(pollset, &connection->sock_pfd) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add to Pollset %s",connection->id); apr_socket_close(connection->sock); mrcp_connection_destroy(connection); return NULL; @@ -296,8 +338,23 @@ static mrcp_connection_t* mrcp_client_agent_connection_create(mrcp_connection_ag apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Established TCP/MRCPv2 Connection %s",connection->id); connection->agent = agent; connection->it = apt_list_push_back(agent->connection_list,connection,connection->pool); + connection->parser = mrcp_parser_create(agent->resource_factory,connection->pool); connection->generator = mrcp_generator_create(agent->resource_factory,connection->pool); + + connection->tx_buffer_size = agent->tx_buffer_size; + connection->tx_buffer = apr_palloc(connection->pool,connection->tx_buffer_size+1); + + connection->rx_buffer_size = agent->rx_buffer_size; + connection->rx_buffer = apr_palloc(connection->pool,connection->rx_buffer_size+1); + apt_text_stream_init(&connection->rx_stream,connection->rx_buffer,connection->rx_buffer_size); + + if(apt_log_masking_get() != APT_LOG_MASKING_NONE) { + connection->verbose = FALSE; + mrcp_parser_verbose_set(connection->parser,TRUE); + mrcp_generator_verbose_set(connection->generator,TRUE); + } + return connection; } @@ -324,12 +381,17 @@ static mrcp_connection_t* mrcp_client_agent_connection_find(mrcp_connection_agen static apt_bool_t mrcp_client_agent_connection_remove(mrcp_connection_agent_t *agent, mrcp_connection_t *connection) { + apt_pollset_t *pollset = apt_poller_task_pollset_get(agent->task); + /* remove from the list */ if(connection->it) { apt_list_elem_remove(agent->connection_list,connection->it); connection->it = NULL; } - apt_pollset_remove(agent->pollset,&connection->sock_pfd); + + if(pollset) { + apt_pollset_remove(pollset,&connection->sock_pfd); + } if(connection->sock) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close TCP/MRCPv2 Connection %s",connection->id); apr_socket_close(connection->sock); @@ -338,7 +400,6 @@ static apt_bool_t mrcp_client_agent_connection_remove(mrcp_connection_agent_t *a return TRUE; } - static apt_bool_t mrcp_client_agent_channel_add(mrcp_connection_agent_t *agent, mrcp_control_channel_t *channel, mrcp_control_descriptor_t *descriptor) { if(agent->offer_new_connection == TRUE) { @@ -367,20 +428,20 @@ static apt_bool_t mrcp_client_agent_channel_modify(mrcp_connection_agent_t *agen /* try to find existing connection */ connection = mrcp_client_agent_connection_find(agent,descriptor); if(!connection) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Found No Existing TCP/MRCPv2 Connection"); + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,channel->log_obj,"Found No Existing TCP/MRCPv2 Connection"); } } if(!connection) { /* create new connection */ connection = mrcp_client_agent_connection_create(agent,descriptor); if(!connection) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Establish TCP/MRCPv2 Connection"); + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,channel->log_obj,"Failed to Establish TCP/MRCPv2 Connection"); } } if(connection) { mrcp_connection_channel_add(connection,channel); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add Control Channel <%s> %s [%d]", + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,channel->log_obj,"Add Control Channel <%s> %s [%d]", channel->identifier.buf, connection->id, apr_hash_count(connection->channel_table)); @@ -404,7 +465,7 @@ static apt_bool_t mrcp_client_agent_channel_remove(mrcp_connection_agent_t *agen if(channel->connection) { mrcp_connection_t *connection = channel->connection; mrcp_connection_channel_remove(connection,channel); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove Control Channel <%s> [%d]", + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,channel->log_obj,"Remove Control Channel <%s> [%d]", channel->identifier.buf, apr_hash_count(connection->channel_table)); if(!connection->access_count) { @@ -419,71 +480,124 @@ static apt_bool_t mrcp_client_agent_channel_remove(mrcp_connection_agent_t *agen return mrcp_control_channel_remove_respond(agent->vtable,channel,TRUE); } +static apt_bool_t mrcp_client_agent_request_cancel(mrcp_connection_agent_t *agent, mrcp_control_channel_t *channel, mrcp_message_t *message) +{ + mrcp_message_t *response; + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,channel->log_obj,"Cancel MRCP Request <%s@%s> [%d]", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + response = mrcp_response_create(message,message->pool); + response->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED; + return mrcp_connection_message_receive(agent->vtable,channel,response); +} + +static apt_bool_t mrcp_client_agent_disconnect_raise(mrcp_connection_agent_t *agent, mrcp_connection_t *connection) +{ + mrcp_control_channel_t *channel; + void *val; + apr_hash_index_t *it = apr_hash_first(connection->pool,connection->channel_table); + /* walk through the list of channels and raise disconnect event for them */ + for(; it; it = apr_hash_next(it)) { + apr_hash_this(it,NULL,NULL,&val); + channel = val; + if(!channel) continue; + + if(channel->active_request) { + mrcp_client_agent_request_cancel(channel->agent,channel,channel->active_request); + channel->active_request = NULL; + if(channel->request_timer) { + apt_timer_kill(channel->request_timer); + } + } + else if(agent->vtable->on_disconnect){ + agent->vtable->on_disconnect(channel); + } + } + return TRUE; +} + static apt_bool_t mrcp_client_agent_messsage_send(mrcp_connection_agent_t *agent, mrcp_control_channel_t *channel, mrcp_message_t *message) { apt_bool_t status = FALSE; mrcp_connection_t *connection = channel->connection; - apt_text_stream_t *stream; - mrcp_stream_status_e result; + apt_text_stream_t stream; + apt_message_status_e result; if(!connection || !connection->sock) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No MRCPv2 Connection"); + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,channel->log_obj,"Null MRCPv2 Connection "APT_SIDRES_FMT,MRCP_MESSAGE_SIDRES(message)); + mrcp_client_agent_request_cancel(agent,channel,message); return FALSE; } - stream = &connection->tx_stream; - mrcp_generator_message_set(connection->generator,message); do { - apt_text_stream_init(&connection->tx_stream,connection->tx_buffer,sizeof(connection->tx_buffer)-1); - result = mrcp_generator_run(connection->generator,stream); - if(result != MRCP_STREAM_STATUS_INVALID) { - stream->text.length = stream->pos - stream->text.buf; - *stream->pos = '\0'; + apt_text_stream_init(&stream,connection->tx_buffer,connection->tx_buffer_size); + result = mrcp_generator_run(connection->generator,message,&stream); + if(result != APT_MESSAGE_STATUS_INVALID) { + stream.text.length = stream.pos - stream.text.buf; + *stream.pos = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send MRCPv2 Stream %s [%lu bytes]\n%s", + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,channel->log_obj,"Send MRCPv2 Stream %s [%"APR_SIZE_T_FMT" bytes]\n%.*s", connection->id, - stream->text.length, - stream->text.buf); - if(apr_socket_send(connection->sock,stream->text.buf,&stream->text.length) == APR_SUCCESS) { + stream.text.length, + connection->verbose == TRUE ? stream.text.length : 0, + stream.text.buf); + + if(apr_socket_send(connection->sock,stream.text.buf,&stream.text.length) == APR_SUCCESS) { status = TRUE; } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Send MRCPv2 Stream"); + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,channel->log_obj,"Failed to Send MRCPv2 Stream %s", + connection->id); } } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Generate MRCPv2 Stream"); + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,channel->log_obj,"Failed to Generate MRCPv2 Stream %s", + connection->id); } } - while(result == MRCP_STREAM_STATUS_INCOMPLETE); + while(result == APT_MESSAGE_STATUS_INCOMPLETE); - if(status == FALSE) { - mrcp_message_t *response = mrcp_response_create(message,message->pool); - response->start_line.method_id = message->start_line.method_id; - response->start_line.method_name = message->start_line.method_name; - response->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED; - mrcp_connection_message_receive(agent->vtable,channel,response); + if(status == TRUE) { + channel->active_request = message; + if(channel->request_timer && agent->request_timeout) { + apt_timer_set(channel->request_timer,agent->request_timeout); + } } - return TRUE; + else { + mrcp_client_agent_request_cancel(agent,channel,message); + } + return status; } -static apt_bool_t mrcp_client_message_handler(void *obj, mrcp_message_t *message, mrcp_stream_status_e status) +static apt_bool_t mrcp_client_message_handler(mrcp_connection_t *connection, mrcp_message_t *message, apt_message_status_e status) { - if(status == MRCP_STREAM_STATUS_COMPLETE) { + if(status == APT_MESSAGE_STATUS_COMPLETE) { /* message is completely parsed */ - mrcp_connection_t *connection = obj; mrcp_control_channel_t *channel; apt_str_t identifier; apt_id_resource_generate(&message->channel_id.session_id,&message->channel_id.resource_name,'@',&identifier,message->pool); channel = mrcp_connection_channel_find(connection,&identifier); if(channel) { mrcp_connection_agent_t *agent = connection->agent; + if(message->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE) { + if(!channel->active_request || + channel->active_request->start_line.request_id != message->start_line.request_id) { + apt_obj_log(APT_LOG_MARK,APT_PRIO_WARNING,channel->log_obj,"Unexpected MRCP Response "APT_SIDRES_FMT" [%d]", + MRCP_MESSAGE_SIDRES(message), + message->start_line.request_id); + return FALSE; + } + if(channel->request_timer) { + apt_timer_kill(channel->request_timer); + } + channel->active_request = NULL; + } + mrcp_connection_message_receive(agent->vtable,channel,message); } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find Channel <%s@%s> in Connection %s [%d]", - message->channel_id.session_id.buf, - message->channel_id.resource_name.buf, + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find Channel "APT_SIDRES_FMT" in Connection %s [%d]", + MRCP_MESSAGE_SIDRES(message), connection->id, apr_hash_count(connection->channel_table)); } @@ -491,151 +605,104 @@ static apt_bool_t mrcp_client_message_handler(void *obj, mrcp_message_t *message return TRUE; } -static apt_bool_t mrcp_client_agent_messsage_receive(mrcp_connection_agent_t *agent, mrcp_connection_t *connection) +/* Receive MRCP message through TCP/MRCPv2 connection */ +static apt_bool_t mrcp_client_poller_signal_process(void *obj, const apr_pollfd_t *descriptor) { + mrcp_connection_agent_t *agent = obj; + mrcp_connection_t *connection = descriptor->client_data; apr_status_t status; apr_size_t offset; apr_size_t length; apt_text_stream_t *stream; + mrcp_message_t *message; + apt_message_status_e msg_status; if(!connection || !connection->sock) { return FALSE; } stream = &connection->rx_stream; - /* init length of the stream */ - stream->text.length = sizeof(connection->rx_buffer)-1; /* calculate offset remaining from the previous receive / if any */ offset = stream->pos - stream->text.buf; /* calculate available length */ - length = stream->text.length - offset; + length = connection->rx_buffer_size - offset; + status = apr_socket_recv(connection->sock,stream->pos,&length); if(status == APR_EOF || length == 0) { + apt_pollset_t *pollset = apt_poller_task_pollset_get(agent->task); apt_log(APT_LOG_MARK,APT_PRIO_INFO,"TCP/MRCPv2 Peer Disconnected %s",connection->id); - apt_pollset_remove(agent->pollset,&connection->sock_pfd); + if(pollset) { + apt_pollset_remove(pollset,&connection->sock_pfd); + } apr_socket_close(connection->sock); connection->sock = NULL; - mrcp_connection_disconnect_raise(connection,agent->vtable); + mrcp_client_agent_disconnect_raise(agent,connection); return TRUE; } + /* calculate actual length of the stream */ stream->text.length = offset + length; stream->pos[length] = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive MRCPv2 Stream %s [%lu bytes]\n%s", - connection->id, - length, - stream->pos); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive MRCPv2 Stream %s [%"APR_SIZE_T_FMT" bytes]\n%.*s", + connection->id, + length, + connection->verbose == TRUE ? length : 0, + stream->pos); /* reset pos */ apt_text_stream_reset(stream); - /* walk through the stream parsing MRCP messages */ - return mrcp_stream_walk(connection->parser,stream,mrcp_client_message_handler,connection); -} - -static apt_bool_t mrcp_client_agent_control_process(mrcp_connection_agent_t *agent) -{ - apt_bool_t status = TRUE; - apt_bool_t running = TRUE; - connection_task_msg_t *msg; do { - apr_thread_mutex_lock(agent->guard); - msg = apt_cyclic_queue_pop(agent->msg_queue); - apr_thread_mutex_unlock(agent->guard); - if(msg) { - switch(msg->type) { - case CONNECTION_TASK_MSG_ADD_CHANNEL: - mrcp_client_agent_channel_add(agent,msg->channel,msg->descriptor); - break; - case CONNECTION_TASK_MSG_MODIFY_CHANNEL: - mrcp_client_agent_channel_modify(agent,msg->channel,msg->descriptor); - break; - case CONNECTION_TASK_MSG_REMOVE_CHANNEL: - mrcp_client_agent_channel_remove(agent,msg->channel); - break; - case CONNECTION_TASK_MSG_SEND_MESSAGE: - mrcp_client_agent_messsage_send(agent,msg->channel,msg->message); - break; - case CONNECTION_TASK_MSG_TERMINATE: - status = FALSE; - break; - } - } - else { - running = FALSE; + msg_status = mrcp_parser_run(connection->parser,stream,&message); + if(mrcp_client_message_handler(connection,message,msg_status) == FALSE) { + return FALSE; } } - while(running == TRUE); - return status; + while(apt_text_is_eos(stream) == FALSE); + + /* scroll remaining stream */ + apt_text_stream_scroll(stream); + return TRUE; } -static apt_bool_t mrcp_client_agent_task_run(apt_task_t *task) +/* Process task message */ +static apt_bool_t mrcp_client_agent_msg_process(apt_task_t *task, apt_task_msg_t *task_msg) { - mrcp_connection_agent_t *agent = apt_task_object_get(task); - apt_bool_t running = TRUE; - apr_status_t status; - apr_int32_t num; - const apr_pollfd_t *ret_pfd; - int i; - - if(!agent) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Start MRCPv2 Agent"); - return FALSE; + apt_poller_task_t *poller_task = apt_task_object_get(task); + mrcp_connection_agent_t *agent = apt_poller_task_object_get(poller_task); + connection_task_msg_t *msg = (connection_task_msg_t*) task_msg->data; + + switch(msg->type) { + case CONNECTION_TASK_MSG_ADD_CHANNEL: + mrcp_client_agent_channel_add(agent,msg->channel,msg->descriptor); + break; + case CONNECTION_TASK_MSG_MODIFY_CHANNEL: + mrcp_client_agent_channel_modify(agent,msg->channel,msg->descriptor); + break; + case CONNECTION_TASK_MSG_REMOVE_CHANNEL: + mrcp_client_agent_channel_remove(agent,msg->channel); + break; + case CONNECTION_TASK_MSG_SEND_MESSAGE: + mrcp_client_agent_messsage_send(agent,msg->channel,msg->message); + break; } - agent->pollset = apt_pollset_create((apr_uint32_t)agent->max_connection_count,agent->pool); - if(!agent->pollset) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); - return FALSE; - } - - /* explicitly indicate task is ready to process messages */ - apt_task_ready(agent->task); - - while(running) { - status = apt_pollset_poll(agent->pollset, -1, &num, &ret_pfd); - if(status != APR_SUCCESS) { - continue; - } - for(i = 0; i < num; i++) { - if(apt_pollset_is_wakeup(agent->pollset,&ret_pfd[i])) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Control Message"); - if(mrcp_client_agent_control_process(agent) == FALSE) { - running = FALSE; - break; - } - continue; - } - - mrcp_client_agent_messsage_receive(agent,ret_pfd[i].client_data); - } - } - - apt_pollset_destroy(agent->pollset); - agent->pollset = NULL; - - apt_task_child_terminate(agent->task); return TRUE; } -static apt_bool_t mrcp_client_agent_task_terminate(apt_task_t *task) +/* Timer callback */ +static void mrcp_client_timer_proc(apt_timer_t *timer, void *obj) { - apt_bool_t status = FALSE; - mrcp_connection_agent_t *agent = apt_task_object_get(task); - if(agent->pollset) { - connection_task_msg_t *msg = apr_pcalloc(agent->pool,sizeof(connection_task_msg_t)); - msg->type = CONNECTION_TASK_MSG_TERMINATE; - - apr_thread_mutex_lock(agent->guard); - status = apt_cyclic_queue_push(agent->msg_queue,msg); - apr_thread_mutex_unlock(agent->guard); - if(apt_pollset_wakeup(agent->pollset) == TRUE) { - status = TRUE; - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Control Message"); + mrcp_control_channel_t *channel = obj; + if(!channel) { + return; + } + + if(channel->request_timer == timer) { + if(channel->active_request) { + mrcp_client_agent_request_cancel(channel->agent,channel,channel->active_request); + channel->active_request = NULL; } } - return status; } diff --git a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_connection.c b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_connection.c index d174cb78d0..29a06abd87 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_connection.c +++ b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_connection.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_connection.c 1710 2010-05-24 17:36:19Z achaloyan $ */ #include "mrcp_connection.h" @@ -32,13 +34,17 @@ mrcp_connection_t* mrcp_connection_create() connection->r_sockaddr = NULL; connection->sock = NULL; connection->id = NULL; + connection->verbose = TRUE; connection->access_count = 0; connection->it = NULL; connection->channel_table = apr_hash_make(pool); - apt_text_stream_init(&connection->rx_stream,connection->rx_buffer,sizeof(connection->rx_buffer)-1); - apt_text_stream_init(&connection->tx_stream,connection->tx_buffer,sizeof(connection->tx_buffer)-1); connection->parser = NULL; connection->generator = NULL; + connection->rx_buffer = NULL; + connection->rx_buffer_size = 0; + connection->tx_buffer = NULL; + connection->tx_buffer_size = 0; + return connection; } @@ -60,7 +66,7 @@ apt_bool_t mrcp_connection_channel_add(mrcp_connection_t *connection, mrcp_contr return TRUE; } -mrcp_control_channel_t* mrcp_connection_channel_find(mrcp_connection_t *connection, const apt_str_t *identifier) +mrcp_control_channel_t* mrcp_connection_channel_find(const mrcp_connection_t *connection, const apt_str_t *identifier) { if(!connection || !identifier) { return NULL; diff --git a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_control_descriptor.c b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_control_descriptor.c index de0de51aa9..0f8fd8b1f4 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_control_descriptor.c +++ b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_control_descriptor.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_control_descriptor.c 1710 2010-05-24 17:36:19Z achaloyan $ */ #include "apt_string_table.h" @@ -133,7 +135,7 @@ MRCP_DECLARE(void) mrcp_cmid_add(apr_array_header_t *cmid_arr, apr_size_t cmid) } /** Find cmid in cmid_arr */ -MRCP_DECLARE(apt_bool_t) mrcp_cmid_find(apr_array_header_t *cmid_arr, apr_size_t cmid) +MRCP_DECLARE(apt_bool_t) mrcp_cmid_find(const apr_array_header_t *cmid_arr, apr_size_t cmid) { int i; for(i=0; inelts; i++) { diff --git a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_server_connection.c b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_server_connection.c index 0b370a6498..f85a3813cd 100644 --- a/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_server_connection.c +++ b/libs/unimrcp/libs/mrcpv2-transport/src/mrcp_server_connection.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_server_connection.c 1792 2011-01-10 21:08:52Z achaloyan $ */ #include "mrcp_connection.h" @@ -20,33 +22,27 @@ #include "mrcp_resource_factory.h" #include "mrcp_message.h" #include "apt_text_stream.h" -#include "apt_task.h" +#include "apt_poller_task.h" #include "apt_pool.h" -#include "apt_pollset.h" -#include "apt_cyclic_queue.h" #include "apt_log.h" -#define MRCPV2_CONNECTION_TASK_NAME "TCP/MRCPv2 Connection Agent" struct mrcp_connection_agent_t { - apr_pool_t *pool; - apt_task_t *task; - mrcp_resource_factory_t *resource_factory; + apr_pool_t *pool; + apt_poller_task_t *task; + const mrcp_resource_factory_t *resource_factory; - apt_obj_list_t *connection_list; - mrcp_connection_t *null_connection; + apt_obj_list_t *connection_list; + mrcp_connection_t *null_connection; - apt_bool_t force_new_connection; - apr_size_t max_connection_count; + apt_bool_t force_new_connection; + apr_size_t tx_buffer_size; + apr_size_t rx_buffer_size; - apr_sockaddr_t *sockaddr; /* Listening socket */ - apr_socket_t *listen_sock; - apr_pollfd_t listen_sock_pfd; - - apr_thread_mutex_t *guard; - apt_cyclic_queue_t *msg_queue; - apt_pollset_t *pollset; + apr_sockaddr_t *sockaddr; + apr_socket_t *listen_sock; + apr_pollfd_t listen_sock_pfd; void *obj; const mrcp_connection_event_vtable_t *vtable; @@ -56,8 +52,7 @@ typedef enum { CONNECTION_TASK_MSG_ADD_CHANNEL, CONNECTION_TASK_MSG_MODIFY_CHANNEL, CONNECTION_TASK_MSG_REMOVE_CHANNEL, - CONNECTION_TASK_MSG_SEND_MESSAGE, - CONNECTION_TASK_MSG_TERMINATE + CONNECTION_TASK_MSG_SEND_MESSAGE } connection_task_msg_type_e; typedef struct connection_task_msg_t connection_task_msg_t; @@ -69,94 +64,125 @@ struct connection_task_msg_t { mrcp_message_t *message; }; -static apt_bool_t mrcp_server_agent_task_run(apt_task_t *task); -static apt_bool_t mrcp_server_agent_task_terminate(apt_task_t *task); -static apt_bool_t mrcp_server_agent_task_on_destroy(apt_task_t *task); +static apt_bool_t mrcp_server_agent_on_destroy(apt_task_t *task); +static apt_bool_t mrcp_server_agent_msg_process(apt_task_t *task, apt_task_msg_t *task_msg); +static apt_bool_t mrcp_server_poller_signal_process(void *obj, const apr_pollfd_t *descriptor); + +static apt_bool_t mrcp_server_agent_listening_socket_create(mrcp_connection_agent_t *agent); +static void mrcp_server_agent_listening_socket_destroy(mrcp_connection_agent_t *agent); + /** Create connection agent */ MRCP_DECLARE(mrcp_connection_agent_t*) mrcp_server_connection_agent_create( + const char *id, const char *listen_ip, apr_port_t listen_port, apr_size_t max_connection_count, apt_bool_t force_new_connection, apr_pool_t *pool) { + apt_task_t *task; apt_task_vtable_t *vtable; + apt_task_msg_pool_t *msg_pool; mrcp_connection_agent_t *agent; if(!listen_ip) { return NULL; } - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create "MRCPV2_CONNECTION_TASK_NAME" %s:%hu [%"APR_SIZE_T_FMT"]", - listen_ip,listen_port,max_connection_count); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv2 Agent [%s] %s:%hu [%"APR_SIZE_T_FMT"]", + id,listen_ip,listen_port,max_connection_count); agent = apr_palloc(pool,sizeof(mrcp_connection_agent_t)); agent->pool = pool; agent->sockaddr = NULL; agent->listen_sock = NULL; - agent->pollset = NULL; - agent->max_connection_count = max_connection_count; agent->force_new_connection = force_new_connection; + agent->rx_buffer_size = MRCP_STREAM_BUFFER_SIZE; + agent->tx_buffer_size = MRCP_STREAM_BUFFER_SIZE; apr_sockaddr_info_get(&agent->sockaddr,listen_ip,APR_INET,listen_port,0,agent->pool); if(!agent->sockaddr) { return NULL; } - agent->task = apt_task_create(agent,NULL,pool); + msg_pool = apt_task_msg_pool_create_dynamic(sizeof(connection_task_msg_t),pool); + + agent->task = apt_poller_task_create( + max_connection_count + 1, + mrcp_server_poller_signal_process, + agent, + msg_pool, + pool); if(!agent->task) { return NULL; } - apt_task_name_set(agent->task,MRCPV2_CONNECTION_TASK_NAME); - vtable = apt_task_vtable_get(agent->task); - if(vtable) { - vtable->run = mrcp_server_agent_task_run; - vtable->terminate = mrcp_server_agent_task_terminate; - vtable->destroy = mrcp_server_agent_task_on_destroy; + task = apt_poller_task_base_get(agent->task); + if(task) { + apt_task_name_set(task,id); } - apt_task_auto_ready_set(agent->task,FALSE); - agent->msg_queue = apt_cyclic_queue_create(CYCLIC_QUEUE_DEFAULT_SIZE); - apr_thread_mutex_create(&agent->guard,APR_THREAD_MUTEX_UNNESTED,pool); + vtable = apt_poller_task_vtable_get(agent->task); + if(vtable) { + vtable->destroy = mrcp_server_agent_on_destroy; + vtable->process_msg = mrcp_server_agent_msg_process; + } agent->connection_list = NULL; agent->null_connection = NULL; + + if(mrcp_server_agent_listening_socket_create(agent) == TRUE) { + /* add listening socket to pollset */ + apt_pollset_t *pollset = apt_poller_task_pollset_get(agent->task); + memset(&agent->listen_sock_pfd,0,sizeof(apr_pollfd_t)); + agent->listen_sock_pfd.desc_type = APR_POLL_SOCKET; + agent->listen_sock_pfd.reqevents = APR_POLLIN; + agent->listen_sock_pfd.desc.s = agent->listen_sock; + agent->listen_sock_pfd.client_data = agent->listen_sock; + if(apt_pollset_add(pollset, &agent->listen_sock_pfd) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add Listening Socket to Pollset"); + mrcp_server_agent_listening_socket_destroy(agent); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Listening Socket"); + } return agent; } -/** Virtual destroy handler. */ -static apt_bool_t mrcp_server_agent_task_on_destroy(apt_task_t *task) +static apt_bool_t mrcp_server_agent_on_destroy(apt_task_t *task) { - mrcp_connection_agent_t *agent = apt_task_object_get(task); - if(agent->guard) { - apr_thread_mutex_destroy(agent->guard); - agent->guard = NULL; - } - if(agent->msg_queue) { - apt_cyclic_queue_destroy(agent->msg_queue); - agent->msg_queue = NULL; + apt_poller_task_t *poller_task = apt_task_object_get(task); + mrcp_connection_agent_t *agent = apt_poller_task_object_get(poller_task); + + apt_pollset_t *pollset = apt_poller_task_pollset_get(poller_task); + if(pollset) { + apt_pollset_remove(pollset,&agent->listen_sock_pfd); } + mrcp_server_agent_listening_socket_destroy(agent); + + apt_poller_task_cleanup(poller_task); return TRUE; } /** Destroy connection agent. */ MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_destroy(mrcp_connection_agent_t *agent) { - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy MRCPv2 Agent"); - return apt_task_destroy(agent->task); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy MRCPv2 Agent [%s]", + mrcp_server_connection_agent_id_get(agent)); + return apt_poller_task_destroy(agent->task); } /** Start connection agent. */ MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_start(mrcp_connection_agent_t *agent) { - return apt_task_start(agent->task); + return apt_poller_task_start(agent->task); } /** Terminate connection agent. */ MRCP_DECLARE(apt_bool_t) mrcp_server_connection_agent_terminate(mrcp_connection_agent_t *agent) { - return apt_task_terminate(agent->task,TRUE); + return apt_poller_task_terminate(agent->task); } /** Set connection event handler. */ @@ -172,31 +198,64 @@ MRCP_DECLARE(void) mrcp_server_connection_agent_handler_set( /** Set MRCP resource factory */ MRCP_DECLARE(void) mrcp_server_connection_resource_factory_set( mrcp_connection_agent_t *agent, - mrcp_resource_factory_t *resource_factroy) + const mrcp_resource_factory_t *resource_factroy) { agent->resource_factory = resource_factroy; } +/** Set rx buffer size */ +MRCP_DECLARE(void) mrcp_server_connection_rx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size) +{ + if(size < MRCP_STREAM_BUFFER_SIZE) { + size = MRCP_STREAM_BUFFER_SIZE; + } + agent->rx_buffer_size = size; +} + +/** Set tx buffer size */ +MRCP_DECLARE(void) mrcp_server_connection_tx_size_set( + mrcp_connection_agent_t *agent, + apr_size_t size) +{ + if(size < MRCP_STREAM_BUFFER_SIZE) { + size = MRCP_STREAM_BUFFER_SIZE; + } + agent->tx_buffer_size = size; +} + /** Get task */ -MRCP_DECLARE(apt_task_t*) mrcp_server_connection_agent_task_get(mrcp_connection_agent_t *agent) +MRCP_DECLARE(apt_task_t*) mrcp_server_connection_agent_task_get(const mrcp_connection_agent_t *agent) { - return agent->task; + return apt_poller_task_base_get(agent->task); } /** Get external object */ -MRCP_DECLARE(void*) mrcp_server_connection_agent_object_get(mrcp_connection_agent_t *agent) +MRCP_DECLARE(void*) mrcp_server_connection_agent_object_get(const mrcp_connection_agent_t *agent) { return agent->obj; } +/** Get string identifier */ +MRCP_DECLARE(const char*) mrcp_server_connection_agent_id_get(const mrcp_connection_agent_t *agent) +{ + apt_task_t *task = apt_poller_task_base_get(agent->task); + return apt_task_name_get(task); +} + + /** Create MRCPv2 control channel */ MRCP_DECLARE(mrcp_control_channel_t*) mrcp_server_control_channel_create(mrcp_connection_agent_t *agent, void *obj, apr_pool_t *pool) { mrcp_control_channel_t *channel = apr_palloc(pool,sizeof(mrcp_control_channel_t)); channel->agent = agent; channel->connection = NULL; + channel->active_request = NULL; + channel->request_timer = NULL; channel->removed = FALSE; channel->obj = obj; + channel->log_obj = NULL; channel->pool = pool; return channel; } @@ -213,6 +272,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_control_channel_destroy(mrcp_control_channe return TRUE; } +/** Signal task message */ static apt_bool_t mrcp_server_control_message_signal( connection_task_msg_type_e type, mrcp_connection_agent_t *agent, @@ -220,22 +280,18 @@ static apt_bool_t mrcp_server_control_message_signal( mrcp_control_descriptor_t *descriptor, mrcp_message_t *message) { - apt_bool_t status; - connection_task_msg_t *msg = apr_palloc(channel->pool,sizeof(connection_task_msg_t)); - msg->type = type; - msg->agent = agent; - msg->channel = channel; - msg->descriptor = descriptor; - msg->message = message; - - apr_thread_mutex_lock(agent->guard); - status = apt_cyclic_queue_push(agent->msg_queue,msg); - apr_thread_mutex_unlock(agent->guard); - if(apt_pollset_wakeup(agent->pollset) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Control Message"); - status = FALSE; + apt_task_t *task = apt_poller_task_base_get(agent->task); + apt_task_msg_t *task_msg = apt_task_msg_get(task); + if(task_msg) { + connection_task_msg_t *msg = (connection_task_msg_t*)task_msg->data; + msg->type = type; + msg->agent = agent; + msg->channel = channel; + msg->descriptor = descriptor; + msg->message = message; + apt_task_msg_signal(task,task_msg); } - return status; + return TRUE; } /** Add MRCPv2 control channel */ @@ -262,8 +318,7 @@ MRCP_DECLARE(apt_bool_t) mrcp_server_control_message_send(mrcp_control_channel_t return mrcp_server_control_message_signal(CONNECTION_TASK_MSG_SEND_MESSAGE,channel->agent,channel,NULL,message); } - -static apt_bool_t mrcp_server_agent_listen_socket_create(mrcp_connection_agent_t *agent) +static apt_bool_t mrcp_server_agent_listening_socket_create(mrcp_connection_agent_t *agent) { apr_status_t status; if(!agent->sockaddr) { @@ -296,7 +351,7 @@ static apt_bool_t mrcp_server_agent_listen_socket_create(mrcp_connection_agent_t return TRUE; } -static void mrcp_server_agent_listen_socket_destroy(mrcp_connection_agent_t *agent) +static void mrcp_server_agent_listening_socket_destroy(mrcp_connection_agent_t *agent) { if(agent->listen_sock) { apr_socket_close(agent->listen_sock); @@ -304,44 +359,6 @@ static void mrcp_server_agent_listen_socket_destroy(mrcp_connection_agent_t *age } } -static apt_bool_t mrcp_server_agent_pollset_create(mrcp_connection_agent_t *agent) -{ - /* create pollset */ - agent->pollset = apt_pollset_create((apr_uint32_t)agent->max_connection_count + 1, agent->pool); - if(!agent->pollset) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); - return FALSE; - } - - if(mrcp_server_agent_listen_socket_create(agent) == TRUE) { - /* add listen socket to pollset */ - memset(&agent->listen_sock_pfd,0,sizeof(apr_pollfd_t)); - agent->listen_sock_pfd.desc_type = APR_POLL_SOCKET; - agent->listen_sock_pfd.reqevents = APR_POLLIN; - agent->listen_sock_pfd.desc.s = agent->listen_sock; - agent->listen_sock_pfd.client_data = agent->listen_sock; - if(apt_pollset_add(agent->pollset, &agent->listen_sock_pfd) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add Listen Socket to Pollset"); - mrcp_server_agent_listen_socket_destroy(agent); - } - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Listen Socket"); - } - - return TRUE; -} - -static void mrcp_server_agent_pollset_destroy(mrcp_connection_agent_t *agent) -{ - mrcp_server_agent_listen_socket_destroy(agent); - if(agent->pollset) { - apt_pollset_destroy(agent->pollset); - agent->pollset = NULL; - } -} - - static mrcp_control_channel_t* mrcp_connection_channel_associate(mrcp_connection_agent_t *agent, mrcp_connection_t *connection, const mrcp_message_t *message) { apt_str_t identifier; @@ -356,7 +373,7 @@ static mrcp_control_channel_t* mrcp_connection_channel_associate(mrcp_connection if(channel) { mrcp_connection_channel_remove(agent->null_connection,channel); mrcp_connection_channel_add(connection,channel); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Move Control Channel <%s> to Connection %s [%d]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Attach Control Channel <%s> to Connection %s [%d]", channel->identifier.buf, connection->id, apr_hash_count(connection->channel_table)); @@ -395,7 +412,7 @@ static apt_bool_t mrcp_connection_remove(mrcp_connection_agent_t *agent, mrcp_co } if(agent->null_connection) { if(apt_list_is_empty(agent->connection_list) == TRUE && apr_hash_count(agent->null_connection->channel_table) == 0) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Pending Connection"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Container for Pending Control Channels"); mrcp_connection_destroy(agent->null_connection); agent->null_connection = NULL; agent->connection_list = NULL; @@ -410,11 +427,13 @@ static apt_bool_t mrcp_server_agent_connection_accept(mrcp_connection_agent_t *a char *remote_ip = NULL; apr_socket_t *sock; apr_pool_t *pool; + apt_pollset_t *pollset = apt_poller_task_pollset_get(agent->task); mrcp_connection_t *connection; if(!agent->null_connection) { pool = apt_pool_create(); if(apr_socket_accept(&sock,agent->listen_sock,pool) != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Accept Connection"); return FALSE; } apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Rejected TCP/MRCPv2 Connection"); @@ -425,6 +444,7 @@ static apt_bool_t mrcp_server_agent_connection_accept(mrcp_connection_agent_t *a pool = agent->null_connection->pool; if(apr_socket_accept(&sock,agent->listen_sock,pool) != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Accept Connection"); return FALSE; } @@ -433,6 +453,7 @@ static apt_bool_t mrcp_server_agent_connection_accept(mrcp_connection_agent_t *a if(apr_socket_addr_get(&connection->r_sockaddr,APR_REMOTE,sock) != APR_SUCCESS || apr_socket_addr_get(&connection->l_sockaddr,APR_LOCAL,sock) != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Get Socket Address"); apr_socket_close(sock); mrcp_connection_destroy(connection); return FALSE; @@ -450,8 +471,8 @@ static apt_bool_t mrcp_server_agent_connection_accept(mrcp_connection_agent_t *a connection->sock_pfd.reqevents = APR_POLLIN; connection->sock_pfd.desc.s = connection->sock; connection->sock_pfd.client_data = connection; - if(apt_pollset_add(agent->pollset, &connection->sock_pfd) != TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add to Pollset"); + if(apt_pollset_add(pollset, &connection->sock_pfd) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add to Pollset %s",connection->id); apr_socket_close(sock); mrcp_connection_destroy(connection); return FALSE; @@ -460,15 +481,30 @@ static apt_bool_t mrcp_server_agent_connection_accept(mrcp_connection_agent_t *a apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Accepted TCP/MRCPv2 Connection %s",connection->id); connection->agent = agent; connection->it = apt_list_push_back(agent->connection_list,connection,connection->pool); + connection->parser = mrcp_parser_create(agent->resource_factory,connection->pool); connection->generator = mrcp_generator_create(agent->resource_factory,connection->pool); + + connection->tx_buffer_size = agent->tx_buffer_size; + connection->tx_buffer = apr_palloc(connection->pool,connection->tx_buffer_size+1); + + connection->rx_buffer_size = agent->rx_buffer_size; + connection->rx_buffer = apr_palloc(connection->pool,connection->rx_buffer_size+1); + apt_text_stream_init(&connection->rx_stream,connection->rx_buffer,connection->rx_buffer_size); + + if(apt_log_masking_get() != APT_LOG_MASKING_NONE) { + connection->verbose = FALSE; + mrcp_parser_verbose_set(connection->parser,TRUE); + mrcp_generator_verbose_set(connection->generator,TRUE); + } return TRUE; } static apt_bool_t mrcp_server_agent_connection_close(mrcp_connection_agent_t *agent, mrcp_connection_t *connection) { + apt_pollset_t *pollset = apt_poller_task_pollset_get(agent->task); apt_log(APT_LOG_MARK,APT_PRIO_INFO,"TCP/MRCPv2 Peer Disconnected %s",connection->id); - apt_pollset_remove(agent->pollset,&connection->sock_pfd); + apt_pollset_remove(pollset,&connection->sock_pfd); apr_socket_close(connection->sock); connection->sock = NULL; if(!connection->access_count) { @@ -503,12 +539,12 @@ static apt_bool_t mrcp_server_agent_channel_add(mrcp_connection_agent_t *agent, } if(!agent->null_connection) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Pending Connection"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Container for Pending Control Channels"); agent->null_connection = mrcp_connection_create(); agent->connection_list = apt_list_create(agent->null_connection->pool); } mrcp_connection_channel_add(agent->null_connection,channel); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add Control Channel <%s> to Pending Connection [%d]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add Pending Control Channel <%s> [%d]", channel->identifier.buf, apr_hash_count(agent->null_connection->channel_table)); /* send response */ @@ -536,7 +572,7 @@ static apt_bool_t mrcp_server_agent_channel_remove(mrcp_connection_agent_t *agen if(!connection->access_count) { if(connection == agent->null_connection) { if(apt_list_is_empty(agent->connection_list) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Pending Connection"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy Container for Pending Control Channels"); mrcp_connection_destroy(agent->null_connection); agent->null_connection = NULL; agent->connection_list = NULL; @@ -545,7 +581,7 @@ static apt_bool_t mrcp_server_agent_channel_remove(mrcp_connection_agent_t *agen else if(!connection->sock) { mrcp_connection_remove(agent,connection); /* set connection to be destroyed on channel destroy */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Mark Connection for Late Destroy"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Mark Connection for Removal %s",connection->id); channel->connection = connection; channel->removed = TRUE; } @@ -557,27 +593,27 @@ static apt_bool_t mrcp_server_agent_channel_remove(mrcp_connection_agent_t *agen static apt_bool_t mrcp_server_agent_messsage_send(mrcp_connection_agent_t *agent, mrcp_connection_t *connection, mrcp_message_t *message) { apt_bool_t status = FALSE; - apt_text_stream_t *stream; - mrcp_stream_status_e result; + apt_text_stream_t stream; + apt_message_status_e result; if(!connection || !connection->sock) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No MRCPv2 Connection"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Null MRCPv2 Connection "APT_SIDRES_FMT,MRCP_MESSAGE_SIDRES(message)); return FALSE; } - stream = &connection->tx_stream; - mrcp_generator_message_set(connection->generator,message); do { - apt_text_stream_init(&connection->tx_stream,connection->tx_buffer,sizeof(connection->tx_buffer)-1); - result = mrcp_generator_run(connection->generator,stream); - if(result != MRCP_STREAM_STATUS_INVALID) { - stream->text.length = stream->pos - stream->text.buf; - *stream->pos = '\0'; - - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send MRCPv2 Stream %s [%lu bytes]\n%s", - connection->id, - stream->text.length, - stream->text.buf); - if(apr_socket_send(connection->sock,stream->text.buf,&stream->text.length) == APR_SUCCESS) { + apt_text_stream_init(&stream,connection->tx_buffer,connection->tx_buffer_size); + result = mrcp_generator_run(connection->generator,message,&stream); + if(result != APT_MESSAGE_STATUS_INVALID) { + stream.text.length = stream.pos - stream.text.buf; + *stream.pos = '\0'; + + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send MRCPv2 Stream %s [%"APR_SIZE_T_FMT" bytes]\n%.*s", + connection->id, + stream.text.length, + connection->verbose == TRUE ? stream.text.length : 0, + stream.text.buf); + + if(apr_socket_send(connection->sock,stream.text.buf,&stream.text.length) == APR_SUCCESS) { status = TRUE; } else { @@ -588,32 +624,30 @@ static apt_bool_t mrcp_server_agent_messsage_send(mrcp_connection_agent_t *agent apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Generate MRCPv2 Stream"); } } - while(result == MRCP_STREAM_STATUS_INCOMPLETE); + while(result == APT_MESSAGE_STATUS_INCOMPLETE); return status; } -static apt_bool_t mrcp_server_message_handler(void *obj, mrcp_message_t *message, mrcp_stream_status_e status) +static apt_bool_t mrcp_server_message_handler(mrcp_connection_t *connection, mrcp_message_t *message, apt_message_status_e status) { - mrcp_connection_t *connection = obj; mrcp_connection_agent_t *agent = connection->agent; - if(status == MRCP_STREAM_STATUS_COMPLETE) { + if(status == APT_MESSAGE_STATUS_COMPLETE) { /* message is completely parsed */ mrcp_control_channel_t *channel = mrcp_connection_channel_associate(agent,connection,message); if(channel) { mrcp_connection_message_receive(agent->vtable,channel,message); } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find Channel <%s@%s> in Connection %s", - message->channel_id.session_id.buf, - message->channel_id.resource_name.buf, + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Find Channel "APT_SIDRES_FMT" in Connection %s", + MRCP_MESSAGE_SIDRES(message), connection->id); } } - else if(status == MRCP_STREAM_STATUS_INVALID) { + else if(status == APT_MESSAGE_STATUS_INVALID) { /* error case */ apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse MRCPv2 Stream"); - if(message->resource) { + if(message && message->resource) { mrcp_message_t *response; response = mrcp_response_create(message,message->pool); response->start_line.status_code = MRCP_STATUS_CODE_UNRECOGNIZED_MESSAGE; @@ -625,149 +659,83 @@ static apt_bool_t mrcp_server_message_handler(void *obj, mrcp_message_t *message return TRUE; } -static apt_bool_t mrcp_server_agent_messsage_receive(mrcp_connection_agent_t *agent, mrcp_connection_t *connection) +/* Receive MRCP message through TCP/MRCPv2 connection */ +static apt_bool_t mrcp_server_poller_signal_process(void *obj, const apr_pollfd_t *descriptor) { + mrcp_connection_agent_t *agent = obj; + mrcp_connection_t *connection = descriptor->client_data; apr_status_t status; apr_size_t offset; apr_size_t length; apt_text_stream_t *stream; + mrcp_message_t *message; + apt_message_status_e msg_status; + if(descriptor->desc.s == agent->listen_sock) { + return mrcp_server_agent_connection_accept(agent); + } + if(!connection || !connection->sock) { return FALSE; } stream = &connection->rx_stream; - - /* init length of the stream */ - stream->text.length = sizeof(connection->rx_buffer)-1; + /* calculate offset remaining from the previous receive / if any */ offset = stream->pos - stream->text.buf; /* calculate available length */ - length = stream->text.length - offset; + length = connection->rx_buffer_size - offset; + status = apr_socket_recv(connection->sock,stream->pos,&length); if(status == APR_EOF || length == 0) { return mrcp_server_agent_connection_close(agent,connection); } + /* calculate actual length of the stream */ stream->text.length = offset + length; stream->pos[length] = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive MRCPv2 Stream %s [%lu bytes]\n%s", - connection->id, - length, - stream->pos); + + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive MRCPv2 Stream %s [%"APR_SIZE_T_FMT" bytes]\n%.*s", + connection->id, + length, + connection->verbose == TRUE ? length : 0, + stream->pos); /* reset pos */ apt_text_stream_reset(stream); - /* walk through the stream parsing MRCP messages */ - return mrcp_stream_walk(connection->parser,stream,mrcp_server_message_handler,connection); -} - -static apt_bool_t mrcp_server_agent_control_process(mrcp_connection_agent_t *agent) -{ - apt_bool_t status = TRUE; - apt_bool_t running = TRUE; - connection_task_msg_t *msg; do { - apr_thread_mutex_lock(agent->guard); - msg = apt_cyclic_queue_pop(agent->msg_queue); - apr_thread_mutex_unlock(agent->guard); - if(msg) { - switch(msg->type) { - case CONNECTION_TASK_MSG_ADD_CHANNEL: - mrcp_server_agent_channel_add(agent,msg->channel,msg->descriptor); - break; - case CONNECTION_TASK_MSG_MODIFY_CHANNEL: - mrcp_server_agent_channel_modify(agent,msg->channel,msg->descriptor); - break; - case CONNECTION_TASK_MSG_REMOVE_CHANNEL: - mrcp_server_agent_channel_remove(agent,msg->channel); - break; - case CONNECTION_TASK_MSG_SEND_MESSAGE: - mrcp_server_agent_messsage_send(agent,msg->channel->connection,msg->message); - break; - case CONNECTION_TASK_MSG_TERMINATE: - status = FALSE; - break; - } - } - else { - running = FALSE; - } - } - while(running == TRUE); - return status; -} - -static apt_bool_t mrcp_server_agent_task_run(apt_task_t *task) -{ - mrcp_connection_agent_t *agent = apt_task_object_get(task); - apt_bool_t running = TRUE; - apr_status_t status; - apr_int32_t num; - const apr_pollfd_t *ret_pfd; - int i; - - if(!agent) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Start MRCPv2 Agent"); - return FALSE; - } - - if(mrcp_server_agent_pollset_create(agent) == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create Pollset"); - return FALSE; - } - - /* explicitly indicate task is ready to process messages */ - apt_task_ready(agent->task); - - while(running) { - status = apt_pollset_poll(agent->pollset, -1, &num, &ret_pfd); - if(status != APR_SUCCESS) { - continue; - } - for(i = 0; i < num; i++) { - if(ret_pfd[i].desc.s == agent->listen_sock) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Accept MRCPv2 Connection"); - mrcp_server_agent_connection_accept(agent); - continue; - } - if(apt_pollset_is_wakeup(agent->pollset,&ret_pfd[i])) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process Control Message"); - if(mrcp_server_agent_control_process(agent) == FALSE) { - running = FALSE; - break; - } - continue; - } - - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Process MRCPv2 Message"); - mrcp_server_agent_messsage_receive(agent,ret_pfd[i].client_data); + msg_status = mrcp_parser_run(connection->parser,stream,&message); + if(mrcp_server_message_handler(connection,message,msg_status) == FALSE) { + return FALSE; } } + while(apt_text_is_eos(stream) == FALSE); - mrcp_server_agent_pollset_destroy(agent); - - apt_task_child_terminate(agent->task); + /* scroll remaining stream */ + apt_text_stream_scroll(stream); return TRUE; } -static apt_bool_t mrcp_server_agent_task_terminate(apt_task_t *task) +/* Process task message */ +static apt_bool_t mrcp_server_agent_msg_process(apt_task_t *task, apt_task_msg_t *task_msg) { - apt_bool_t status = FALSE; - mrcp_connection_agent_t *agent = apt_task_object_get(task); - if(agent->pollset) { - connection_task_msg_t *msg = apr_pcalloc(agent->pool,sizeof(connection_task_msg_t)); - msg->type = CONNECTION_TASK_MSG_TERMINATE; - - apr_thread_mutex_lock(agent->guard); - status = apt_cyclic_queue_push(agent->msg_queue,msg); - apr_thread_mutex_unlock(agent->guard); - if(apt_pollset_wakeup(agent->pollset) == TRUE) { - status = TRUE; - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Control Message"); - } + apt_poller_task_t *poller_task = apt_task_object_get(task); + mrcp_connection_agent_t *agent = apt_poller_task_object_get(poller_task); + connection_task_msg_t *msg = (connection_task_msg_t*) task_msg->data; + switch(msg->type) { + case CONNECTION_TASK_MSG_ADD_CHANNEL: + mrcp_server_agent_channel_add(agent,msg->channel,msg->descriptor); + break; + case CONNECTION_TASK_MSG_MODIFY_CHANNEL: + mrcp_server_agent_channel_modify(agent,msg->channel,msg->descriptor); + break; + case CONNECTION_TASK_MSG_REMOVE_CHANNEL: + mrcp_server_agent_channel_remove(agent,msg->channel); + break; + case CONNECTION_TASK_MSG_SEND_MESSAGE: + mrcp_server_agent_messsage_send(agent,msg->channel->connection,msg->message); + break; } - return status; + + return TRUE; } diff --git a/libs/unimrcp/libs/uni-rtsp/include/rtsp.h b/libs/unimrcp/libs/uni-rtsp/include/rtsp.h index d2d029f635..fbc55d6ef1 100644 --- a/libs/unimrcp/libs/uni-rtsp/include/rtsp.h +++ b/libs/unimrcp/libs/uni-rtsp/include/rtsp.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __RTSP_H__ -#define __RTSP_H__ +#ifndef RTSP_H +#define RTSP_H /** * @file rtsp.h @@ -40,4 +42,4 @@ #define RTSP_DECLARE(type) type #endif -#endif /*__RTSP_H__*/ +#endif /* RTSP_H */ diff --git a/libs/unimrcp/libs/uni-rtsp/include/rtsp_client.h b/libs/unimrcp/libs/uni-rtsp/include/rtsp_client.h index 4d3bd1f1c6..0209e7211a 100644 --- a/libs/unimrcp/libs/uni-rtsp/include/rtsp_client.h +++ b/libs/unimrcp/libs/uni-rtsp/include/rtsp_client.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_client.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __RTSP_CLIENT_H__ -#define __RTSP_CLIENT_H__ +#ifndef RTSP_CLIENT_H +#define RTSP_CLIENT_H /** * @file rtsp_client.h @@ -50,12 +52,14 @@ struct rtsp_client_vtable_t { /** * Create RTSP client. * @param max_connection_count the number of max RTSP connections + * @param request_timeout the request timeout to set * @param obj the external object to send event to * @param handler the response/event handler * @param pool the pool to allocate memory from */ RTSP_DECLARE(rtsp_client_t*) rtsp_client_create( apr_size_t max_connection_count, + apr_size_t request_timeout, void *obj, const rtsp_client_vtable_t *handler, apr_pool_t *pool); @@ -82,13 +86,13 @@ RTSP_DECLARE(apt_bool_t) rtsp_client_terminate(rtsp_client_t *client); * Get task. * @param client the client to get task from */ -RTSP_DECLARE(apt_task_t*) rtsp_client_task_get(rtsp_client_t *client); +RTSP_DECLARE(apt_task_t*) rtsp_client_task_get(const rtsp_client_t *client); /** * Get external object. * @param client the client to get object from */ -RTSP_DECLARE(void*) rtsp_client_object_get(rtsp_client_t *client); +RTSP_DECLARE(void*) rtsp_client_object_get(const rtsp_client_t *client); /** @@ -146,4 +150,4 @@ RTSP_DECLARE(const apt_str_t*) rtsp_client_session_id_get(const rtsp_client_sess APT_END_EXTERN_C -#endif /*__RTSP_CLIENT_H__*/ +#endif /* RTSP_CLIENT_H */ diff --git a/libs/unimrcp/libs/uni-rtsp/include/rtsp_header.h b/libs/unimrcp/libs/uni-rtsp/include/rtsp_header.h index 2a71c6ed2d..4345ad4606 100644 --- a/libs/unimrcp/libs/uni-rtsp/include/rtsp_header.h +++ b/libs/unimrcp/libs/uni-rtsp/include/rtsp_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_header.h 1648 2010-04-12 20:03:59Z achaloyan $ */ -#ifndef __RTSP_HEADER_H__ -#define __RTSP_HEADER_H__ +#ifndef RTSP_HEADER_H +#define RTSP_HEADER_H /** * @file rtsp_header.h @@ -23,7 +25,7 @@ */ #include "rtsp.h" -#include "apt_text_stream.h" +#include "apt_header_field.h" APT_BEGIN_EXTERN_C @@ -99,9 +101,6 @@ typedef enum { } rtsp_content_type_e; -/** Bit field masks are used to define property set */ -typedef int rtsp_header_property_t; - /** RTSP/RTP port range declaration */ typedef struct rtsp_port_range_t rtsp_port_range_t; @@ -156,8 +155,8 @@ struct rtsp_header_t { /** Content length */ apr_size_t content_length; - /** Property set */ - rtsp_header_property_t property_set; + /** Header section (collection of header fields)*/ + apt_header_section_t header_section; }; @@ -188,7 +187,7 @@ static APR_INLINE void rtsp_transport_init(rtsp_transport_t *transport) } /** Initialize header */ -static APR_INLINE void rtsp_header_init(rtsp_header_t *header) +static APR_INLINE void rtsp_header_init(rtsp_header_t *header, apr_pool_t *pool) { header->cseq = 0; rtsp_transport_init(&header->transport); @@ -196,37 +195,38 @@ static APR_INLINE void rtsp_header_init(rtsp_header_t *header) apt_string_reset(&header->rtp_info); header->content_type = RTSP_CONTENT_TYPE_NONE; header->content_length = 0; - header->property_set = 0; + + apt_header_section_init(&header->header_section); + apt_header_section_array_alloc(&header->header_section,RTSP_HEADER_FIELD_COUNT,pool); } -/** Parse RTSP message */ -RTSP_DECLARE(apt_bool_t) rtsp_header_parse(rtsp_header_t *header, apt_text_stream_t *text_stream, apr_pool_t *pool); -/** Generate RTSP message */ -RTSP_DECLARE(apt_bool_t) rtsp_header_generate(rtsp_header_t *header, apt_text_stream_t *text_stream); +/** Add RTSP header field */ +RTSP_DECLARE(apt_bool_t) rtsp_header_field_add(rtsp_header_t *header, apt_header_field_t *header_field, apr_pool_t *pool); +/** Parse RTSP header fields */ +RTSP_DECLARE(apt_bool_t) rtsp_header_fields_parse(rtsp_header_t *header, apr_pool_t *pool); -/** Add property to property set */ -static APR_INLINE void rtsp_header_property_add(rtsp_header_property_t *property_set, apr_size_t id) -{ - int mask = 1 << id; - *property_set |= mask; -} +/** Add RTSP header field property */ +RTSP_DECLARE(apt_bool_t) rtsp_header_property_add(rtsp_header_t *header, rtsp_header_field_id id, apr_pool_t *pool); -/** Remove property from property set */ -static APR_INLINE void rtsp_header_property_remove(rtsp_header_property_t *property_set, apr_size_t id) +/** Remove RTSP header field property */ +static APR_INLINE apt_bool_t rtsp_header_property_remove(rtsp_header_t *header, rtsp_header_field_id id) { - int mask = 1 << id; - *property_set &= ~mask; + apt_header_field_t *header_field = apt_header_section_field_get(&header->header_section,id); + if(header_field) { + return apt_header_section_field_remove(&header->header_section,header_field); + } + return FALSE; } -/** Check property in property set */ -static APR_INLINE apt_bool_t rtsp_header_property_check(const rtsp_header_property_t *property_set, apr_size_t id) +/** Check RTSP header field property */ +static APR_INLINE apt_bool_t rtsp_header_property_check(const rtsp_header_t *header, rtsp_header_field_id id) { - int mask = 1 << id; - return ((*property_set & mask) == mask) ? TRUE : FALSE; + return apt_header_section_field_check(&header->header_section,id); } + APT_END_EXTERN_C -#endif /*__RTSP_HEADER_H__*/ +#endif /* RTSP_HEADER_H */ diff --git a/libs/unimrcp/libs/uni-rtsp/include/rtsp_message.h b/libs/unimrcp/libs/uni-rtsp/include/rtsp_message.h index ae57237614..71546d31e5 100644 --- a/libs/unimrcp/libs/uni-rtsp/include/rtsp_message.h +++ b/libs/unimrcp/libs/uni-rtsp/include/rtsp_message.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_message.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __RTSP_MESSAGE_H__ -#define __RTSP_MESSAGE_H__ +#ifndef RTSP_MESSAGE_H +#define RTSP_MESSAGE_H /** * @file rtsp_message.h @@ -73,4 +75,4 @@ RTSP_DECLARE(void) rtsp_message_destroy(rtsp_message_t *message); APT_END_EXTERN_C -#endif /*__RTSP_MESSAGE_H__*/ +#endif /* RTSP_MESSAGE_H */ diff --git a/libs/unimrcp/libs/uni-rtsp/include/rtsp_server.h b/libs/unimrcp/libs/uni-rtsp/include/rtsp_server.h index bf57ce176f..19e2131fb3 100644 --- a/libs/unimrcp/libs/uni-rtsp/include/rtsp_server.h +++ b/libs/unimrcp/libs/uni-rtsp/include/rtsp_server.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_server.h 1710 2010-05-24 17:36:19Z achaloyan $ */ -#ifndef __RTSP_SERVER_H__ -#define __RTSP_SERVER_H__ +#ifndef RTSP_SERVER_H +#define RTSP_SERVER_H /** * @file rtsp_server.h @@ -84,13 +86,13 @@ RTSP_DECLARE(apt_bool_t) rtsp_server_terminate(rtsp_server_t *server); * Get task. * @param server the server to get task from */ -RTSP_DECLARE(apt_task_t*) rtsp_server_task_get(rtsp_server_t *server); +RTSP_DECLARE(apt_task_t*) rtsp_server_task_get(const rtsp_server_t *server); /** * Get external object. * @param server the server to get object from */ -RTSP_DECLARE(void*) rtsp_server_object_get(rtsp_server_t *server); +RTSP_DECLARE(void*) rtsp_server_object_get(const rtsp_server_t *server); /** * Send RTSP message. @@ -140,4 +142,4 @@ RTSP_DECLARE(const char*) rtsp_server_session_destination_get(const rtsp_server_ APT_END_EXTERN_C -#endif /*__RTSP_SERVER_H__*/ +#endif /* RTSP_SERVER_H */ diff --git a/libs/unimrcp/libs/uni-rtsp/include/rtsp_start_line.h b/libs/unimrcp/libs/uni-rtsp/include/rtsp_start_line.h index 99b73880e6..8fe8c85c37 100644 --- a/libs/unimrcp/libs/uni-rtsp/include/rtsp_start_line.h +++ b/libs/unimrcp/libs/uni-rtsp/include/rtsp_start_line.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_start_line.h 1632 2010-03-30 20:46:25Z achaloyan $ */ -#ifndef __RTSP_START_LINE_H__ -#define __RTSP_START_LINE_H__ +#ifndef RTSP_START_LINE_H +#define RTSP_START_LINE_H /** * @file rtsp_start_line.h @@ -65,6 +67,8 @@ typedef enum { RTSP_STATUS_CODE_NOT_FOUND = 404, RTSP_STATUS_CODE_METHOD_NOT_ALLOWED = 405, RTSP_STATUS_CODE_NOT_ACCEPTABLE = 406, + RTSP_STATUS_CODE_PROXY_AUTH_REQUIRED = 407, + RTSP_STATUS_CODE_REQUEST_TIMEOUT = 408, RTSP_STATUS_CODE_SESSION_NOT_FOUND = 454, RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR = 500, @@ -80,6 +84,8 @@ typedef enum { RTSP_REASON_PHRASE_NOT_FOUND, RTSP_REASON_PHRASE_METHOD_NOT_ALLOWED, RTSP_REASON_PHRASE_NOT_ACCEPTABLE, + RTSP_REASON_PHRASE_PROXY_AUTH_REQUIRED, + RTSP_REASON_PHRASE_REQUEST_TIMEOUT, RTSP_REASON_PHRASE_SESSION_NOT_FOUND, RTSP_REASON_PHRASE_INTERNAL_SERVER_ERROR, RTSP_REASON_PHRASE_NOT_IMPLEMENTED, @@ -162,7 +168,7 @@ static APR_INLINE void rtsp_start_line_init(rtsp_start_line_t *start_line, rtsp_ } /** Parse RTSP start-line */ -RTSP_DECLARE(apt_bool_t) rtsp_start_line_parse(rtsp_start_line_t *start_line, apt_text_stream_t *text_stream, apr_pool_t *pool); +RTSP_DECLARE(apt_bool_t) rtsp_start_line_parse(rtsp_start_line_t *start_line, apt_str_t *str, apr_pool_t *pool); /** Generate RTSP start-line */ RTSP_DECLARE(apt_bool_t) rtsp_start_line_generate(rtsp_start_line_t *start_line, apt_text_stream_t *text_stream); @@ -172,4 +178,4 @@ RTSP_DECLARE(const apt_str_t*) rtsp_reason_phrase_get(rtsp_reason_phrase_e reaso APT_END_EXTERN_C -#endif /*__RTSP_START_LINE_H__*/ +#endif /* RTSP_START_LINE_H */ diff --git a/libs/unimrcp/libs/uni-rtsp/include/rtsp_stream.h b/libs/unimrcp/libs/uni-rtsp/include/rtsp_stream.h index 3d9e31b260..ecebef6055 100644 --- a/libs/unimrcp/libs/uni-rtsp/include/rtsp_stream.h +++ b/libs/unimrcp/libs/uni-rtsp/include/rtsp_stream.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_stream.h 1632 2010-03-30 20:46:25Z achaloyan $ */ -#ifndef __RTSP_STREAM_H__ -#define __RTSP_STREAM_H__ +#ifndef RTSP_STREAM_H +#define RTSP_STREAM_H /** * @file rtsp_stream.h @@ -23,47 +25,30 @@ */ #include "rtsp_message.h" +#include "apt_text_message.h" APT_BEGIN_EXTERN_C -/** Status of RTSP stream processing (parse/generate) */ -typedef enum { - RTSP_STREAM_STATUS_COMPLETE, - RTSP_STREAM_STATUS_INCOMPLETE, - RTSP_STREAM_STATUS_INVALID -} rtsp_stream_status_e; - /** Opaque RTSP parser declaration */ typedef struct rtsp_parser_t rtsp_parser_t; /** Opaque RTSP generator declaration */ typedef struct rtsp_generator_t rtsp_generator_t; -/** RTSP message handler */ -typedef apt_bool_t (*rtsp_message_handler_f)(void *obj, rtsp_message_t *message, rtsp_stream_status_e status); /** Create RTSP stream parser */ RTSP_DECLARE(rtsp_parser_t*) rtsp_parser_create(apr_pool_t *pool); /** Parse RTSP stream */ -RTSP_DECLARE(rtsp_stream_status_e) rtsp_parser_run(rtsp_parser_t *parser, apt_text_stream_t *stream); - -/** Get parsed RTSP message */ -RTSP_DECLARE(rtsp_message_t*) rtsp_parser_message_get(const rtsp_parser_t *parser); +RTSP_DECLARE(apt_message_status_e) rtsp_parser_run(rtsp_parser_t *parser, apt_text_stream_t *stream, rtsp_message_t **message); /** Create RTSP stream generator */ RTSP_DECLARE(rtsp_generator_t*) rtsp_generator_create(apr_pool_t *pool); -/** Set RTSP message to generate */ -RTSP_DECLARE(apt_bool_t) rtsp_generator_message_set(rtsp_generator_t *generator, rtsp_message_t *message); - /** Generate RTSP stream */ -RTSP_DECLARE(rtsp_stream_status_e) rtsp_generator_run(rtsp_generator_t *generator, apt_text_stream_t *stream); - +RTSP_DECLARE(apt_message_status_e) rtsp_generator_run(rtsp_generator_t *generator, rtsp_message_t *message, apt_text_stream_t *stream); -/** Walk through RTSP stream and call message handler for each parsed message */ -RTSP_DECLARE(apt_bool_t) rtsp_stream_walk(rtsp_parser_t *parser, apt_text_stream_t *stream, rtsp_message_handler_f handler, void *obj); APT_END_EXTERN_C -#endif /*__RTSP_STREAM_H__*/ +#endif /* RTSP_STREAM_H */ diff --git a/libs/unimrcp/libs/uni-rtsp/src/rtsp_client.c b/libs/unimrcp/libs/uni-rtsp/src/rtsp_client.c index 044dd0623e..9c4d23ba90 100644 --- a/libs/unimrcp/libs/uni-rtsp/src/rtsp_client.c +++ b/libs/unimrcp/libs/uni-rtsp/src/rtsp_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,12 +12,14 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_client.c 1710 2010-05-24 17:36:19Z achaloyan $ */ #include #include "rtsp_client.h" #include "rtsp_stream.h" -#include "apt_net_client_task.h" +#include "apt_poller_task.h" #include "apt_text_stream.h" #include "apt_pool.h" #include "apt_obj_list.h" @@ -36,42 +38,50 @@ typedef enum { /** RTSP client */ struct rtsp_client_t { apr_pool_t *pool; - apt_net_client_task_t *task; + apt_poller_task_t *task; apr_pool_t *sub_pool; apt_obj_list_t *connection_list; + apr_uint32_t request_timeout; + void *obj; const rtsp_client_vtable_t *vtable; }; /** RTSP connection */ struct rtsp_client_connection_t { - /** Connection base */ - apt_net_client_connection_t *base; + /** Memory pool */ + apr_pool_t *pool; + /** Connected socket */ + apr_socket_t *sock; + /** Socket poll descriptor */ + apr_pollfd_t sock_pfd; + /** String identifier used for traces */ + const char *id; /** RTSP client, connection belongs to */ - rtsp_client_t *client; + rtsp_client_t *client; /** Element of the connection list in agent */ - apt_list_elem_t *it; + apt_list_elem_t *it; /** Handle table (rtsp_client_session_t*) */ - apr_hash_t *handle_table; + apr_hash_t *handle_table; /** Session table (rtsp_client_session_t*) */ - apr_hash_t *session_table; + apr_hash_t *session_table; /** Inprogress request/session queue (rtsp_client_session_t*) */ - apt_obj_list_t *inprogress_request_queue; + apt_obj_list_t *inprogress_request_queue; /** Last CSeq sent */ - apr_size_t last_cseq; + apr_size_t last_cseq; - char rx_buffer[RTSP_STREAM_BUFFER_SIZE]; - apt_text_stream_t rx_stream; - rtsp_parser_t *parser; + char rx_buffer[RTSP_STREAM_BUFFER_SIZE]; + apt_text_stream_t rx_stream; + rtsp_parser_t *parser; - char tx_buffer[RTSP_STREAM_BUFFER_SIZE]; - apt_text_stream_t tx_stream; - rtsp_generator_t *generator; + char tx_buffer[RTSP_STREAM_BUFFER_SIZE]; + apt_text_stream_t tx_stream; + rtsp_generator_t *generator; }; /** RTSP session */ @@ -93,6 +103,9 @@ struct rtsp_client_session_t { /** Pending request queue (rtsp_message_t*) */ apt_obj_list_t *pending_request_queue; + /** Timer used for request timeouts */ + apt_timer_t *request_timer; + /** Resource table */ apr_hash_t *resource_table; @@ -116,23 +129,22 @@ struct task_msg_data_t { static apt_bool_t rtsp_client_task_msg_process(apt_task_t *task, apt_task_msg_t *msg); -static apt_bool_t rtsp_client_message_receive(apt_net_client_task_t *task, apt_net_client_connection_t *connection); +static apt_bool_t rtsp_client_poller_signal_process(void *obj, const apr_pollfd_t *descriptor); -static const apt_net_client_vtable_t client_vtable = { - rtsp_client_message_receive -}; - -static apt_bool_t rtsp_client_message_send(rtsp_client_t *client, apt_net_client_connection_t *connection, rtsp_message_t *message); +static apt_bool_t rtsp_client_message_send(rtsp_client_t *client, rtsp_client_connection_t *connection, rtsp_message_t *message); static apt_bool_t rtsp_client_session_message_process(rtsp_client_t *client, rtsp_client_session_t *session, rtsp_message_t *message); static apt_bool_t rtsp_client_session_request_process(rtsp_client_t *client, rtsp_client_session_t *session, rtsp_message_t *message); static apt_bool_t rtsp_client_session_response_process(rtsp_client_t *client, rtsp_client_session_t *session, rtsp_message_t *request, rtsp_message_t *response); +static void rtsp_client_timer_proc(apt_timer_t *timer, void *obj); + /** Create RTSP client */ RTSP_DECLARE(rtsp_client_t*) rtsp_client_create( - apr_size_t max_connection_count, - void *obj, - const rtsp_client_vtable_t *handler, - apr_pool_t *pool) + apr_size_t max_connection_count, + apr_size_t request_timeout, + void *obj, + const rtsp_client_vtable_t *handler, + apr_pool_t *pool) { apt_task_vtable_t *vtable; apt_task_msg_pool_t *msg_pool; @@ -146,18 +158,24 @@ RTSP_DECLARE(rtsp_client_t*) rtsp_client_create( msg_pool = apt_task_msg_pool_create_dynamic(sizeof(task_msg_data_t),pool); - client->task = apt_net_client_task_create(max_connection_count,client,&client_vtable,msg_pool,pool); + client->task = apt_poller_task_create( + max_connection_count, + rtsp_client_poller_signal_process, + client, + msg_pool, + pool); if(!client->task) { return NULL; } - vtable = apt_net_client_task_vtable_get(client->task); + vtable = apt_poller_task_vtable_get(client->task); if(vtable) { vtable->process_msg = rtsp_client_task_msg_process; } client->sub_pool = apt_subpool_create(pool); client->connection_list = NULL; + client->request_timeout = (apr_uint32_t)request_timeout; return client; } @@ -165,29 +183,29 @@ RTSP_DECLARE(rtsp_client_t*) rtsp_client_create( RTSP_DECLARE(apt_bool_t) rtsp_client_destroy(rtsp_client_t *client) { apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy RTSP Client"); - return apt_net_client_task_destroy(client->task); + return apt_poller_task_destroy(client->task); } /** Start connection agent */ RTSP_DECLARE(apt_bool_t) rtsp_client_start(rtsp_client_t *client) { - return apt_net_client_task_start(client->task); + return apt_poller_task_start(client->task); } /** Terminate connection agent */ RTSP_DECLARE(apt_bool_t) rtsp_client_terminate(rtsp_client_t *client) { - return apt_net_client_task_terminate(client->task); + return apt_poller_task_terminate(client->task); } /** Get task */ -RTSP_DECLARE(apt_task_t*) rtsp_client_task_get(rtsp_client_t *client) +RTSP_DECLARE(apt_task_t*) rtsp_client_task_get(const rtsp_client_t *client) { - return apt_net_client_task_base_get(client->task); + return apt_poller_task_base_get(client->task); } /** Get external object */ -RTSP_DECLARE(void*) rtsp_client_object_get(rtsp_client_t *client) +RTSP_DECLARE(void*) rtsp_client_object_get(const rtsp_client_t *client) { return client->obj; } @@ -217,7 +235,7 @@ static apt_bool_t rtsp_client_control_message_signal( rtsp_client_session_t *session, rtsp_message_t *message) { - apt_task_t *task = apt_net_client_task_base_get(client->task); + apt_task_t *task = apt_poller_task_base_get(client->task); apt_task_msg_t *task_msg = apt_task_msg_get(task); if(task_msg) { task_msg_data_t *data = (task_msg_data_t*)task_msg->data; @@ -245,6 +263,11 @@ RTSP_DECLARE(rtsp_client_session_t*) rtsp_client_session_create( session->connection = NULL; session->active_request = NULL; session->pending_request_queue = apt_list_create(pool); + session->request_timer = apt_poller_task_timer_create( + client->task, + rtsp_client_timer_proc, + session, + pool); session->resource_table = apr_hash_make(pool); session->term_state = TERMINATION_STATE_NONE; @@ -277,31 +300,107 @@ RTSP_DECLARE(apt_bool_t) rtsp_client_session_request(rtsp_client_t *client, rtsp return rtsp_client_control_message_signal(TASK_MSG_SEND_MESSAGE,client,session,message); } + +/** Create connection */ +static apt_bool_t rtsp_client_connect(rtsp_client_connection_t *connection, apt_pollset_t *pollset, const char *ip, apr_port_t port) +{ + char *local_ip = NULL; + char *remote_ip = NULL; + apr_sockaddr_t *l_sockaddr = NULL; + apr_sockaddr_t *r_sockaddr = NULL; + + if(apr_sockaddr_info_get(&r_sockaddr,ip,APR_INET,port,0,connection->pool) != APR_SUCCESS) { + return FALSE; + } + + if(apr_socket_create(&connection->sock,r_sockaddr->family,SOCK_STREAM,APR_PROTO_TCP,connection->pool) != APR_SUCCESS) { + return FALSE; + } + + apr_socket_opt_set(connection->sock, APR_SO_NONBLOCK, 0); + apr_socket_timeout_set(connection->sock, -1); + apr_socket_opt_set(connection->sock, APR_SO_REUSEADDR, 1); + + if(apr_socket_connect(connection->sock,r_sockaddr) != APR_SUCCESS) { + apr_socket_close(connection->sock); + connection->sock = NULL; + return FALSE; + } + + if(apr_socket_addr_get(&l_sockaddr,APR_LOCAL,connection->sock) != APR_SUCCESS) { + apr_socket_close(connection->sock); + connection->sock = NULL; + return FALSE; + } + + apr_sockaddr_ip_get(&local_ip,l_sockaddr); + apr_sockaddr_ip_get(&remote_ip,r_sockaddr); + connection->id = apr_psprintf(connection->pool,"%s:%hu <-> %s:%hu", + local_ip,l_sockaddr->port, + remote_ip,r_sockaddr->port); + + memset(&connection->sock_pfd,0,sizeof(apr_pollfd_t)); + connection->sock_pfd.desc_type = APR_POLL_SOCKET; + connection->sock_pfd.reqevents = APR_POLLIN; + connection->sock_pfd.desc.s = connection->sock; + connection->sock_pfd.client_data = connection; + if(apt_pollset_add(pollset,&connection->sock_pfd) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add to Pollset %s",connection->id); + apr_socket_close(connection->sock); + connection->sock = NULL; + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Established RTSP Connection %s",connection->id); + return TRUE; +} + +/** Close connection */ +static apt_bool_t rtsp_client_connection_close(rtsp_client_connection_t *connection, apt_pollset_t *pollset) +{ + if(connection->sock) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close RTSP Connection %s",connection->id); + apt_pollset_remove(pollset,&connection->sock_pfd); + apr_socket_close(connection->sock); + connection->sock = NULL; + } + return TRUE; +} + + /* Create RTSP connection */ static apt_bool_t rtsp_client_connection_create(rtsp_client_t *client, rtsp_client_session_t *session) { rtsp_client_connection_t *rtsp_connection; - apt_net_client_connection_t *connection = apt_net_client_connect(client->task,session->server_ip.buf,session->server_port); - if(!connection) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Connect to RTSP Server %s:%d",session->server_ip.buf,session->server_port); + apt_pollset_t *pollset = apt_poller_task_pollset_get(client->task); + apr_pool_t *pool = apt_pool_create(); + if(!pool) { + return FALSE; + } + + rtsp_connection = apr_palloc(pool,sizeof(rtsp_client_connection_t)); + rtsp_connection->pool = pool; + rtsp_connection->sock = NULL; + + if(rtsp_client_connect(rtsp_connection,pollset,session->server_ip.buf,session->server_port) == FALSE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Connect to RTSP Server %s:%hu", + session->server_ip.buf,session->server_port); + apr_pool_destroy(pool); return FALSE; } - rtsp_connection = apr_palloc(connection->pool,sizeof(rtsp_client_connection_t)); - rtsp_connection->handle_table = apr_hash_make(connection->pool); - rtsp_connection->session_table = apr_hash_make(connection->pool); - rtsp_connection->inprogress_request_queue = apt_list_create(connection->pool); + rtsp_connection->handle_table = apr_hash_make(pool); + rtsp_connection->session_table = apr_hash_make(pool); + rtsp_connection->inprogress_request_queue = apt_list_create(pool); apt_text_stream_init(&rtsp_connection->rx_stream,rtsp_connection->rx_buffer,sizeof(rtsp_connection->rx_buffer)-1); apt_text_stream_init(&rtsp_connection->tx_stream,rtsp_connection->tx_buffer,sizeof(rtsp_connection->tx_buffer)-1); - rtsp_connection->parser = rtsp_parser_create(connection->pool); - rtsp_connection->generator = rtsp_generator_create(connection->pool); + rtsp_connection->parser = rtsp_parser_create(pool); + rtsp_connection->generator = rtsp_generator_create(pool); rtsp_connection->last_cseq = 0; - rtsp_connection->base = connection; - connection->obj = rtsp_connection; if(!client->connection_list) { client->connection_list = apt_list_create(client->sub_pool); } rtsp_connection->client = client; - rtsp_connection->it = apt_list_push_back(client->connection_list,rtsp_connection,connection->pool); + rtsp_connection->it = apt_list_push_back(client->connection_list,rtsp_connection,pool); session->connection = rtsp_connection; return TRUE; } @@ -310,8 +409,11 @@ static apt_bool_t rtsp_client_connection_create(rtsp_client_t *client, rtsp_clie static apt_bool_t rtsp_client_connection_destroy(rtsp_client_connection_t *rtsp_connection) { rtsp_client_t *client = rtsp_connection->client; + apt_pollset_t *pollset = apt_poller_task_pollset_get(client->task); apt_list_elem_remove(client->connection_list,rtsp_connection->it); - apt_net_client_disconnect(client->task,rtsp_connection->base); + rtsp_client_connection_close(rtsp_connection,pollset); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy RTSP Connection %s",rtsp_connection->id); + apr_pool_destroy(rtsp_connection->pool); if(apt_list_is_empty(client->connection_list) == TRUE) { apr_pool_clear(client->sub_pool); @@ -389,14 +491,14 @@ static apt_bool_t rtsp_client_session_url_generate(rtsp_client_session_t *sessio { apt_str_t *url = &message->start_line.common.request_line.url; if(session->resource_location.length) { - url->buf = apr_psprintf(message->pool,"rtsp://%s:%d/%s/%s", + url->buf = apr_psprintf(message->pool,"rtsp://%s:%hu/%s/%s", session->server_ip.buf, session->server_port, session->resource_location.buf, message->start_line.common.request_line.resource_name); } else { - url->buf = apr_psprintf(message->pool,"rtsp://%s:%d/%s", + url->buf = apr_psprintf(message->pool,"rtsp://%s:%hu/%s", session->server_ip.buf, session->server_port, message->start_line.common.request_line.resource_name); @@ -414,6 +516,9 @@ static apt_bool_t rtsp_client_request_push(rtsp_client_connection_t *rtsp_connec message->header.cseq); apt_list_push_back(rtsp_connection->inprogress_request_queue,session,session->pool); session->active_request = message; + if(rtsp_connection->client->request_timeout) { + apt_timer_set(session->request_timer,rtsp_connection->client->request_timeout); + } return TRUE; } @@ -435,6 +540,7 @@ static apt_bool_t rtsp_client_request_pop(rtsp_client_connection_t *rtsp_connect response->header.cseq); apt_list_elem_remove(rtsp_connection->inprogress_request_queue,elem); session->active_request = NULL; + apt_timer_kill(session->request_timer); return TRUE; } elem = apt_list_next_elem_get(rtsp_connection->inprogress_request_queue,elem); @@ -459,13 +565,13 @@ static apt_bool_t rtsp_client_session_request_process(rtsp_client_t *client, rts if(session->id.length) { message->header.session_id = session->id; - rtsp_header_property_add(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID); + rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_SESSION_ID,message->pool); } message->header.cseq = ++session->connection->last_cseq; - rtsp_header_property_add(&message->header.property_set,RTSP_HEADER_FIELD_CSEQ); + rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_CSEQ,message->pool); - if(rtsp_client_message_send(client,session->connection->base,message) == FALSE) { + if(rtsp_client_message_send(client,session->connection,message) == FALSE) { /* respond with error */ return FALSE; } @@ -533,7 +639,7 @@ static apt_bool_t rtsp_client_session_event_process(rtsp_client_t *client, rtsp_ { rtsp_message_t *response = NULL; rtsp_client_session_t *session = NULL; - if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) { + if(rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) { /* find existing session */ session = apr_hash_get( rtsp_connection->session_table, @@ -543,9 +649,9 @@ static apt_bool_t rtsp_client_session_event_process(rtsp_client_t *client, rtsp_ if(session) { response = rtsp_response_create(message,RTSP_STATUS_CODE_OK,RTSP_REASON_PHRASE_OK,message->pool); - if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) { + if(rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) { response->header.session_id = message->header.session_id; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_SESSION_ID); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_SESSION_ID,message->pool); } client->vtable->on_session_event(client,session,message); } @@ -553,7 +659,7 @@ static apt_bool_t rtsp_client_session_event_process(rtsp_client_t *client, rtsp_ response = rtsp_response_create(message,RTSP_STATUS_CODE_NOT_FOUND,RTSP_REASON_PHRASE_NOT_FOUND,message->pool); } - return rtsp_client_message_send(client,rtsp_connection->base,response); + return rtsp_client_message_send(client,rtsp_connection,response); } /* Process incoming RTSP response */ @@ -564,7 +670,7 @@ static apt_bool_t rtsp_client_session_response_process(rtsp_client_t *client, rt response->start_line.common.status_line.status_code == RTSP_STATUS_CODE_OK) { if(apr_hash_count(session->resource_table) == 0) { - if(rtsp_header_property_check(&response->header.property_set,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) { + if(rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) { session->id = response->header.session_id; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add RTSP Session "APT_PTRSID_FMT, session, @@ -629,32 +735,55 @@ static apt_bool_t rtsp_client_session_terminate_raise(rtsp_client_t *client, rts return TRUE; } +/* Cancel RTSP request */ +static apt_bool_t rtsp_client_request_cancel(rtsp_client_t *client, rtsp_client_session_t *session, rtsp_status_code_e status_code, rtsp_reason_phrase_e reason) +{ + rtsp_message_t *request; + rtsp_message_t *response; + if(!session->active_request) { + return FALSE; + } + + request = session->active_request; + session->active_request = NULL; + + response = rtsp_response_create( + request, + status_code, + reason, + session->pool); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Cancel RTSP Request "APT_PTRSID_FMT" CSeq:%"APR_SIZE_T_FMT" [%d]", + session, + request->header.session_id.buf ? request->header.session_id.buf : "new", + request->header.cseq, + status_code); + rtsp_client_session_response_process(client,session,request,response); + return TRUE; +} + /* RTSP connection disconnected */ static apt_bool_t rtsp_client_on_disconnect(rtsp_client_t *client, rtsp_client_connection_t *rtsp_connection) { rtsp_client_session_t *session; - rtsp_message_t *request; - rtsp_message_t *response; apr_size_t remaining_handles = 0; apr_size_t cancelled_requests = 0; + apt_pollset_t *pollset = apt_poller_task_pollset_get(client->task); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"TCP Peer Disconnected %s", rtsp_connection->base->id); - apt_net_client_connection_close(client->task,rtsp_connection->base); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"RTSP Peer Disconnected %s", rtsp_connection->id); + rtsp_client_connection_close(rtsp_connection,pollset); /* Cancel in-progreess requests */ do { session = apt_list_pop_front(rtsp_connection->inprogress_request_queue); - if(session && session->active_request) { - request = session->active_request; - session->active_request = NULL; - cancelled_requests++; - - response = rtsp_response_create( - request, - RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR, - RTSP_REASON_PHRASE_INTERNAL_SERVER_ERROR, - session->pool); - rtsp_client_session_response_process(client,session,request,response); + if(session) { + if(rtsp_client_request_cancel( + client, + session, + RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR, + RTSP_REASON_PHRASE_INTERNAL_SERVER_ERROR) == TRUE) { + cancelled_requests++; + apt_timer_kill(session->request_timer); + } } } while(session); @@ -665,7 +794,7 @@ static apt_bool_t rtsp_client_on_disconnect(rtsp_client_t *client, rtsp_client_c void *val; apr_hash_index_t *it; apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Terminate Remaining RTSP Handles [%"APR_SIZE_T_FMT"]",remaining_handles); - it = apr_hash_first(rtsp_connection->base->pool,rtsp_connection->session_table); + it = apr_hash_first(rtsp_connection->pool,rtsp_connection->session_table); for(; it; it = apr_hash_next(it)) { apr_hash_this(it,NULL,NULL,&val); session = val; @@ -683,34 +812,31 @@ static apt_bool_t rtsp_client_on_disconnect(rtsp_client_t *client, rtsp_client_c } /* Send RTSP message through RTSP connection */ -static apt_bool_t rtsp_client_message_send(rtsp_client_t *client, apt_net_client_connection_t *connection, rtsp_message_t *message) +static apt_bool_t rtsp_client_message_send(rtsp_client_t *client, rtsp_client_connection_t *rtsp_connection, rtsp_message_t *message) { apt_bool_t status = FALSE; - rtsp_client_connection_t *rtsp_connection; apt_text_stream_t *stream; - rtsp_stream_status_e result; + apt_message_status_e result; - if(!connection || !connection->sock) { + if(!rtsp_connection || !rtsp_connection->sock) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No RTSP Connection"); return FALSE; } - rtsp_connection = connection->obj; stream = &rtsp_connection->tx_stream; - rtsp_generator_message_set(rtsp_connection->generator,message); do { stream->text.length = sizeof(rtsp_connection->tx_buffer)-1; apt_text_stream_reset(stream); - result = rtsp_generator_run(rtsp_connection->generator,stream); - if(result != RTSP_STREAM_STATUS_INVALID) { + result = rtsp_generator_run(rtsp_connection->generator,message,stream); + if(result != APT_MESSAGE_STATUS_INVALID) { stream->text.length = stream->pos - stream->text.buf; *stream->pos = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send RTSP Stream %s [%lu bytes]\n%s", - connection->id, + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send RTSP Stream %s [%"APR_SIZE_T_FMT" bytes]\n%s", + rtsp_connection->id, stream->text.length, stream->text.buf); - if(apr_socket_send(connection->sock,stream->text.buf,&stream->text.length) == APR_SUCCESS) { + if(apr_socket_send(rtsp_connection->sock,stream->text.buf,&stream->text.length) == APR_SUCCESS) { status = TRUE; } else { @@ -721,16 +847,15 @@ static apt_bool_t rtsp_client_message_send(rtsp_client_t *client, apt_net_client apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Generate RTSP Stream"); } } - while(result == RTSP_STREAM_STATUS_INCOMPLETE); + while(result == APT_MESSAGE_STATUS_INCOMPLETE); return status; } -/** return TRUE to proceed with the next message in the stream (if any) */ -static apt_bool_t rtsp_client_message_handler(void *obj, rtsp_message_t *message, rtsp_stream_status_e status) +/** Return TRUE to proceed with the next message in the stream (if any) */ +static apt_bool_t rtsp_client_message_handler(rtsp_client_connection_t *rtsp_connection, rtsp_message_t *message, apt_message_status_e status) { - rtsp_client_connection_t *rtsp_connection = obj; - if(status != RTSP_STREAM_STATUS_COMPLETE) { + if(status != APT_MESSAGE_STATUS_COMPLETE) { /* message is not completely parsed, nothing to do */ return TRUE; } @@ -776,50 +901,61 @@ static apt_bool_t rtsp_client_message_handler(void *obj, rtsp_message_t *message } /* Receive RTSP message through RTSP connection */ -static apt_bool_t rtsp_client_message_receive(apt_net_client_task_t *task, apt_net_client_connection_t *connection) +static apt_bool_t rtsp_client_poller_signal_process(void *obj, const apr_pollfd_t *descriptor) { - rtsp_client_t *client = apt_net_client_task_object_get(task); - rtsp_client_connection_t *rtsp_connection; + rtsp_client_t *client = obj; + rtsp_client_connection_t *rtsp_connection = descriptor->client_data; apr_status_t status; apr_size_t offset; apr_size_t length; apt_text_stream_t *stream; + rtsp_message_t *message; + apt_message_status_e msg_status; - if(!connection || !connection->sock) { + if(!rtsp_connection || !rtsp_connection->sock) { return FALSE; } - rtsp_connection = connection->obj; stream = &rtsp_connection->rx_stream; - /* init length of the stream */ - stream->text.length = sizeof(rtsp_connection->rx_buffer)-1; /* calculate offset remaining from the previous receive / if any */ offset = stream->pos - stream->text.buf; /* calculate available length */ - length = stream->text.length - offset; - status = apr_socket_recv(connection->sock,stream->pos,&length); + length = sizeof(rtsp_connection->rx_buffer) - 1 - offset; + + status = apr_socket_recv(rtsp_connection->sock,stream->pos,&length); if(status == APR_EOF || length == 0) { return rtsp_client_on_disconnect(client,rtsp_connection); } + /* calculate actual length of the stream */ stream->text.length = offset + length; stream->pos[length] = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive RTSP Stream %s [%lu bytes]\n%s", - connection->id, + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive RTSP Stream %s [%"APR_SIZE_T_FMT" bytes]\n%s", + rtsp_connection->id, length, stream->pos); /* reset pos */ apt_text_stream_reset(stream); - /* walk through the stream parsing RTSP messages */ - return rtsp_stream_walk(rtsp_connection->parser,stream,rtsp_client_message_handler,rtsp_connection); + + do { + msg_status = rtsp_parser_run(rtsp_connection->parser,stream,&message); + if(rtsp_client_message_handler(rtsp_connection,message,msg_status) == FALSE) { + return FALSE; + } + } + while(apt_text_is_eos(stream) == FALSE); + + /* scroll remaining stream */ + apt_text_stream_scroll(stream); + return TRUE; } /* Process task message */ static apt_bool_t rtsp_client_task_msg_process(apt_task_t *task, apt_task_msg_t *task_msg) { - apt_net_client_task_t *net_task = apt_task_object_get(task); - rtsp_client_t *client = apt_net_client_task_object_get(net_task); + apt_poller_task_t *poller_task = apt_task_object_get(task); + rtsp_client_t *client = apt_poller_task_object_get(poller_task); task_msg_data_t *data = (task_msg_data_t*) task_msg->data; switch(data->type) { @@ -833,3 +969,20 @@ static apt_bool_t rtsp_client_task_msg_process(apt_task_t *task, apt_task_msg_t return TRUE; } + +/* Timer callback */ +static void rtsp_client_timer_proc(apt_timer_t *timer, void *obj) +{ + rtsp_client_session_t *session = obj; + if(!session || !session->connection || !session->connection->client) { + return; + } + + if(session->request_timer == timer) { + rtsp_client_request_cancel( + session->connection->client, + session, + RTSP_STATUS_CODE_REQUEST_TIMEOUT, + RTSP_REASON_PHRASE_REQUEST_TIMEOUT); + } +} diff --git a/libs/unimrcp/libs/uni-rtsp/src/rtsp_header.c b/libs/unimrcp/libs/uni-rtsp/src/rtsp_header.c index b090fd7303..de19f125f4 100644 --- a/libs/unimrcp/libs/uni-rtsp/src/rtsp_header.c +++ b/libs/unimrcp/libs/uni-rtsp/src/rtsp_header.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,13 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_header.c 1718 2010-05-31 13:12:43Z achaloyan $ */ #include "rtsp_header.h" #include "apt_string_table.h" +#include "apt_text_stream.h" /** String table of RTSP header fields (rtsp_header_field_id) */ static const apt_str_table_item_t rtsp_header_string_table[] = { @@ -87,12 +90,12 @@ static apt_bool_t rtsp_port_range_generate(rtsp_transport_attrib_e attrib, const if(!str) { return FALSE; } - apt_string_value_generate(str,text_stream); + apt_text_string_insert(text_stream,str); apt_text_char_insert(text_stream,'='); - apt_size_value_generate(port_range->min,text_stream); + apt_text_size_value_insert(text_stream,port_range->min); if(port_range->max > port_range->min) { apt_text_char_insert(text_stream,'-'); - apt_size_value_generate(port_range->max,text_stream); + apt_text_size_value_insert(text_stream,port_range->max); } return TRUE; } @@ -197,13 +200,12 @@ static apt_bool_t rtsp_transport_protocol_parse(rtsp_transport_t *transport, con } /** Parse RTSP transport */ -static apt_bool_t rtsp_transport_parse(rtsp_transport_t *transport, const apt_str_t *line, apr_pool_t *pool) +static apt_bool_t rtsp_transport_parse(rtsp_transport_t *transport, const apt_str_t *value, apr_pool_t *pool) { apt_str_t field; apt_text_stream_t stream; - stream.text = *line; - apt_text_stream_reset(&stream); + apt_text_stream_init(&stream,value->buf,value->length); /* read transport protocol (RTP/AVP[/UDP]) */ if(apt_text_field_read(&stream,';',TRUE,&field) == FALSE) { return FALSE; @@ -223,16 +225,20 @@ static apt_bool_t rtsp_transport_parse(rtsp_transport_t *transport, const apt_st } /** Generate RTSP transport */ -static apt_bool_t rtsp_transport_generate(rtsp_transport_t *transport, apt_text_stream_t *text_stream) +static apt_bool_t rtsp_transport_generate(const rtsp_transport_t *transport, apt_str_t *value, apr_pool_t *pool) { + char buf[256]; + apt_text_stream_t text_stream; const apt_str_t *protocol = apt_string_table_str_get(rtsp_transport_string_table,RTSP_TRANSPORT_COUNT,transport->protocol); const apt_str_t *profile = apt_string_table_str_get(rtsp_profile_string_table,RTSP_PROFILE_COUNT,transport->profile); if(!protocol || !profile) { return FALSE; } - apt_string_value_generate(protocol,text_stream); - apt_text_char_insert(text_stream,'/'); - apt_string_value_generate(profile,text_stream); + + apt_text_stream_init(&text_stream,buf,sizeof(buf)); + apt_text_string_insert(&text_stream,protocol); + apt_text_char_insert(&text_stream,'/'); + apt_text_string_insert(&text_stream,profile); if(transport->delivery != RTSP_DELIVERY_NONE) { const apt_str_t *delivery = NULL; @@ -248,29 +254,33 @@ static apt_bool_t rtsp_transport_generate(rtsp_transport_t *transport, apt_text_ return FALSE; } - apt_text_char_insert(text_stream,';'); - apt_string_value_generate(delivery,text_stream); + apt_text_char_insert(&text_stream,';'); + apt_text_string_insert(&text_stream,delivery); } if(rtsp_port_range_is_valid(&transport->client_port_range) == TRUE) { - apt_text_char_insert(text_stream,';'); - rtsp_port_range_generate(RTSP_TRANSPORT_ATTRIB_CLIENT_PORT,&transport->client_port_range,text_stream); + apt_text_char_insert(&text_stream,';'); + rtsp_port_range_generate(RTSP_TRANSPORT_ATTRIB_CLIENT_PORT,&transport->client_port_range,&text_stream); } if(rtsp_port_range_is_valid(&transport->server_port_range) == TRUE) { - apt_text_char_insert(text_stream,';'); - rtsp_port_range_generate(RTSP_TRANSPORT_ATTRIB_SERVER_PORT,&transport->server_port_range,text_stream); + apt_text_char_insert(&text_stream,';'); + rtsp_port_range_generate(RTSP_TRANSPORT_ATTRIB_SERVER_PORT,&transport->server_port_range,&text_stream); } if(transport->mode.length) { const apt_str_t *str; str = apt_string_table_str_get(rtsp_transport_attrib_string_table,RTSP_TRANSPORT_ATTRIB_COUNT,RTSP_TRANSPORT_ATTRIB_MODE); if(str) { - apt_text_char_insert(text_stream,';'); - apt_string_value_generate(str,text_stream); - apt_text_char_insert(text_stream,'='); - apt_string_value_generate(&transport->mode,text_stream); + apt_text_char_insert(&text_stream,';'); + apt_text_string_insert(&text_stream,str); + apt_text_char_insert(&text_stream,'='); + apt_text_string_insert(&text_stream,&transport->mode); } } + value->length = text_stream.pos - text_stream.text.buf; + value->buf = apr_palloc(pool,value->length + 1); + memcpy(value->buf,text_stream.text.buf,value->length); + value->buf[value->length] = '\0'; return TRUE; } @@ -290,8 +300,8 @@ static apt_bool_t rtsp_session_id_parse(apt_str_t *session_id, const apt_str_t * return TRUE; } -/** Parse RTSP header field */ -static apt_bool_t rtsp_header_field_parse(rtsp_header_t *header, rtsp_header_field_id id, const apt_str_t *value, apr_pool_t *pool) +/** Parse RTSP header field value */ +static apt_bool_t rtsp_header_field_value_parse(rtsp_header_t *header, rtsp_header_field_id id, const apt_str_t *value, apr_pool_t *pool) { apt_bool_t status = TRUE; switch(id) { @@ -305,7 +315,7 @@ static apt_bool_t rtsp_header_field_parse(rtsp_header_t *header, rtsp_header_fie status = rtsp_session_id_parse(&header->session_id,value,pool); break; case RTSP_HEADER_FIELD_RTP_INFO: - apt_string_copy(&header->rtp_info,value,pool); + header->rtp_info = *value; break; case RTSP_HEADER_FIELD_CONTENT_TYPE: header->content_type = apt_string_table_id_find(rtsp_content_type_string_table,RTSP_CONTENT_TYPE_COUNT,value); @@ -319,32 +329,32 @@ static apt_bool_t rtsp_header_field_parse(rtsp_header_t *header, rtsp_header_fie return status; } -/** Generate RTSP header field */ -static apr_size_t rtsp_header_field_generate(rtsp_header_t *header, apr_size_t id, apt_text_stream_t *value) +/** Generate RTSP header field value */ +static apt_bool_t rtsp_header_field_value_generate(const rtsp_header_t *header, rtsp_header_field_id id, apt_str_t *value, apr_pool_t *pool) { switch(id) { case RTSP_HEADER_FIELD_CSEQ: - apt_size_value_generate(header->cseq,value); + apt_size_value_generate(header->cseq,value,pool); break; case RTSP_HEADER_FIELD_TRANSPORT: - rtsp_transport_generate(&header->transport,value); + rtsp_transport_generate(&header->transport,value,pool); break; case RTSP_HEADER_FIELD_SESSION_ID: - apt_string_value_generate(&header->session_id,value); + *value = header->session_id; break; case RTSP_HEADER_FIELD_RTP_INFO: - apt_string_value_generate(&header->rtp_info,value); + *value = header->rtp_info; break; case RTSP_HEADER_FIELD_CONTENT_TYPE: { const apt_str_t *name = apt_string_table_str_get(rtsp_content_type_string_table,RTSP_CONTENT_TYPE_COUNT,header->content_type); if(name) { - apt_string_value_generate(name,value); + *value = *name; } break; } case RTSP_HEADER_FIELD_CONTENT_LENGTH: - apt_size_value_generate(header->content_length,value); + apt_size_value_generate(header->content_length,value,pool); break; default: break; @@ -352,58 +362,59 @@ static apr_size_t rtsp_header_field_generate(rtsp_header_t *header, apr_size_t i return TRUE; } -/** Parse RTSP header */ -RTSP_DECLARE(apt_bool_t) rtsp_header_parse(rtsp_header_t *header, apt_text_stream_t *text_stream, apr_pool_t *pool) +/** Add RTSP header field */ +RTSP_DECLARE(apt_bool_t) rtsp_header_field_add(rtsp_header_t *header, apt_header_field_t *header_field, apr_pool_t *pool) { - apt_pair_t pair; - apt_bool_t result = FALSE; - - do { - if(apt_text_header_read(text_stream,&pair) == TRUE) { - if(pair.name.length) { - /* parse header_field (name/value) */ - rtsp_header_field_id id = apt_string_table_id_find(rtsp_header_string_table,RTSP_HEADER_FIELD_COUNT,&pair.name); - if(id < RTSP_HEADER_FIELD_COUNT) { - if(rtsp_header_field_parse(header,id,&pair.value,pool) == TRUE) { - rtsp_header_property_add(&header->property_set,id); - } - } - } - else { - /* empty header -> exit */ - result = TRUE; - break; - } - } + /* parse header field (name-value) */ + header_field->id = apt_string_table_id_find( + rtsp_header_string_table, + RTSP_HEADER_FIELD_COUNT, + &header_field->name); + if(apt_string_is_empty(&header_field->value) == FALSE) { + rtsp_header_field_value_parse(header,header_field->id,&header_field->value,pool); } - while(apt_text_is_eos(text_stream) == FALSE); - return result; + return apt_header_section_field_add(&header->header_section,header_field); } -/** Generate RTSP header */ -RTSP_DECLARE(apt_bool_t) rtsp_header_generate(rtsp_header_t *header, apt_text_stream_t *text_stream) +/** Parse RTSP header fields */ +RTSP_DECLARE(apt_bool_t) rtsp_header_fields_parse(rtsp_header_t *header, apr_pool_t *pool) { - const apt_str_t *name; - apr_size_t i; - rtsp_header_property_t property_set; - - property_set = header->property_set; - for(i=0; iheader_section.ring); + header_field != APR_RING_SENTINEL(&header->header_section.ring, apt_header_field_t, link); + header_field = APR_RING_NEXT(header_field, link)) { + + header_field->id = apt_string_table_id_find( + rtsp_header_string_table, + RTSP_HEADER_FIELD_COUNT, + &header_field->name); + if(apt_string_is_empty(&header_field->value) == FALSE) { + rtsp_header_field_value_parse(header,header_field->id,&header_field->value,pool); } + apt_header_section_field_set(&header->header_section,header_field); } - - apt_text_eol_insert(text_stream); return TRUE; } + +/** Add RTSP header field property */ +RTSP_DECLARE(apt_bool_t) rtsp_header_property_add(rtsp_header_t *header, rtsp_header_field_id id, apr_pool_t *pool) +{ + apt_header_field_t *header_field; + header_field = apt_header_section_field_get(&header->header_section,id); + if(header_field) { + /* such header field already exists, just (re)generate value */ + return rtsp_header_field_value_generate(header,id,&header_field->value,pool); + } + + header_field = apt_header_field_alloc(pool); + if(rtsp_header_field_value_generate(header,id,&header_field->value,pool) == TRUE) { + const apt_str_t *name = apt_string_table_str_get(rtsp_header_string_table,RTSP_HEADER_FIELD_COUNT,id); + if(name) { + header_field->name = *name; + header_field->id = id; + return apt_header_section_field_insert(&header->header_section,header_field); + } + } + return FALSE; +} diff --git a/libs/unimrcp/libs/uni-rtsp/src/rtsp_message.c b/libs/unimrcp/libs/uni-rtsp/src/rtsp_message.c index 2bb2ee60d0..4a8eb2a31d 100644 --- a/libs/unimrcp/libs/uni-rtsp/src/rtsp_message.c +++ b/libs/unimrcp/libs/uni-rtsp/src/rtsp_message.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_message.c 1648 2010-04-12 20:03:59Z achaloyan $ */ #include "rtsp_message.h" @@ -21,7 +23,7 @@ static APR_INLINE void rtsp_message_init(rtsp_message_t *message, rtsp_message_t { message->pool = pool; rtsp_start_line_init(&message->start_line,message_type); - rtsp_header_init(&message->header); + rtsp_header_init(&message->header,pool); apt_string_reset(&message->body); } @@ -55,17 +57,16 @@ RTSP_DECLARE(rtsp_message_t*) rtsp_response_create(const rtsp_message_t *request apt_string_copy(&status_line->reason,reason_str,pool); } - if(rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_CSEQ) == TRUE) { + if(rtsp_header_property_check(&request->header,RTSP_HEADER_FIELD_CSEQ) == TRUE) { response->header.cseq = request->header.cseq; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CSEQ); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_CSEQ,response->pool); } - if(rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_TRANSPORT) == TRUE) { + if(rtsp_header_property_check(&request->header,RTSP_HEADER_FIELD_TRANSPORT) == TRUE) { const rtsp_transport_t *req_transport = &request->header.transport; rtsp_transport_t *res_transport = &response->header.transport; if(req_transport->mode.length) { apt_string_copy(&res_transport->mode,&req_transport->mode,pool); - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_TRANSPORT); } } diff --git a/libs/unimrcp/libs/uni-rtsp/src/rtsp_server.c b/libs/unimrcp/libs/uni-rtsp/src/rtsp_server.c index c9f6c8c2b3..e025358388 100644 --- a/libs/unimrcp/libs/uni-rtsp/src/rtsp_server.c +++ b/libs/unimrcp/libs/uni-rtsp/src/rtsp_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,12 +12,14 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_server.c 1710 2010-05-24 17:36:19Z achaloyan $ */ #include #include "rtsp_server.h" #include "rtsp_stream.h" -#include "apt_net_server_task.h" +#include "apt_poller_task.h" #include "apt_text_stream.h" #include "apt_pool.h" #include "apt_obj_list.h" @@ -31,35 +33,48 @@ typedef struct rtsp_server_connection_t rtsp_server_connection_t; /** RTSP server */ struct rtsp_server_t { apr_pool_t *pool; - apt_net_server_task_t *task; + apt_poller_task_t *task; apr_pool_t *sub_pool; apt_obj_list_t *connection_list; + /* Listening socket descriptor */ + apr_sockaddr_t *sockaddr; + apr_socket_t *listen_sock; + apr_pollfd_t listen_sock_pfd; + void *obj; const rtsp_server_vtable_t *vtable; }; /** RTSP connection */ struct rtsp_server_connection_t { - /** Connection base */ - apt_net_server_connection_t *base; + /** Memory pool */ + apr_pool_t *pool; + /** Client IP address */ + char *client_ip; + /** Accepted socket */ + apr_socket_t *sock; + /** Socket poll descriptor */ + apr_pollfd_t sock_pfd; + /** String identifier used for traces */ + const char *id; /** RTSP server, connection belongs to */ - rtsp_server_t *server; + rtsp_server_t *server; /** Element of the connection list in agent */ - apt_list_elem_t *it; + apt_list_elem_t *it; /** Session table (rtsp_server_session_t*) */ - apr_hash_t *session_table; + apr_hash_t *session_table; - char rx_buffer[RTSP_STREAM_BUFFER_SIZE]; - apt_text_stream_t rx_stream; - rtsp_parser_t *parser; + char rx_buffer[RTSP_STREAM_BUFFER_SIZE]; + apt_text_stream_t rx_stream; + rtsp_parser_t *parser; - char tx_buffer[RTSP_STREAM_BUFFER_SIZE]; - apt_text_stream_t tx_stream; - rtsp_generator_t *generator; + char tx_buffer[RTSP_STREAM_BUFFER_SIZE]; + apt_text_stream_t tx_stream; + rtsp_generator_t *generator; }; /** RTSP session */ @@ -100,19 +115,14 @@ struct task_msg_data_t { rtsp_message_t *message; }; +static apt_bool_t rtsp_server_on_destroy(apt_task_t *task); static apt_bool_t rtsp_server_task_msg_process(apt_task_t *task, apt_task_msg_t *msg); +static apt_bool_t rtsp_server_poller_signal_process(void *obj, const apr_pollfd_t *descriptor); +static apt_bool_t rtsp_server_message_send(rtsp_server_t *server, rtsp_server_connection_t *connection, rtsp_message_t *message); -static apt_bool_t rtsp_server_on_connect(apt_net_server_task_t *task, apt_net_server_connection_t *connection); -static apt_bool_t rtsp_server_on_disconnect(apt_net_server_task_t *task, apt_net_server_connection_t *connection); -static apt_bool_t rtsp_server_message_receive(apt_net_server_task_t *task, apt_net_server_connection_t *connection); - -static const apt_net_server_vtable_t server_vtable = { - rtsp_server_on_connect, - rtsp_server_on_disconnect, - rtsp_server_message_receive -}; +static apt_bool_t rtsp_server_listening_socket_create(rtsp_server_t *server); +static void rtsp_server_listening_socket_destroy(rtsp_server_t *server); -static apt_bool_t rtsp_server_message_send(rtsp_server_t *server, apt_net_server_connection_t *connection, rtsp_message_t *message); /** Create RTSP server */ RTSP_DECLARE(rtsp_server_t*) rtsp_server_create( @@ -132,58 +142,83 @@ RTSP_DECLARE(rtsp_server_t*) rtsp_server_create( } apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create RTSP Server %s:%hu [%"APR_SIZE_T_FMT"]", - listen_ip,listen_port,max_connection_count); + listen_ip, + listen_port, + max_connection_count); server = apr_palloc(pool,sizeof(rtsp_server_t)); server->pool = pool; server->obj = obj; server->vtable = handler; + server->listen_sock = NULL; + server->sockaddr = NULL; + apr_sockaddr_info_get(&server->sockaddr,listen_ip,APR_INET,listen_port,0,pool); + if(!server->sockaddr) { + return NULL; + } + msg_pool = apt_task_msg_pool_create_dynamic(sizeof(task_msg_data_t),pool); - server->task = apt_net_server_task_create( - listen_ip,listen_port,max_connection_count, - server,&server_vtable,msg_pool,pool); + server->task = apt_poller_task_create( + max_connection_count + 1, + rtsp_server_poller_signal_process, + server, + msg_pool, + pool); if(!server->task) { return NULL; } - - vtable = apt_net_server_task_vtable_get(server->task); + + vtable = apt_poller_task_vtable_get(server->task); if(vtable) { + vtable->destroy = rtsp_server_on_destroy; vtable->process_msg = rtsp_server_task_msg_process; } server->sub_pool = apt_subpool_create(pool); server->connection_list = NULL; + + rtsp_server_listening_socket_create(server); return server; } +static apt_bool_t rtsp_server_on_destroy(apt_task_t *task) +{ + apt_poller_task_t *poller_task = apt_task_object_get(task); + rtsp_server_t *server = apt_poller_task_object_get(poller_task); + + rtsp_server_listening_socket_destroy(server); + apt_poller_task_cleanup(poller_task); + return TRUE; +} + /** Destroy RTSP server */ RTSP_DECLARE(apt_bool_t) rtsp_server_destroy(rtsp_server_t *server) { apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Destroy RTSP Server"); - return apt_net_server_task_destroy(server->task); + return apt_poller_task_destroy(server->task); } -/** Start connection agent. */ +/** Start connection agent */ RTSP_DECLARE(apt_bool_t) rtsp_server_start(rtsp_server_t *server) { - return apt_net_server_task_start(server->task); + return apt_poller_task_start(server->task); } -/** Terminate connection agent. */ +/** Terminate connection agent */ RTSP_DECLARE(apt_bool_t) rtsp_server_terminate(rtsp_server_t *server) { - return apt_net_server_task_terminate(server->task); + return apt_poller_task_terminate(server->task); } /** Get task */ -RTSP_DECLARE(apt_task_t*) rtsp_server_task_get(rtsp_server_t *server) +RTSP_DECLARE(apt_task_t*) rtsp_server_task_get(const rtsp_server_t *server) { - return apt_net_server_task_base_get(server->task); + return apt_poller_task_base_get(server->task); } /** Get external object */ -RTSP_DECLARE(void*) rtsp_server_object_get(rtsp_server_t *server) +RTSP_DECLARE(void*) rtsp_server_object_get(const rtsp_server_t *server) { return server->obj; } @@ -216,7 +251,7 @@ RTSP_DECLARE(const rtsp_message_t*) rtsp_server_session_request_get(const rtsp_s RTSP_DECLARE(const char*) rtsp_server_session_destination_get(const rtsp_server_session_t *session) { if(session->connection) { - return session->connection->base->client_ip; + return session->connection->client_ip; } return NULL; } @@ -228,7 +263,7 @@ static apt_bool_t rtsp_server_control_message_signal( rtsp_server_session_t *session, rtsp_message_t *message) { - apt_task_t *task = apt_net_server_task_base_get(server->task); + apt_task_t *task = apt_poller_task_base_get(server->task); apt_task_msg_t *task_msg = apt_task_msg_get(task); if(task_msg) { task_msg_data_t *data = (task_msg_data_t*)task_msg->data; @@ -285,6 +320,13 @@ static void rtsp_server_session_destroy(rtsp_server_session_t *session) } } +/** Destroy RTSP connection */ +static void rtsp_server_connection_destroy(rtsp_server_connection_t *rtsp_connection) +{ + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Destroy RTSP Connection %s",rtsp_connection->id); + apr_pool_destroy(rtsp_connection->pool); +} + /* Finally terminate RTSP session */ static apt_bool_t rtsp_server_session_do_terminate(rtsp_server_t *server, rtsp_server_session_t *session) { @@ -296,11 +338,11 @@ static apt_bool_t rtsp_server_session_do_terminate(rtsp_server_t *server, rtsp_s if(response) { if(session->id.buf) { response->header.session_id = session->id; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_SESSION_ID); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_SESSION_ID,response->pool); } if(rtsp_connection) { - rtsp_server_message_send(server,rtsp_connection->base,response); + rtsp_server_message_send(server,rtsp_connection,response); } } } @@ -311,7 +353,7 @@ static apt_bool_t rtsp_server_session_do_terminate(rtsp_server_t *server, rtsp_s if(rtsp_connection && !rtsp_connection->it) { if(apr_hash_count(rtsp_connection->session_table) == 0) { - apt_net_server_connection_destroy(rtsp_connection->base); + rtsp_server_connection_destroy(rtsp_connection); } } return TRUE; @@ -322,7 +364,7 @@ static apt_bool_t rtsp_server_error_respond(rtsp_server_t *server, rtsp_server_c { /* send error response to client */ rtsp_message_t *response = rtsp_response_create(request,status_code,reason,request->pool); - if(rtsp_server_message_send(server,rtsp_connection->base,response) == FALSE) { + if(rtsp_server_message_send(server,rtsp_connection,response) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Send RTSP Response"); return FALSE; } @@ -365,6 +407,9 @@ static rtsp_server_session_t* rtsp_server_session_setup_process(rtsp_server_t *s if(message->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) { /* create new session */ session = rtsp_server_session_create(server); + if(!session) { + return NULL; + } session->connection = rtsp_connection; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add RTSP Session "APT_SID_FMT,session->id.buf); apr_hash_set(rtsp_connection->session_table,session->id.buf,session->id.length,session); @@ -372,6 +417,9 @@ static rtsp_server_session_t* rtsp_server_session_setup_process(rtsp_server_t *s else if(message->start_line.common.request_line.method_id == RTSP_METHOD_DESCRIBE) { /* create new session as a communication object */ session = rtsp_server_session_create(server); + if(!session) { + return NULL; + } session->connection = rtsp_connection; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Add RTSP Session "APT_SID_FMT,session->id.buf); apr_hash_set(rtsp_connection->session_table,session->id.buf,session->id.length,session); @@ -395,7 +443,7 @@ static apt_bool_t rtsp_server_session_request_process(rtsp_server_t *server, rts return TRUE; } - if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID) != TRUE) { + if(rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_SESSION_ID) != TRUE) { /* no session-id specified */ session = rtsp_server_session_setup_process(server,rtsp_connection,message); if(session) { @@ -404,6 +452,13 @@ static apt_bool_t rtsp_server_session_request_process(rtsp_server_t *server, rts rtsp_server_session_destroy(session); } } + else { + /* error case, failed to create a session */ + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create RTSP Session"); + return rtsp_server_error_respond(server,rtsp_connection,message, + RTSP_STATUS_CODE_NOT_ACCEPTABLE, + RTSP_REASON_PHRASE_NOT_ACCEPTABLE); + } return TRUE; } @@ -419,7 +474,7 @@ static apt_bool_t rtsp_server_session_request_process(rtsp_server_t *server, rts RTSP_STATUS_CODE_NOT_FOUND, RTSP_REASON_PHRASE_NOT_FOUND); } - + if(session->terminating == TRUE) { /* error case, session is being terminated */ apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Not Acceptable Request "APT_SID_FMT,message->header.session_id.buf); @@ -456,13 +511,13 @@ static apt_bool_t rtsp_server_session_response_process(rtsp_server_t *server, rt } message->start_line.common.request_line.url = request->start_line.common.request_line.url; message->header.cseq = session->last_cseq; - rtsp_header_property_add(&message->header.property_set,RTSP_HEADER_FIELD_CSEQ); + rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_CSEQ,message->pool); if(session->id.buf) { message->header.session_id = session->id; - rtsp_header_property_add(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID); + rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_SESSION_ID,message->pool); } - rtsp_server_message_send(server,session->connection->base,message); + rtsp_server_message_send(server,session->connection,message); return TRUE; } @@ -478,7 +533,7 @@ static apt_bool_t rtsp_server_session_response_process(rtsp_server_t *server, rt else { if(session->id.buf) { message->header.session_id = session->id; - rtsp_header_property_add(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID); + rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_SESSION_ID,message->pool); } if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) { if(message->start_line.common.status_line.status_code == RTSP_STATUS_CODE_OK) { @@ -493,7 +548,7 @@ static apt_bool_t rtsp_server_session_response_process(rtsp_server_t *server, rt } session->last_cseq = message->header.cseq; - rtsp_server_message_send(server,session->connection->base,message); + rtsp_server_message_send(server,session->connection,message); if(terminate == TRUE) { session->active_request = NULL; @@ -509,34 +564,31 @@ static apt_bool_t rtsp_server_session_response_process(rtsp_server_t *server, rt } /* Send RTSP message through RTSP connection */ -static apt_bool_t rtsp_server_message_send(rtsp_server_t *server, apt_net_server_connection_t *connection, rtsp_message_t *message) +static apt_bool_t rtsp_server_message_send(rtsp_server_t *server, rtsp_server_connection_t *rtsp_connection, rtsp_message_t *message) { apt_bool_t status = FALSE; - rtsp_server_connection_t *rtsp_connection; apt_text_stream_t *stream; - rtsp_stream_status_e result; + apt_message_status_e result; - if(!connection || !connection->sock) { + if(!rtsp_connection || !rtsp_connection->sock) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No RTSP Connection"); return FALSE; } - rtsp_connection = connection->obj; stream = &rtsp_connection->tx_stream; - rtsp_generator_message_set(rtsp_connection->generator,message); do { stream->text.length = sizeof(rtsp_connection->tx_buffer)-1; apt_text_stream_reset(stream); - result = rtsp_generator_run(rtsp_connection->generator,stream); - if(result != RTSP_STREAM_STATUS_INVALID) { + result = rtsp_generator_run(rtsp_connection->generator,message,stream); + if(result != APT_MESSAGE_STATUS_INVALID) { stream->text.length = stream->pos - stream->text.buf; *stream->pos = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send RTSP Stream %s [%lu bytes]\n%s", - connection->id, + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send RTSP Stream %s [%"APR_SIZE_T_FMT" bytes]\n%s", + rtsp_connection->id, stream->text.length, stream->text.buf); - if(apr_socket_send(connection->sock,stream->text.buf,&stream->text.length) == APR_SUCCESS) { + if(apr_socket_send(rtsp_connection->sock,stream->text.buf,&stream->text.length) == APR_SUCCESS) { status = TRUE; } else { @@ -547,32 +599,30 @@ static apt_bool_t rtsp_server_message_send(rtsp_server_t *server, apt_net_server apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Generate RTSP Stream"); } } - while(result == RTSP_STREAM_STATUS_INCOMPLETE); + while(result == APT_MESSAGE_STATUS_INCOMPLETE); return status; } -static apt_bool_t rtsp_server_message_handler(void *obj, rtsp_message_t *message, rtsp_stream_status_e status) +static apt_bool_t rtsp_server_message_handler(rtsp_server_connection_t *rtsp_connection, rtsp_message_t *message, apt_message_status_e status) { - rtsp_server_connection_t *rtsp_connection = obj; - if(status == RTSP_STREAM_STATUS_COMPLETE) { + if(status == APT_MESSAGE_STATUS_COMPLETE) { /* message is completely parsed */ apt_str_t *destination; - rtsp_message_t *message = rtsp_parser_message_get(rtsp_connection->parser); destination = &message->header.transport.destination; - if(!destination->buf && rtsp_connection->base->client_ip) { - apt_string_assign(destination,rtsp_connection->base->client_ip,rtsp_connection->base->pool); + if(!destination->buf && rtsp_connection->client_ip) { + apt_string_assign(destination,rtsp_connection->client_ip,rtsp_connection->pool); } rtsp_server_session_request_process(rtsp_connection->server,rtsp_connection,message); } - else if(status == RTSP_STREAM_STATUS_INVALID) { + else if(status == APT_MESSAGE_STATUS_INVALID) { /* error case */ rtsp_message_t *response; apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse RTSP Stream"); if(message) { response = rtsp_response_create(message,RTSP_STATUS_CODE_BAD_REQUEST, RTSP_REASON_PHRASE_BAD_REQUEST,message->pool); - if(rtsp_server_message_send(rtsp_connection->server,rtsp_connection->base,response) == FALSE) { + if(rtsp_server_message_send(rtsp_connection->server,rtsp_connection,response) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Send RTSP Response"); } } @@ -580,72 +630,143 @@ static apt_bool_t rtsp_server_message_handler(void *obj, rtsp_message_t *message return TRUE; } -/* Receive RTSP message through RTSP connection */ -static apt_bool_t rtsp_server_message_receive(apt_net_server_task_t *task, apt_net_server_connection_t *connection) +/** Create listening socket and add to pollset */ +static apt_bool_t rtsp_server_listening_socket_create(rtsp_server_t *server) { - rtsp_server_connection_t *rtsp_connection; apr_status_t status; - apr_size_t offset; - apr_size_t length; - apt_text_stream_t *stream; + apt_pollset_t *pollset = apt_poller_task_pollset_get(server->task); + + if(!server->sockaddr || !pollset) { + return FALSE; + } - if(!connection || !connection->sock) { + /* create listening socket */ + status = apr_socket_create(&server->listen_sock, server->sockaddr->family, SOCK_STREAM, APR_PROTO_TCP, server->pool); + if(status != APR_SUCCESS) { return FALSE; } - rtsp_connection = connection->obj; - stream = &rtsp_connection->rx_stream; - /* init length of the stream */ - stream->text.length = sizeof(rtsp_connection->rx_buffer)-1; - /* calculate offset remaining from the previous receive / if any */ - offset = stream->pos - stream->text.buf; - /* calculate available length */ - length = stream->text.length - offset; - status = apr_socket_recv(connection->sock,stream->pos,&length); - if(status == APR_EOF || length == 0) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"TCP Peer Disconnected %s",connection->id); - return apt_net_server_connection_close(task,connection); + apr_socket_opt_set(server->listen_sock, APR_SO_NONBLOCK, 0); + apr_socket_timeout_set(server->listen_sock, -1); + apr_socket_opt_set(server->listen_sock, APR_SO_REUSEADDR, 1); + + status = apr_socket_bind(server->listen_sock, server->sockaddr); + if(status != APR_SUCCESS) { + apr_socket_close(server->listen_sock); + server->listen_sock = NULL; + return FALSE; + } + status = apr_socket_listen(server->listen_sock, SOMAXCONN); + if(status != APR_SUCCESS) { + apr_socket_close(server->listen_sock); + server->listen_sock = NULL; + return FALSE; } - /* calculate actual length of the stream */ - stream->text.length = offset + length; - stream->pos[length] = '\0'; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive RTSP Stream %s [%lu bytes]\n%s", - connection->id, - length, - stream->pos); - /* reset pos */ - apt_text_stream_reset(stream); - /* walk through the stream parsing RTSP messages */ - return rtsp_stream_walk(rtsp_connection->parser,stream,rtsp_server_message_handler,rtsp_connection); + memset(&server->listen_sock_pfd,0,sizeof(apr_pollfd_t)); + server->listen_sock_pfd.desc_type = APR_POLL_SOCKET; + server->listen_sock_pfd.reqevents = APR_POLLIN; + server->listen_sock_pfd.desc.s = server->listen_sock; + server->listen_sock_pfd.client_data = server->listen_sock; + if(apt_pollset_add(pollset, &server->listen_sock_pfd) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add Listening Socket to Pollset"); + apr_socket_close(server->listen_sock); + server->listen_sock = NULL; + } + + return TRUE; +} + +/** Remove from pollset and destroy listening socket */ +static void rtsp_server_listening_socket_destroy(rtsp_server_t *server) +{ + apt_pollset_t *pollset = apt_poller_task_pollset_get(server->task); + if(pollset) { + apt_pollset_remove(pollset,&server->listen_sock_pfd); + } + + if(server->listen_sock) { + apr_socket_close(server->listen_sock); + server->listen_sock = NULL; + } } -/* New RTSP connection accepted */ -static apt_bool_t rtsp_server_on_connect(apt_net_server_task_t *task, apt_net_server_connection_t *connection) +/* Accept RTSP connection */ +static apt_bool_t rtsp_server_connection_accept(rtsp_server_t *server) { - rtsp_server_t *server = apt_net_server_task_object_get(task); - rtsp_server_connection_t *rtsp_connection = apr_palloc(connection->pool,sizeof(rtsp_server_connection_t)); - rtsp_connection->session_table = apr_hash_make(connection->pool); + rtsp_server_connection_t *rtsp_connection; + char *local_ip = NULL; + char *remote_ip = NULL; + apr_sockaddr_t *l_sockaddr = NULL; + apr_sockaddr_t *r_sockaddr = NULL; + apt_pollset_t *pollset = apt_poller_task_pollset_get(server->task); + apr_pool_t *pool = apt_pool_create(); + if(!pool) { + return FALSE; + } + + rtsp_connection = apr_palloc(pool,sizeof(rtsp_server_connection_t)); + rtsp_connection->pool = pool; + rtsp_connection->sock = NULL; + rtsp_connection->client_ip = NULL; + + if(apr_socket_accept(&rtsp_connection->sock,server->listen_sock,rtsp_connection->pool) != APR_SUCCESS) { + apr_pool_destroy(pool); + return FALSE; + } + + if(apr_socket_addr_get(&l_sockaddr,APR_LOCAL,rtsp_connection->sock) != APR_SUCCESS || + apr_socket_addr_get(&r_sockaddr,APR_REMOTE,rtsp_connection->sock) != APR_SUCCESS) { + apr_pool_destroy(pool); + return FALSE; + } + + apr_sockaddr_ip_get(&local_ip,l_sockaddr); + apr_sockaddr_ip_get(&remote_ip,r_sockaddr); + rtsp_connection->client_ip = remote_ip; + rtsp_connection->id = apr_psprintf(pool,"%s:%hu <-> %s:%hu", + local_ip,l_sockaddr->port, + remote_ip,r_sockaddr->port); + + memset(&rtsp_connection->sock_pfd,0,sizeof(apr_pollfd_t)); + rtsp_connection->sock_pfd.desc_type = APR_POLL_SOCKET; + rtsp_connection->sock_pfd.reqevents = APR_POLLIN; + rtsp_connection->sock_pfd.desc.s = rtsp_connection->sock; + rtsp_connection->sock_pfd.client_data = rtsp_connection; + if(apt_pollset_add(pollset,&rtsp_connection->sock_pfd) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Add to Pollset %s",rtsp_connection->id); + apr_socket_close(rtsp_connection->sock); + apr_pool_destroy(pool); + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Accepted TCP Connection %s",rtsp_connection->id); + rtsp_connection->session_table = apr_hash_make(rtsp_connection->pool); apt_text_stream_init(&rtsp_connection->rx_stream,rtsp_connection->rx_buffer,sizeof(rtsp_connection->rx_buffer)-1); apt_text_stream_init(&rtsp_connection->tx_stream,rtsp_connection->tx_buffer,sizeof(rtsp_connection->tx_buffer)-1); - rtsp_connection->parser = rtsp_parser_create(connection->pool); - rtsp_connection->generator = rtsp_generator_create(connection->pool); - rtsp_connection->base = connection; - connection->obj = rtsp_connection; + rtsp_connection->parser = rtsp_parser_create(rtsp_connection->pool); + rtsp_connection->generator = rtsp_generator_create(rtsp_connection->pool); if(!server->connection_list) { server->connection_list = apt_list_create(server->sub_pool); } rtsp_connection->server = server; - rtsp_connection->it = apt_list_push_back(server->connection_list,rtsp_connection,connection->pool); + rtsp_connection->it = apt_list_push_back(server->connection_list,rtsp_connection,rtsp_connection->pool); return TRUE; } -/* RTSP connection disconnected */ -static apt_bool_t rtsp_server_on_disconnect(apt_net_server_task_t *task, apt_net_server_connection_t *connection) +/** Close connection */ +static apt_bool_t rtsp_server_connection_close(rtsp_server_t *server, rtsp_server_connection_t *rtsp_connection) { + apt_pollset_t *pollset = apt_poller_task_pollset_get(server->task); apr_size_t remaining_sessions = 0; - rtsp_server_t *server = apt_net_server_task_object_get(task); - rtsp_server_connection_t *rtsp_connection = connection->obj; + if(!rtsp_connection || !rtsp_connection->sock) { + return FALSE; + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close RTSP Connection %s",rtsp_connection->id); + apt_pollset_remove(pollset,&rtsp_connection->sock_pfd); + apr_socket_close(rtsp_connection->sock); + rtsp_connection->sock = NULL; + apt_list_elem_remove(server->connection_list,rtsp_connection->it); rtsp_connection->it = NULL; if(apt_list_is_empty(server->connection_list) == TRUE) { @@ -660,7 +781,7 @@ static apt_bool_t rtsp_server_on_disconnect(apt_net_server_task_t *task, apt_net apr_hash_index_t *it; apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Terminate Remaining RTSP Sessions [%"APR_SIZE_T_FMT"]", remaining_sessions); - it = apr_hash_first(connection->pool,rtsp_connection->session_table); + it = apr_hash_first(rtsp_connection->pool,rtsp_connection->session_table); for(; it; it = apr_hash_next(it)) { apr_hash_this(it,NULL,NULL,&val); session = val; @@ -670,16 +791,72 @@ static apt_bool_t rtsp_server_on_disconnect(apt_net_server_task_t *task, apt_net } } else { - apt_net_server_connection_destroy(connection); + rtsp_server_connection_destroy(rtsp_connection); } return TRUE; } + +/* Receive RTSP message through RTSP connection */ +static apt_bool_t rtsp_server_poller_signal_process(void *obj, const apr_pollfd_t *descriptor) +{ + rtsp_server_t *server = obj; + rtsp_server_connection_t *rtsp_connection = descriptor->client_data; + apr_status_t status; + apr_size_t offset; + apr_size_t length; + apt_text_stream_t *stream; + rtsp_message_t *message; + apt_message_status_e msg_status; + + if(descriptor->desc.s == server->listen_sock) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Accept Connection"); + return rtsp_server_connection_accept(server); + } + + if(!rtsp_connection || !rtsp_connection->sock) { + return FALSE; + } + stream = &rtsp_connection->rx_stream; + + /* calculate offset remaining from the previous receive / if any */ + offset = stream->pos - stream->text.buf; + /* calculate available length */ + length = sizeof(rtsp_connection->rx_buffer) - 1 - offset; + + status = apr_socket_recv(rtsp_connection->sock,stream->pos,&length); + if(status == APR_EOF || length == 0) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"RTSP Peer Disconnected %s",rtsp_connection->id); + return rtsp_server_connection_close(server,rtsp_connection); + } + + /* calculate actual length of the stream */ + stream->text.length = offset + length; + stream->pos[length] = '\0'; + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive RTSP Stream %s [%"APR_SIZE_T_FMT" bytes]\n%s", + rtsp_connection->id, + length, + stream->pos); + + /* reset pos */ + apt_text_stream_reset(stream); + + do { + msg_status = rtsp_parser_run(rtsp_connection->parser,stream,&message); + rtsp_server_message_handler(rtsp_connection,message,msg_status); + } + while(apt_text_is_eos(stream) == FALSE); + + /* scroll remaining stream */ + apt_text_stream_scroll(stream); + return TRUE; +} + /* Process task message */ static apt_bool_t rtsp_server_task_msg_process(apt_task_t *task, apt_task_msg_t *task_msg) { - apt_net_server_task_t *net_task = apt_task_object_get(task); - rtsp_server_t *server = apt_net_server_task_object_get(net_task); + apt_poller_task_t *poller_task = apt_task_object_get(task); + rtsp_server_t *server = apt_poller_task_object_get(poller_task); task_msg_data_t *data = (task_msg_data_t*) task_msg->data; switch(data->type) { diff --git a/libs/unimrcp/libs/uni-rtsp/src/rtsp_start_line.c b/libs/unimrcp/libs/uni-rtsp/src/rtsp_start_line.c index 24449a8976..7e06a2e541 100644 --- a/libs/unimrcp/libs/uni-rtsp/src/rtsp_start_line.c +++ b/libs/unimrcp/libs/uni-rtsp/src/rtsp_start_line.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_start_line.c 1671 2010-04-28 19:50:29Z achaloyan $ */ #include "rtsp_start_line.h" @@ -43,6 +45,8 @@ static const apt_str_table_item_t rtsp_reason_string_table[] = { {{"Not Found", 9},4}, {{"Method Not Allowed", 18},0}, {{"Not Acceptable", 14},4}, + {{"Proxy Auth Required", 19},0}, + {{"Request Timeout", 15},0}, {{"Session Not Found", 17},0}, {{"Internal Server Error", 21},0}, {{"Not Implemented", 15},4} @@ -95,10 +99,20 @@ static rtsp_version_e rtsp_version_parse(const apt_str_t *field) /** Generate RTSP version */ static apt_bool_t rtsp_version_generate(rtsp_version_e version, apt_text_stream_t *stream) { + if(stream->pos + RTSP_NAME_LENGTH + 1 >= stream->end) { + return FALSE; + } memcpy(stream->pos,RTSP_NAME,RTSP_NAME_LENGTH); stream->pos += RTSP_NAME_LENGTH; *stream->pos++ = RTSP_NAME_VERSION_SEPARATOR; - apt_size_value_generate(version,stream); + + if(apt_text_size_value_insert(stream,version) == FALSE) { + return FALSE; + } + + if(stream->pos + 2 >= stream->end) { + return FALSE; + } *stream->pos++ = RTSP_VERSION_MAJOR_MINOR_SEPARATOR; *stream->pos++ = '0'; return TRUE; @@ -113,7 +127,7 @@ static APR_INLINE rtsp_status_code_e rtsp_status_code_parse(const apt_str_t *fie /** Generate RTSP status-code */ static APR_INLINE apt_bool_t rtsp_status_code_generate(rtsp_status_code_e status_code, apt_text_stream_t *stream) { - return apt_size_value_generate(status_code,stream); + return apt_text_size_value_insert(stream,status_code); } /** Generate RTSP request-line */ @@ -124,40 +138,50 @@ static apt_bool_t rtsp_request_line_generate(rtsp_request_line_t *start_line, ap return FALSE; } start_line->method_name = *method_name; - apt_string_value_generate(&start_line->method_name,stream); - apt_text_space_insert(stream); + if(apt_text_string_insert(stream,&start_line->method_name) == FALSE) { + return FALSE; + } + if(apt_text_space_insert(stream) == FALSE) { + return FALSE; + } - apt_string_value_generate(&start_line->url,stream); - apt_text_space_insert(stream); + if(apt_text_string_insert(stream,&start_line->url) == FALSE) { + return FALSE; + } + if(apt_text_space_insert(stream) == FALSE) { + return FALSE; + } - rtsp_version_generate(start_line->version,stream); - return TRUE; + return rtsp_version_generate(start_line->version,stream); } /** Generate RTSP status-line */ static apt_bool_t rtsp_status_line_generate(rtsp_status_line_t *start_line, apt_text_stream_t *stream) { - rtsp_version_generate(start_line->version,stream); - apt_text_space_insert(stream); + if(rtsp_version_generate(start_line->version,stream) == FALSE) { + return FALSE; + } + if(apt_text_space_insert(stream) == FALSE) { + return FALSE; + } - rtsp_status_code_generate(start_line->status_code,stream); - apt_text_space_insert(stream); + if(rtsp_status_code_generate(start_line->status_code,stream) == FALSE) { + return FALSE; + } + if(apt_text_space_insert(stream) == FALSE) { + return FALSE; + } - apt_string_value_generate(&start_line->reason,stream); - return TRUE; + return apt_text_string_insert(stream,&start_line->reason); } /** Parse RTSP start-line */ -RTSP_DECLARE(apt_bool_t) rtsp_start_line_parse(rtsp_start_line_t *start_line, apt_text_stream_t *stream, apr_pool_t *pool) +RTSP_DECLARE(apt_bool_t) rtsp_start_line_parse(rtsp_start_line_t *start_line, apt_str_t *str, apr_pool_t *pool) { apt_text_stream_t line; apt_str_t field; - if(apt_text_line_read(stream,&line.text) == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot parse RTSP start-line"); - return FALSE; - } - apt_text_stream_reset(&line); + apt_text_stream_init(&line,str->buf,str->length); if(apt_text_field_read(&line,APT_TOKEN_SP,TRUE,&field) == FALSE) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot read the first field in start-line"); return FALSE; @@ -223,11 +247,11 @@ RTSP_DECLARE(apt_bool_t) rtsp_start_line_generate(rtsp_start_line_t *start_line, break; } - if(status == TRUE) { - apt_text_eol_insert(stream); + if(status == FALSE) { + return FALSE; } - - return status; + + return apt_text_eol_insert(stream); } /** Get reason phrase by status code */ diff --git a/libs/unimrcp/libs/uni-rtsp/src/rtsp_stream.c b/libs/unimrcp/libs/uni-rtsp/src/rtsp_stream.c index bb8633fb70..845c17503b 100644 --- a/libs/unimrcp/libs/uni-rtsp/src/rtsp_stream.c +++ b/libs/unimrcp/libs/uni-rtsp/src/rtsp_stream.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,280 +12,113 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: rtsp_stream.c 1648 2010-04-12 20:03:59Z achaloyan $ */ #include "rtsp_stream.h" #include "apt_log.h" -/** Stage of RTSP stream processing (parse/generate) */ -typedef enum { - RTSP_STREAM_STAGE_NONE, - RTSP_STREAM_STAGE_START_LINE, - RTSP_STREAM_STAGE_HEADER, - RTSP_STREAM_STAGE_BODY -} rtsp_stream_stage_e; - /** RTSP parser */ struct rtsp_parser_t { - rtsp_stream_stage_e stage; - apt_bool_t skip_lf; - rtsp_message_t *message; - apr_pool_t *pool; + apt_message_parser_t *base; }; /** RTSP generator */ struct rtsp_generator_t { - rtsp_stream_status_e stage; - rtsp_message_t *message; - apr_pool_t *pool; + apt_message_generator_t *base; }; -/** Read RTSP message-body */ -static apt_bool_t rtsp_message_body_read(rtsp_message_t *message, apt_text_stream_t *stream) -{ - apt_bool_t status = TRUE; - if(message->body.buf) { - /* stream length available to read */ - apr_size_t stream_length = stream->text.length - (stream->pos - stream->text.buf); - /* required/remaining length to read */ - apr_size_t required_length = message->header.content_length - message->body.length; - if(required_length > stream_length) { - required_length = stream_length; - /* not complete */ - status = FALSE; - } - memcpy(message->body.buf+message->body.length,stream->pos,required_length); - message->body.length += required_length; - stream->pos += required_length; - message->body.buf[message->body.length] = '\0'; - } +/** Create message and read start line */ +static apt_bool_t rtsp_parser_on_start(apt_message_parser_t *parser, apt_message_context_t *context, apt_text_stream_t *stream, apr_pool_t *pool); +/** Header section handler */ +static apt_bool_t rtsp_parser_on_header_complete(apt_message_parser_t *parser, apt_message_context_t *context); - return status; -} +static const apt_message_parser_vtable_t parser_vtable = { + rtsp_parser_on_start, + rtsp_parser_on_header_complete, + NULL +}; -/** Write RTSP message-body */ -static apt_bool_t rtsp_message_body_write(rtsp_message_t *message, apt_text_stream_t *stream) -{ - apt_bool_t status = TRUE; - if(message->body.length < message->header.content_length) { - /* stream length available to write */ - apr_size_t stream_length = stream->text.length - (stream->pos - stream->text.buf); - /* required/remaining length to write */ - apr_size_t required_length = message->header.content_length - message->body.length; - if(required_length > stream_length) { - required_length = stream_length; - /* not complete */ - status = FALSE; - } - memcpy(stream->pos,message->body.buf+message->body.length,required_length); - message->body.length += required_length; - stream->pos += required_length; - } +/** Initialize by generating message start line and return header section and body */ +apt_bool_t rtsp_generator_on_start(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream); + +static const apt_message_generator_vtable_t generator_vtable = { + rtsp_generator_on_start, + NULL, + NULL +}; - return status; -} /** Create RTSP parser */ RTSP_DECLARE(rtsp_parser_t*) rtsp_parser_create(apr_pool_t *pool) { rtsp_parser_t *parser = apr_palloc(pool,sizeof(rtsp_parser_t)); - parser->stage = RTSP_STREAM_STAGE_NONE; - parser->skip_lf = FALSE; - parser->message = NULL; - parser->pool = pool; + parser->base = apt_message_parser_create(parser,&parser_vtable,pool); return parser; } -static rtsp_stream_status_e rtsp_parser_break(rtsp_parser_t *parser, apt_text_stream_t *stream) +/** Parse RTSP stream */ +RTSP_DECLARE(apt_message_status_e) rtsp_parser_run(rtsp_parser_t *parser, apt_text_stream_t *stream, rtsp_message_t **message) { - /* failed to parse message */ - if(apt_text_is_eos(stream) == TRUE) { - /* end of stream reached */ - return RTSP_STREAM_STATUS_INCOMPLETE; - } - - /* error case */ - parser->stage = RTSP_STREAM_STAGE_NONE; - return RTSP_STREAM_STATUS_INVALID; + return apt_message_parser_run(parser->base,stream,(void**)message); } -/** Parse RTSP stream */ -RTSP_DECLARE(rtsp_stream_status_e) rtsp_parser_run(rtsp_parser_t *parser, apt_text_stream_t *stream) +/** Create message and read start line */ +static apt_bool_t rtsp_parser_on_start(apt_message_parser_t *parser, apt_message_context_t *context, apt_text_stream_t *stream, apr_pool_t *pool) { - rtsp_message_t *message = parser->message; - if(parser->stage == RTSP_STREAM_STAGE_NONE || !message) { - /* create new RTSP message */ - message = rtsp_message_create(RTSP_MESSAGE_TYPE_UNKNOWN,parser->pool); - parser->message = message; - parser->stage = RTSP_STREAM_STAGE_START_LINE; - } - - if(parser->stage == RTSP_STREAM_STAGE_START_LINE) { - /* parse start-line */ - if(rtsp_start_line_parse(&message->start_line,stream,message->pool) == FALSE) { - return rtsp_parser_break(parser,stream); - } - parser->stage = RTSP_STREAM_STAGE_HEADER; + rtsp_message_t *message; + apt_str_t start_line; + /* read start line */ + if(apt_text_line_read(stream,&start_line) == FALSE) { + return FALSE; } - - if(parser->stage == RTSP_STREAM_STAGE_HEADER) { - /* parse header */ - if(rtsp_header_parse(&message->header,stream,message->pool) == FALSE) { - return rtsp_parser_break(parser,stream); - } - - parser->stage = RTSP_STREAM_STAGE_NONE; - if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE) { - if(message->header.content_length) { - apt_str_t *body = &message->body; - body->buf = apr_palloc(message->pool,message->header.content_length+1); - body->length = 0; - parser->stage = RTSP_STREAM_STAGE_BODY; - } - } + + message = rtsp_message_create(RTSP_MESSAGE_TYPE_UNKNOWN,pool); + if(rtsp_start_line_parse(&message->start_line,&start_line,message->pool) == FALSE) { + return FALSE; } + + context->message = message; + context->header = &message->header.header_section; + context->body = &message->body; + return TRUE; +} - if(parser->stage == RTSP_STREAM_STAGE_BODY) { - if(rtsp_message_body_read(message,stream) == FALSE) { - return rtsp_parser_break(parser,stream); - } - parser->stage = RTSP_STREAM_STAGE_NONE; - } +/** Header section handler */ +static apt_bool_t rtsp_parser_on_header_complete(apt_message_parser_t *parser, apt_message_context_t *context) +{ + rtsp_message_t *rtsp_message = context->message; + rtsp_header_fields_parse(&rtsp_message->header,rtsp_message->pool); - /* in the worst case message segmentation may occur between and - of the final empty header */ - if(!message->body.length && *(stream->pos-1)== APT_TOKEN_CR) { - /* if this is the case be prepared to skip */ - parser->skip_lf = TRUE; + if(context->body && rtsp_header_property_check(&rtsp_message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE) { + context->body->length = rtsp_message->header.content_length; } - return RTSP_STREAM_STATUS_COMPLETE; -} - -/** Get parsed RTSP message */ -RTSP_DECLARE(rtsp_message_t*) rtsp_parser_message_get(const rtsp_parser_t *parser) -{ - return parser->message; + return TRUE; } - /** Create RTSP stream generator */ RTSP_DECLARE(rtsp_generator_t*) rtsp_generator_create(apr_pool_t *pool) { rtsp_generator_t *generator = apr_palloc(pool,sizeof(rtsp_generator_t)); - generator->stage = RTSP_STREAM_STAGE_NONE; - generator->message = NULL; - generator->pool = pool; + generator->base = apt_message_generator_create(generator,&generator_vtable,pool); return generator; } -/** Set RTSP message to generate */ -RTSP_DECLARE(apt_bool_t) rtsp_generator_message_set(rtsp_generator_t *generator, rtsp_message_t *message) -{ - if(!message) { - return FALSE; - } - generator->message = message; - return TRUE; -} - -static rtsp_stream_status_e rtsp_generator_break(rtsp_generator_t *generator, apt_text_stream_t *stream) -{ - /* failed to generate message */ - if(apt_text_is_eos(stream) == TRUE) { - /* end of stream reached */ - return RTSP_STREAM_STATUS_INCOMPLETE; - } - - /* error case */ - generator->stage = RTSP_STREAM_STAGE_NONE; - return RTSP_STREAM_STATUS_INVALID; -} /** Generate RTSP stream */ -RTSP_DECLARE(rtsp_stream_status_e) rtsp_generator_run(rtsp_generator_t *generator, apt_text_stream_t *stream) +RTSP_DECLARE(apt_message_status_e) rtsp_generator_run(rtsp_generator_t *generator, rtsp_message_t *message, apt_text_stream_t *stream) { - rtsp_message_t *message = generator->message; - if(!message) { - return RTSP_STREAM_STATUS_INVALID; - } - - if(generator->stage == RTSP_STREAM_STAGE_NONE) { - /* generate start-line */ - if(rtsp_start_line_generate(&message->start_line,stream) == FALSE) { - return rtsp_generator_break(generator,stream); - } - - /* generate header */ - if(rtsp_header_generate(&message->header,stream) == FALSE) { - return rtsp_generator_break(generator,stream); - } - - generator->stage = RTSP_STREAM_STAGE_NONE; - if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE) { - if(message->header.content_length) { - apt_str_t *body = &message->body; - body->length = 0; - generator->stage = RTSP_STREAM_STAGE_BODY; - } - } - } - - if(generator->stage == RTSP_STREAM_STAGE_BODY) { - if(rtsp_message_body_write(message,stream) == FALSE) { - return rtsp_generator_break(generator,stream); - } - - generator->stage = RTSP_STREAM_STAGE_NONE; - } - - return RTSP_STREAM_STATUS_COMPLETE; + return apt_message_generator_run(generator->base,message,stream); } - -/** Walk through RTSP stream and invoke message handler for each parsed message */ -RTSP_DECLARE(apt_bool_t) rtsp_stream_walk(rtsp_parser_t *parser, apt_text_stream_t *stream, rtsp_message_handler_f handler, void *obj) +/** Initialize by generating message start line and return header section and body */ +apt_bool_t rtsp_generator_on_start(apt_message_generator_t *generator, apt_message_context_t *context, apt_text_stream_t *stream) { - rtsp_stream_status_e status; - if(parser->skip_lf == TRUE) { - /* skip occurred as a result of message segmentation between and */ - apt_text_char_skip(stream,APT_TOKEN_LF); - parser->skip_lf = FALSE; - } - do { - status = rtsp_parser_run(parser,stream); - if(status == RTSP_STREAM_STATUS_COMPLETE) { - /* message is completely parsed */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Parsed RTSP Message [%lu]", stream->pos - stream->text.buf); - /* connection has already been destroyed, if handler return FALSE */ - if(handler(obj,parser->message,status) == FALSE) { - return TRUE; - } - } - else if(status == RTSP_STREAM_STATUS_INCOMPLETE) { - /* message is partially parsed, to be continued */ - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Truncated RTSP Message [%lu]", stream->pos - stream->text.buf); - /* prepare stream for further processing */ - if(apt_text_stream_scroll(stream) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Scroll RTSP Stream", stream->text.buf); - } - return TRUE; - } - else if(status == RTSP_STREAM_STATUS_INVALID){ - /* error case */ - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse RTSP Message"); - /* invoke message handler */ - if(handler(obj,parser->message,status) == TRUE) { - /* reset stream pos */ - stream->pos = stream->text.buf; - } - return FALSE; - } - } - while(apt_text_is_eos(stream) == FALSE); - - /* reset stream pos */ - apt_text_stream_reset(stream); - return TRUE; + rtsp_message_t *rtsp_message = context->message; + context->header = &rtsp_message->header.header_section; + context->body = &rtsp_message->body; + return rtsp_start_line_generate(&rtsp_message->start_line,stream); } diff --git a/libs/unimrcp/libs/uni-rtsp/unirtsp.2008.vcproj b/libs/unimrcp/libs/uni-rtsp/unirtsp.2008.vcproj deleted file mode 100644 index 4189ab121e..0000000000 --- a/libs/unimrcp/libs/uni-rtsp/unirtsp.2008.vcproj +++ /dev/null @@ -1,321 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/libs/uni-rtsp/unirtsp.2010.vcxproj b/libs/unimrcp/libs/uni-rtsp/unirtsp.2010.vcxproj deleted file mode 100644 index 9fad4f7787..0000000000 --- a/libs/unimrcp/libs/uni-rtsp/unirtsp.2010.vcxproj +++ /dev/null @@ -1,132 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - unirtsp - {504B3154-7A4F-459D-9877-B951021C3F1F} - unirtsp - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;%(PreprocessorDefinitions) - ProgramDatabase - - - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;%(PreprocessorDefinitions) - - - - - X64 - - - codecs;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/libs/uni-rtsp/unirtsp.2010.vcxproj.filters b/libs/unimrcp/libs/uni-rtsp/unirtsp.2010.vcxproj.filters deleted file mode 100644 index 5a1581a2c3..0000000000 --- a/libs/unimrcp/libs/uni-rtsp/unirtsp.2010.vcxproj.filters +++ /dev/null @@ -1,56 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {fd4564ef-9f34-4f23-992d-37f127e289a2} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - include - - - include - - - include - - - include - - - include - - - - - src - - - src - - - src - - - src - - - src - - - src - - - \ No newline at end of file diff --git a/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sdp.h b/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sdp.h index a7938c841a..8061119c58 100644 --- a/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sdp.h +++ b/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sdp.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sdp.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_SDP_H__ -#define __MRCP_SDP_H__ +#ifndef MRCP_SDP_H +#define MRCP_SDP_H /** * @file mrcp_sdp.h @@ -37,4 +39,4 @@ MRCP_DECLARE(apr_size_t) sdp_resource_discovery_string_generate(const char *ip, APT_END_EXTERN_C -#endif /*__MRCP_SDP_H__*/ +#endif /* MRCP_SDP_H */ diff --git a/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_client_agent.h b/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_client_agent.h index 6505c7695e..da9cfdd6eb 100644 --- a/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_client_agent.h +++ b/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_client_agent.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sofiasip_client_agent.h 1700 2010-05-21 18:56:06Z achaloyan $ */ -#ifndef __MRCP_SOFIASIP_CLIENT_AGENT_H__ -#define __MRCP_SOFIASIP_CLIENT_AGENT_H__ +#ifndef MRCP_SOFIASIP_CLIENT_AGENT_H +#define MRCP_SOFIASIP_CLIENT_AGENT_H /** * @file mrcp_sofiasip_client_agent.h @@ -40,30 +42,26 @@ struct mrcp_sofia_client_config_t { apr_port_t local_port; /** Local SIP user name */ char *local_user_name; - - /** Remote IP address */ - char *remote_ip; - /** Remote SIP port */ - apr_port_t remote_port; - /** Remote SIP user name */ - char *remote_user_name; - - /** Force destination ip address. Should be used only in case - SDP contains incorrect connection address (local IP address behind NAT) */ - apt_bool_t force_destination; - /** User agent name */ char *user_agent_name; /** SDP origin */ char *origin; /** SIP transport */ char *transport; + /** SIP T1 timer */ + apr_size_t sip_t1; + /** SIP T2 timer */ + apr_size_t sip_t2; + /** SIP T4 timer */ + apr_size_t sip_t4; + /** SIP T1x64 timer */ + apr_size_t sip_t1x64; }; /** * Create Sofia-SIP signaling agent. */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_client_agent_create(mrcp_sofia_client_config_t *config, apr_pool_t *pool); +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_client_agent_create(const char *id, mrcp_sofia_client_config_t *config, apr_pool_t *pool); /** * Allocate Sofia-SIP config. @@ -72,4 +70,4 @@ MRCP_DECLARE(mrcp_sofia_client_config_t*) mrcp_sofiasip_client_config_alloc(apr_ APT_END_EXTERN_C -#endif /*__MRCP_SOFIASIP_CLIENT_AGENT_H__*/ +#endif /* MRCP_SOFIASIP_CLIENT_AGENT_H */ diff --git a/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_server_agent.h b/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_server_agent.h index 85bdea45f4..7876d59f68 100644 --- a/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_server_agent.h +++ b/libs/unimrcp/modules/mrcp-sofiasip/include/mrcp_sofiasip_server_agent.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sofiasip_server_agent.h 1700 2010-05-21 18:56:06Z achaloyan $ */ -#ifndef __MRCP_SOFIASIP_SERVER_AGENT_H__ -#define __MRCP_SOFIASIP_SERVER_AGENT_H__ +#ifndef MRCP_SOFIASIP_SERVER_AGENT_H +#define MRCP_SOFIASIP_SERVER_AGENT_H /** * @file mrcp_sofiasip_server_agent.h @@ -38,7 +40,6 @@ struct mrcp_sofia_server_config_t { char *ext_ip; /** Local port to bind to */ apr_port_t local_port; - /** SIP user name */ char *user_name; /** User agent name */ @@ -47,16 +48,23 @@ struct mrcp_sofia_server_config_t { char *origin; /** SIP transport */ char *transport; - /** Force destination ip address. Should be used only in case SDP contains incorrect connection address (local IP address behind NAT) */ apt_bool_t force_destination; + /** SIP T1 timer */ + apr_size_t sip_t1; + /** SIP T2 timer */ + apr_size_t sip_t2; + /** SIP T4 timer */ + apr_size_t sip_t4; + /** SIP T1x64 timer */ + apr_size_t sip_t1x64; }; /** * Create Sofia-SIP signaling agent. */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_server_agent_create(mrcp_sofia_server_config_t *config, apr_pool_t *pool); +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_server_agent_create(const char *id, mrcp_sofia_server_config_t *config, apr_pool_t *pool); /** * Allocate Sofia-SIP config. @@ -65,4 +73,4 @@ MRCP_DECLARE(mrcp_sofia_server_config_t*) mrcp_sofiasip_server_config_alloc(apr_ APT_END_EXTERN_C -#endif /*__MRCP_SOFIASIP_SERVER_AGENT_H__*/ +#endif /* MRCP_SOFIASIP_SERVER_AGENT_H */ diff --git a/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2008.vcproj b/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2008.vcproj deleted file mode 100644 index 5b10a418b3..0000000000 --- a/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2008.vcproj +++ /dev/null @@ -1,293 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2010.vcxproj b/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2010.vcxproj deleted file mode 100644 index b3931497c7..0000000000 --- a/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2010.vcxproj +++ /dev/null @@ -1,138 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mrcpsofiasip - {746F3632-5BB2-4570-9453-31D6D58A7D8E} - mrcpsofiasip - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - - - - - X64 - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - ProgramDatabase - - - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - - - - - X64 - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - {70a49bc2-7500-41d0-b75d-edcc5be987a0} - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2010.vcxproj.filters b/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2010.vcxproj.filters deleted file mode 100644 index d2157eea88..0000000000 --- a/libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2010.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {6e92b598-880e-4fe5-88fb-f69df8e06a57} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - include - - - - - src - - - src - - - src - - - \ No newline at end of file diff --git a/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sdp.c b/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sdp.c index 7af406ff1c..23a1efe8d9 100644 --- a/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sdp.c +++ b/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sdp.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sdp.c 1647 2010-04-12 19:34:53Z achaloyan $ */ #include @@ -331,7 +333,7 @@ static apt_bool_t mrcp_control_media_generate(mrcp_control_descriptor_t *control apt_string_set(&name,sdp_media->m_proto_name); control_media->proto = mrcp_proto_find(&name); if(control_media->proto != MRCP_PROTO_TCP) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Not supported SDP Proto [%s], expected [%s]",sdp_media->m_proto_name,mrcp_proto_get(MRCP_PROTO_TCP)); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Not supported SDP Proto [%s], expected [%s]",sdp_media->m_proto_name,mrcp_proto_get(MRCP_PROTO_TCP)->buf); return FALSE; } diff --git a/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_client_agent.c b/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_client_agent.c index aa7a5fb753..6ef4199fbe 100644 --- a/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_client_agent.c +++ b/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_client_agent.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sofiasip_client_agent.c 1799 2011-05-12 02:32:32Z achaloyan $ */ typedef struct mrcp_sofia_agent_t mrcp_sofia_agent_t; @@ -35,14 +37,11 @@ typedef struct mrcp_sofia_session_t mrcp_sofia_session_t; #include "mrcp_sdp.h" #include "apt_log.h" -#define SOFIA_TASK_NAME "SofiaSIP Agent" - struct mrcp_sofia_agent_t { mrcp_sig_agent_t *sig_agent; mrcp_sofia_client_config_t *config; char *sip_contact_str; - char *sip_to_str; char *sip_from_str; char *sip_bind_str; @@ -51,12 +50,16 @@ struct mrcp_sofia_agent_t { }; struct mrcp_sofia_session_t { - mrcp_session_t *session; - su_home_t *home; - nua_handle_t *nh; + mrcp_session_t *session; + mrcp_sig_settings_t *sip_settings; + char *sip_to_str; + + su_home_t *home; + nua_handle_t *nh; - apt_bool_t terminate_requested; - apr_thread_mutex_t *mutex; + apt_bool_t terminate_requested; + mrcp_session_descriptor_t *descriptor; + apr_thread_mutex_t *mutex; }; /* Task Interface */ @@ -77,7 +80,7 @@ static const mrcp_session_request_vtable_t session_request_vtable = { }; static apt_bool_t mrcp_sofia_config_validate(mrcp_sofia_agent_t *sofia_agent, mrcp_sofia_client_config_t *config, apr_pool_t *pool); -static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session); +static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session, mrcp_sig_settings_t *settings); static void mrcp_sofia_event_callback( nua_event_t nua_event, int status, @@ -91,13 +94,13 @@ static void mrcp_sofia_event_callback( nua_event_t nua_event, /** Create Sofia-SIP Signaling Agent */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_client_agent_create(mrcp_sofia_client_config_t *config, apr_pool_t *pool) +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_client_agent_create(const char *id, mrcp_sofia_client_config_t *config, apr_pool_t *pool) { apt_task_t *task; apt_task_vtable_t *vtable; mrcp_sofia_agent_t *sofia_agent; sofia_agent = apr_palloc(pool,sizeof(mrcp_sofia_agent_t)); - sofia_agent->sig_agent = mrcp_signaling_agent_create(sofia_agent,MRCP_VERSION_2,pool); + sofia_agent->sig_agent = mrcp_signaling_agent_create(id,sofia_agent,MRCP_VERSION_2,pool); sofia_agent->sig_agent->create_client_session = mrcp_sofia_session_create; sofia_agent->root = NULL; sofia_agent->nua = NULL; @@ -110,7 +113,7 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_client_agent_create(mrcp_sofia_cli if(!task) { return NULL; } - apt_task_name_set(task,SOFIA_TASK_NAME); + apt_task_name_set(task,id); vtable = apt_task_vtable_get(task); if(vtable) { vtable->on_pre_run = mrcp_sofia_task_initialize; @@ -118,10 +121,8 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_client_agent_create(mrcp_sofia_cli vtable->terminate = mrcp_sofia_task_terminate; } sofia_agent->sig_agent->task = task; - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create "SOFIA_TASK_NAME" ["SOFIA_SIP_VERSION"] %s:%hu -> %s:%hu %s", - config->local_ip,config->local_port, - config->remote_ip,config->remote_port, - config->transport ? config->transport : ""); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create SofiaSIP Agent [%s] ["SOFIA_SIP_VERSION"] %s", + id,sofia_agent->sip_bind_str); return sofia_agent->sig_agent; } @@ -133,48 +134,37 @@ MRCP_DECLARE(mrcp_sofia_client_config_t*) mrcp_sofiasip_client_config_alloc(apr_ config->ext_ip = NULL; config->local_port = 0; config->local_user_name = NULL; - config->remote_ip = NULL; - config->remote_port = 0; - config->remote_user_name = NULL; - - config->force_destination = FALSE; config->user_agent_name = NULL; config->origin = NULL; config->transport = NULL; + + config->sip_t1 = 0; + config->sip_t2 = 0; + config->sip_t4 = 0; + config->sip_t1x64 = 0; return config; } static apt_bool_t mrcp_sofia_config_validate(mrcp_sofia_agent_t *sofia_agent, mrcp_sofia_client_config_t *config, apr_pool_t *pool) { const char *local_ip = config->ext_ip ? config->ext_ip : config->local_ip; - if(!config->local_ip || !config->remote_ip) { + if(!config->local_ip) { return FALSE; } sofia_agent->config = config; - sofia_agent->sip_contact_str = apr_psprintf(pool,"sip:%s:%d", local_ip, config->local_port); - sofia_agent->sip_from_str = apr_psprintf(pool,"sip:%s:%d", local_ip, config->local_port); + sofia_agent->sip_contact_str = apr_psprintf(pool,"sip:%s:%hu", local_ip, config->local_port); + sofia_agent->sip_from_str = apr_psprintf(pool,"sip:%s:%hu", local_ip, config->local_port); - if(config->remote_user_name && config->remote_user_name != '\0') { - sofia_agent->sip_to_str = apr_psprintf(pool,"sip:%s@%s:%d", - config->remote_user_name, - config->remote_ip, - config->remote_port); - } - else { - sofia_agent->sip_to_str = apr_psprintf(pool,"sip:%s:%d", - config->remote_ip, - config->remote_port); - } if(config->transport) { - sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%d;transport=%s", + sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%hu;transport=%s", config->local_ip, config->local_port, config->transport); } else { - sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%d", + sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%hu", config->local_ip, config->local_port); } @@ -184,6 +174,7 @@ static apt_bool_t mrcp_sofia_config_validate(mrcp_sofia_agent_t *sofia_agent, mr static void mrcp_sofia_task_initialize(apt_task_t *task) { mrcp_sofia_agent_t *sofia_agent = apt_task_object_get(task); + mrcp_sofia_client_config_t *sofia_config = sofia_agent->config; /* Initialize Sofia-SIP library and create event loop */ su_init(); @@ -204,7 +195,11 @@ static void mrcp_sofia_task_initialize(apt_task_t *task) sofia_agent->nua, NUTAG_AUTOANSWER(0), NUTAG_APPL_METHOD("OPTIONS"), - SIPTAG_USER_AGENT_STR(sofia_agent->config->user_agent_name), + TAG_IF(sofia_config->sip_t1,NTATAG_SIP_T1(sofia_config->sip_t1)), + TAG_IF(sofia_config->sip_t2,NTATAG_SIP_T2(sofia_config->sip_t2)), + TAG_IF(sofia_config->sip_t4,NTATAG_SIP_T4(sofia_config->sip_t4)), + TAG_IF(sofia_config->sip_t1x64,NTATAG_SIP_T1X64(sofia_config->sip_t1x64)), + SIPTAG_USER_AGENT_STR(sofia_config->user_agent_name), TAG_END()); } } @@ -244,7 +239,7 @@ static APR_INLINE mrcp_sofia_agent_t* mrcp_sofia_agent_get(mrcp_session_t *sessi return session->signaling_agent->obj; } -static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session) +static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session, mrcp_sig_settings_t *settings) { mrcp_sofia_agent_t *sofia_agent = mrcp_sofia_agent_get(session); mrcp_sofia_session_t *sofia_session; @@ -254,15 +249,30 @@ static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session) sofia_session->mutex = NULL; sofia_session->home = su_home_new(sizeof(*sofia_session->home)); sofia_session->session = session; + sofia_session->sip_settings = settings; sofia_session->terminate_requested = FALSE; + sofia_session->descriptor = NULL; session->obj = sofia_session; - + + if(settings->user_name && settings->user_name != '\0') { + sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s@%s:%hu", + settings->user_name, + settings->server_ip, + settings->server_port); + } + else { + sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s:%hu", + settings->server_ip, + settings->server_port); + } + sofia_session->nh = nua_handle( sofia_agent->nua, sofia_session, - SIPTAG_TO_STR(sofia_agent->sip_to_str), + SIPTAG_TO_STR(sofia_session->sip_to_str), SIPTAG_FROM_STR(sofia_agent->sip_from_str), SIPTAG_CONTACT_STR(sofia_agent->sip_contact_str), + TAG_IF(settings->feature_tags,SIPTAG_ACCEPT_CONTACT_STR(settings->feature_tags)), TAG_END()); apr_thread_mutex_create(&sofia_session->mutex,APR_THREAD_MUTEX_DEFAULT,session->pool); @@ -313,8 +323,10 @@ static apt_bool_t mrcp_sofia_session_offer(mrcp_session_t *session, mrcp_session } if(sdp_string_generate_by_mrcp_descriptor(sdp_str,sizeof(sdp_str),descriptor,TRUE) > 0) { local_sdp_str = sdp_str; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Local SDP "APT_PTRSID_FMT"\n%s", - MRCP_SESSION_PTRSID(session), + sofia_session->descriptor = descriptor; + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->log_obj,"Local SDP "APT_NAMESID_FMT"\n%s", + session->name, + MRCP_SESSION_SID(session), local_sdp_str); } @@ -392,14 +404,15 @@ static void mrcp_sofia_on_session_ready( sdp_parser_t *parser = NULL; sdp_session_t *sdp = NULL; const char *force_destination_ip = NULL; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remote SDP "APT_PTRSID_FMT"\n%s", - MRCP_SESSION_PTRSID(session), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->log_obj,"Remote SDP "APT_NAMESID_FMT"\n%s", + session->name, + MRCP_SESSION_SID(session), remote_sdp_str); parser = sdp_parse(sofia_session->home,remote_sdp_str,(int)strlen(remote_sdp_str),0); sdp = sdp_session(parser); - if(sofia_agent && sofia_agent->config->force_destination == TRUE) { - force_destination_ip = sofia_agent->config->remote_ip; + if(sofia_session->sip_settings->force_destination == TRUE) { + force_destination_ip = sofia_session->sip_settings->server_ip; } descriptor = mrcp_descriptor_generate_by_sdp_session(sdp,force_destination_ip,session->pool); sdp_parser_free(parser); @@ -409,6 +422,62 @@ static void mrcp_sofia_on_session_ready( } } +static void mrcp_sofia_on_session_redirect( + int status, + mrcp_sofia_agent_t *sofia_agent, + nua_handle_t *nh, + mrcp_sofia_session_t *sofia_session, + sip_t const *sip, + tagi_t tags[]) +{ + mrcp_session_t *session = sofia_session->session; + sip_contact_t *sip_contact; + if(!sip) { + return; + } + sip_contact = sip->sip_contact; + if(!sip_contact || !sip_contact->m_url) { + return; + } + + if(sip_contact->m_url->url_user && sip_contact->m_url->url_user != '\0') { + sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s@%s:%s", + sip_contact->m_url->url_user, + sip_contact->m_url->url_host, + sip_contact->m_url->url_port); + } + else { + sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s:%s", + sip_contact->m_url->url_host, + sip_contact->m_url->url_port); + } + + apr_thread_mutex_lock(sofia_session->mutex); + + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->log_obj,"Redirect "APT_NAMESID_FMT" to %s", + session->name, + MRCP_SESSION_SID(session), + sofia_session->sip_to_str); + + if(sofia_session->nh) { + nua_handle_bind(sofia_session->nh, NULL); + nua_handle_destroy(sofia_session->nh); + sofia_session->nh = NULL; + } + + sofia_session->nh = nua_handle( + sofia_agent->nua, + sofia_session, + SIPTAG_TO_STR(sofia_session->sip_to_str), + SIPTAG_FROM_STR(sofia_agent->sip_from_str), + SIPTAG_CONTACT_STR(sofia_agent->sip_contact_str), + TAG_END()); + + apr_thread_mutex_unlock(sofia_session->mutex); + + mrcp_sofia_session_offer(sofia_session->session,sofia_session->descriptor); +} + static void mrcp_sofia_on_session_terminate( int status, mrcp_sofia_agent_t *sofia_agent, @@ -450,8 +519,8 @@ static void mrcp_sofia_on_state_change( NUTAG_CALLSTATE_REF(ss_state), TAG_END()); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"SIP Call State "APT_PTR_FMT" [%s]", - sofia_session ? MRCP_SESSION_PTR(sofia_session->session) : NULL, + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"SIP Call State %s [%s]", + sofia_session ? sofia_session->session->name : "", nua_callstate_name(ss_state)); switch(ss_state) { @@ -477,15 +546,15 @@ static void mrcp_sofia_on_resource_discover( const char *remote_sdp_str = NULL; mrcp_session_descriptor_t *descriptor = NULL; - tl_gets(tags, - SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str), - TAG_END()); - + if(sip->sip_payload) { + remote_sdp_str = sip->sip_payload->pl_data; + } + if(remote_sdp_str) { sdp_parser_t *parser = NULL; sdp_session_t *sdp = NULL; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Resource Discovery SDP "APT_PTR_FMT"\n%s", - MRCP_SESSION_PTR(session), + apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->obj,"Resource Discovery SDP %s\n%s", + session->name, remote_sdp_str); parser = sdp_parse(sofia_session->home,remote_sdp_str,(int)strlen(remote_sdp_str),0); @@ -517,6 +586,11 @@ static void mrcp_sofia_event_callback( case nua_i_state: mrcp_sofia_on_state_change(status,sofia_agent,nh,sofia_session,sip,tags); break; + case nua_r_invite: + if(status >= 300 && status < 400) { + mrcp_sofia_on_session_redirect(status,sofia_agent,nh,sofia_session,sip,tags); + } + break; case nua_r_options: mrcp_sofia_on_resource_discover(status,sofia_agent,nh,sofia_session,sip,tags); break; diff --git a/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_server_agent.c b/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_server_agent.c index c5f81a22b5..e094078a24 100644 --- a/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_server_agent.c +++ b/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sofiasip_server_agent.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_sofiasip_server_agent.c 1700 2010-05-21 18:56:06Z achaloyan $ */ typedef struct mrcp_sofia_agent_t mrcp_sofia_agent_t; @@ -35,8 +37,6 @@ typedef struct mrcp_sofia_session_t mrcp_sofia_session_t; #include "mrcp_sdp.h" #include "apt_log.h" -#define SOFIA_TASK_NAME "SofiaSIP Agent" - struct mrcp_sofia_agent_t { mrcp_sig_agent_t *sig_agent; @@ -82,13 +82,13 @@ static void mrcp_sofia_event_callback( nua_event_t nua_event, /** Create Sofia-SIP Signaling Agent */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_server_agent_create(mrcp_sofia_server_config_t *config, apr_pool_t *pool) +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_server_agent_create(const char *id, mrcp_sofia_server_config_t *config, apr_pool_t *pool) { apt_task_t *task; apt_task_vtable_t *vtable; mrcp_sofia_agent_t *sofia_agent; sofia_agent = apr_palloc(pool,sizeof(mrcp_sofia_agent_t)); - sofia_agent->sig_agent = mrcp_signaling_agent_create(sofia_agent,MRCP_VERSION_2,pool); + sofia_agent->sig_agent = mrcp_signaling_agent_create(id,sofia_agent,MRCP_VERSION_2,pool); sofia_agent->config = config; sofia_agent->root = NULL; sofia_agent->nua = NULL; @@ -101,7 +101,7 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_server_agent_create(mrcp_sofia_ser if(!task) { return NULL; } - apt_task_name_set(task,SOFIA_TASK_NAME); + apt_task_name_set(task,id); vtable = apt_task_vtable_get(task); if(vtable) { vtable->on_pre_run = mrcp_sofia_task_initialize; @@ -109,10 +109,8 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_sofiasip_server_agent_create(mrcp_sofia_ser vtable->terminate = mrcp_sofia_task_terminate; } sofia_agent->sig_agent->task = task; - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create "SOFIA_TASK_NAME" ["SOFIA_SIP_VERSION"] %s:%hu %s", - config->local_ip, - config->local_port, - config->transport ? config->transport : ""); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create SofiaSIP Agent [%s] ["SOFIA_SIP_VERSION"] %s", + id,sofia_agent->sip_bind_str); return sofia_agent->sig_agent; } @@ -128,6 +126,10 @@ MRCP_DECLARE(mrcp_sofia_server_config_t*) mrcp_sofiasip_server_config_alloc(apr_ config->origin = NULL; config->transport = NULL; config->force_destination = FALSE; + config->sip_t1 = 0; + config->sip_t2 = 0; + config->sip_t4 = 0; + config->sip_t1x64 = 0; return config; } @@ -135,15 +137,15 @@ static apt_bool_t mrcp_sofia_config_validate(mrcp_sofia_agent_t *sofia_agent, mr { const char *local_ip = config->ext_ip ? config->ext_ip : config->local_ip; sofia_agent->config = config; - sofia_agent->sip_contact_str = apr_psprintf(pool,"sip:%s:%d",local_ip,config->local_port); + sofia_agent->sip_contact_str = apr_psprintf(pool,"sip:%s:%hu",local_ip,config->local_port); if(config->transport) { - sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%d;transport=%s", + sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%hu;transport=%s", config->local_ip, config->local_port, config->transport); } else { - sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%d", + sofia_agent->sip_bind_str = apr_psprintf(pool,"sip:%s:%hu", config->local_ip, config->local_port); } @@ -153,6 +155,7 @@ static apt_bool_t mrcp_sofia_config_validate(mrcp_sofia_agent_t *sofia_agent, mr static void mrcp_sofia_task_initialize(apt_task_t *task) { mrcp_sofia_agent_t *sofia_agent = apt_task_object_get(task); + mrcp_sofia_server_config_t *sofia_config = sofia_agent->config; /* Initialize Sofia-SIP library and create event loop */ su_init(); @@ -173,7 +176,11 @@ static void mrcp_sofia_task_initialize(apt_task_t *task) sofia_agent->nua, NUTAG_AUTOANSWER(0), NUTAG_APPL_METHOD("OPTIONS"), - SIPTAG_USER_AGENT_STR(sofia_agent->config->user_agent_name), + TAG_IF(sofia_config->sip_t1,NTATAG_SIP_T1(sofia_config->sip_t1)), + TAG_IF(sofia_config->sip_t2,NTATAG_SIP_T2(sofia_config->sip_t2)), + TAG_IF(sofia_config->sip_t4,NTATAG_SIP_T4(sofia_config->sip_t4)), + TAG_IF(sofia_config->sip_t1x64,NTATAG_SIP_T1X64(sofia_config->sip_t1x64)), + SIPTAG_USER_AGENT_STR(sofia_config->user_agent_name), TAG_END()); } } @@ -270,7 +277,10 @@ static apt_bool_t mrcp_sofia_on_session_answer(mrcp_session_t *session, mrcp_ses if(sdp_string_generate_by_mrcp_descriptor(sdp_str,sizeof(sdp_str),descriptor,FALSE) > 0) { local_sdp_str = sdp_str; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Local SDP\n%s", local_sdp_str); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Local SDP "APT_NAMESID_FMT"\n%s", + session->name, + MRCP_SESSION_SID(session), + local_sdp_str); } nua_respond(sofia_session->nh, SIP_200_OK, @@ -333,7 +343,10 @@ static void mrcp_sofia_on_call_receive(mrcp_sofia_agent_t *sofia_agent, if(remote_sdp_str) { sdp_parser_t *parser = NULL; sdp_session_t *sdp = NULL; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remote SDP\n%s", remote_sdp_str); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remote SDP "APT_NAMESID_FMT"\n%s", + sofia_session->session->name, + MRCP_SESSION_SID(sofia_session->session), + remote_sdp_str); parser = sdp_parse(sofia_session->home,remote_sdp_str,(int)strlen(remote_sdp_str),0); sdp = sdp_session(parser); @@ -371,7 +384,9 @@ static void mrcp_sofia_on_state_change(mrcp_sofia_agent_t *sofia_agent, NUTAG_CALLSTATE_REF(ss_state), TAG_END()); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"SIP Call State [%s]", nua_callstate_name(ss_state)); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"SIP Call State %s [%s]", + sofia_session ? sofia_session->session->name : "", + nua_callstate_name(ss_state)); switch(ss_state) { case nua_callstate_received: @@ -397,7 +412,8 @@ static void mrcp_sofia_on_resource_discover(mrcp_sofia_agent_t *sofia_agent, if(sdp_resource_discovery_string_generate(ip,sofia_agent->config->origin,sdp_str,sizeof(sdp_str)) > 0) { local_sdp_str = sdp_str; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Resource Discovery SDP\n[%s]\n", local_sdp_str); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Resource Discovery SDP\n[%s]\n", + local_sdp_str); } nua_respond(nh, SIP_200_OK, diff --git a/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_client_agent.h b/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_client_agent.h index fc26929cbe..e455e4476e 100644 --- a/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_client_agent.h +++ b/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_client_agent.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_unirtsp_client_agent.h 1700 2010-05-21 18:56:06Z achaloyan $ */ -#ifndef __MRCP_UNIRTSP_CLIENT_AGENT_H__ -#define __MRCP_UNIRTSP_CLIENT_AGENT_H__ +#ifndef MRCP_UNIRTSP_CLIENT_AGENT_H +#define MRCP_UNIRTSP_CLIENT_AGENT_H /** * @file mrcp_unirtsp_client_agent.h @@ -28,41 +30,30 @@ APT_BEGIN_EXTERN_C -/** UniRTSP config declaration */ +/** Declaration of UniRTSP agent config */ typedef struct rtsp_client_config_t rtsp_client_config_t; -/** UniRTSP config */ +/** Configuration of UniRTSP agent */ struct rtsp_client_config_t { - /** Server IP address */ - char *server_ip; - /** Server port */ - apr_port_t server_port; - /** Resource location */ - char *resource_location; /** SDP origin */ char *origin; - - /** Map of the MRCP resource names */ - apr_table_t *resource_map; - /** Number of max RTSP connections */ apr_size_t max_connection_count; - - /** Force destination ip address. Should be used only in case - SDP contains incorrect connection address (local IP address behind NAT) */ - apt_bool_t force_destination; + /** Request timeout */ + apr_size_t request_timeout; }; /** * Create UniRTSP signaling agent. */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_client_agent_create(rtsp_client_config_t *config, apr_pool_t *pool); +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_client_agent_create(const char *id, rtsp_client_config_t *config, apr_pool_t *pool); /** * Allocate UniRTSP config. */ MRCP_DECLARE(rtsp_client_config_t*) mrcp_unirtsp_client_config_alloc(apr_pool_t *pool); + APT_END_EXTERN_C -#endif /*__MRCP_UNIRTSP_CLIENT_AGENT_H__*/ +#endif /* MRCP_UNIRTSP_CLIENT_AGENT_H */ diff --git a/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_sdp.h b/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_sdp.h index 58d35347d0..74de717a48 100644 --- a/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_sdp.h +++ b/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_sdp.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_unirtsp_sdp.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __MRCP_UNIRTSP_SDP_H__ -#define __MRCP_UNIRTSP_SDP_H__ +#ifndef MRCP_UNIRTSP_SDP_H +#define MRCP_UNIRTSP_SDP_H /** * @file mrcp_unirtsp_sdp.h @@ -84,4 +86,4 @@ MRCP_DECLARE(const char*) rtsp_name_get_by_mrcp_name(const apr_table_t *resource APT_END_EXTERN_C -#endif /*__MRCP_UNIRTSP_SDP_H__*/ +#endif /* MRCP_UNIRTSP_SDP_H */ diff --git a/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_server_agent.h b/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_server_agent.h index e117f2a672..e93f692c5b 100644 --- a/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_server_agent.h +++ b/libs/unimrcp/modules/mrcp-unirtsp/include/mrcp_unirtsp_server_agent.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_unirtsp_server_agent.h 1700 2010-05-21 18:56:06Z achaloyan $ */ -#ifndef __MRCP_UNIRTSP_SERVER_AGENT_H__ -#define __MRCP_UNIRTSP_SERVER_AGENT_H__ +#ifndef MRCP_UNIRTSP_SERVER_AGENT_H +#define MRCP_UNIRTSP_SERVER_AGENT_H /** * @file mrcp_unirtsp_server_agent.h @@ -56,7 +58,7 @@ struct rtsp_server_config_t { /** * Create UniRTSP signaling agent. */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_server_agent_create(rtsp_server_config_t *config, apr_pool_t *pool); +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_server_agent_create(const char *id, rtsp_server_config_t *config, apr_pool_t *pool); /** * Allocate UniRTSP config. @@ -65,4 +67,4 @@ MRCP_DECLARE(rtsp_server_config_t*) mrcp_unirtsp_server_config_alloc(apr_pool_t APT_END_EXTERN_C -#endif /*__MRCP_UNIRTSP_SERVER_AGENT_H__*/ +#endif /* MRCP_UNIRTSP_SERVER_AGENT_H */ diff --git a/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2008.vcproj b/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2008.vcproj deleted file mode 100644 index d0d90c646d..0000000000 --- a/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2008.vcproj +++ /dev/null @@ -1,293 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2010.vcxproj b/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2010.vcxproj deleted file mode 100644 index f8a573d857..0000000000 --- a/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2010.vcxproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - mrcpunirtsp - {DEB01ACB-D65F-4A62-AED9-58C1054499E9} - mrcpunirtsp - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - $(PlatformName)\$(Configuration)\ - - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;RTSP_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - - - - - X64 - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;RTSP_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - ProgramDatabase - - - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;RTSP_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - - - - - X64 - - - include;%(AdditionalIncludeDirectories) - APT_STATIC_LIB;RTSP_STATIC_LIB;MPF_STATIC_LIB;MRCP_STATIC_LIB;LIBSOFIA_SIP_UA_STATIC;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2010.vcxproj.filters b/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2010.vcxproj.filters deleted file mode 100644 index a990550f29..0000000000 --- a/libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2010.vcxproj.filters +++ /dev/null @@ -1,35 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {f87f8ada-12d1-412b-bd14-7e62df3f92a0} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - include - - - include - - - include - - - - - src - - - src - - - src - - - \ No newline at end of file diff --git a/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_client_agent.c b/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_client_agent.c index 0b0840b1d7..6997c47004 100644 --- a/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_client_agent.c +++ b/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_client_agent.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_unirtsp_client_agent.c 1700 2010-05-21 18:56:06Z achaloyan $ */ #include @@ -28,7 +30,6 @@ #include "apt_consumer_task.h" #include "apt_log.h" -#define UNIRTSP_TASK_NAME "UniRTSP Agent" typedef struct mrcp_unirtsp_agent_t mrcp_unirtsp_agent_t; typedef struct mrcp_unirtsp_session_t mrcp_unirtsp_session_t; @@ -41,10 +42,11 @@ struct mrcp_unirtsp_agent_t { }; struct mrcp_unirtsp_session_t { - mrcp_message_t *mrcp_message; - mrcp_session_t *mrcp_session; - rtsp_client_session_t *rtsp_session; - su_home_t *home; + mrcp_message_t *mrcp_message; + mrcp_session_t *mrcp_session; + rtsp_client_session_t *rtsp_session; + mrcp_sig_settings_t *rtsp_settings; + su_home_t *home; }; @@ -72,18 +74,18 @@ static const rtsp_client_vtable_t session_response_vtable = { mrcp_unirtsp_on_session_event }; -static apt_bool_t mrcp_unirtsp_session_create(mrcp_session_t *session); +static apt_bool_t mrcp_unirtsp_session_create(mrcp_session_t *session, mrcp_sig_settings_t *settings); static apt_bool_t rtsp_config_validate(mrcp_unirtsp_agent_t *agent, rtsp_client_config_t *config, apr_pool_t *pool); static apt_bool_t mrcp_unirtsp_on_resource_discover(mrcp_unirtsp_agent_t *agent, mrcp_unirtsp_session_t *session, rtsp_message_t *request, rtsp_message_t *response); /** Create UniRTSP Signaling Agent */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_client_agent_create(rtsp_client_config_t *config, apr_pool_t *pool) +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_client_agent_create(const char *id, rtsp_client_config_t *config, apr_pool_t *pool) { apt_task_t *task; mrcp_unirtsp_agent_t *agent; agent = apr_palloc(pool,sizeof(mrcp_unirtsp_agent_t)); - agent->sig_agent = mrcp_signaling_agent_create(agent,MRCP_VERSION_1,pool); + agent->sig_agent = mrcp_signaling_agent_create(id,agent,MRCP_VERSION_1,pool); agent->sig_agent->create_client_session = mrcp_unirtsp_session_create; agent->config = config; @@ -91,20 +93,22 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_client_agent_create(rtsp_client_con return NULL; } - agent->rtsp_client = rtsp_client_create(config->max_connection_count, - agent,&session_response_vtable,pool); + agent->rtsp_client = rtsp_client_create( + config->max_connection_count, + config->request_timeout, + agent, + &session_response_vtable, + pool); if(!agent->rtsp_client) { return NULL; } task = rtsp_client_task_get(agent->rtsp_client); - apt_task_name_set(task,UNIRTSP_TASK_NAME); + apt_task_name_set(task,id); agent->sig_agent->task = task; - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create "UNIRTSP_TASK_NAME" %s:%hu [%"APR_SIZE_T_FMT"]", - config->server_ip, - config->server_port, - config->max_connection_count); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create UniRTSP Agent [%s] [%"APR_SIZE_T_FMT"]", + id,config->max_connection_count); return agent->sig_agent; } @@ -112,22 +116,14 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_client_agent_create(rtsp_client_con MRCP_DECLARE(rtsp_client_config_t*) mrcp_unirtsp_client_config_alloc(apr_pool_t *pool) { rtsp_client_config_t *config = apr_palloc(pool,sizeof(rtsp_client_config_t)); - config->server_ip = NULL; - config->server_port = 0; - config->resource_location = NULL; config->origin = NULL; - config->resource_map = apr_table_make(pool,2); config->max_connection_count = 100; - config->force_destination = FALSE; + config->request_timeout = 0; return config; } - static apt_bool_t rtsp_config_validate(mrcp_unirtsp_agent_t *agent, rtsp_client_config_t *config, apr_pool_t *pool) { - if(!config->server_ip) { - return FALSE; - } agent->config = config; return TRUE; } @@ -139,7 +135,7 @@ static APR_INLINE mrcp_unirtsp_agent_t* client_agent_get(apt_task_t *task) return agent; } -static apt_bool_t mrcp_unirtsp_session_create(mrcp_session_t *mrcp_session) +static apt_bool_t mrcp_unirtsp_session_create(mrcp_session_t *mrcp_session, mrcp_sig_settings_t *settings) { mrcp_unirtsp_agent_t *agent = mrcp_session->signaling_agent->obj; mrcp_unirtsp_session_t *session; @@ -147,15 +143,16 @@ static apt_bool_t mrcp_unirtsp_session_create(mrcp_session_t *mrcp_session) session = apr_palloc(mrcp_session->pool,sizeof(mrcp_unirtsp_session_t)); session->home = su_home_new(sizeof(*session->home)); + session->rtsp_settings = settings; session->mrcp_message = NULL; session->mrcp_session = mrcp_session; mrcp_session->obj = session; session->rtsp_session = rtsp_client_session_create( agent->rtsp_client, - agent->config->server_ip, - agent->config->server_port, - agent->config->resource_location); + session->rtsp_settings->server_ip, + session->rtsp_settings->server_port, + session->rtsp_settings->resource_location); if(!session->rtsp_session) { su_home_unref(session->home); return FALSE; @@ -198,9 +195,9 @@ static apt_bool_t mrcp_unirtsp_on_announce_response(mrcp_unirtsp_agent_t *agent, return FALSE; } - if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && + if(rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && message->header.content_type == RTSP_CONTENT_TYPE_MRCP && - rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && + rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && message->header.content_length > 0) { apt_text_stream_t text_stream; @@ -212,9 +209,8 @@ static apt_bool_t mrcp_unirtsp_on_announce_response(mrcp_unirtsp_agent_t *agent, apt_string_set(&resource_name_str,resource_name); parser = mrcp_parser_create(agent->sig_agent->resource_factory,session->mrcp_session->pool); - mrcp_parser_resource_name_set(parser,&resource_name_str); - if(mrcp_parser_run(parser,&text_stream) == MRCP_STREAM_STATUS_COMPLETE) { - mrcp_message = mrcp_parser_message_get(parser); + mrcp_parser_resource_set(parser,&resource_name_str); + if(mrcp_parser_run(parser,&text_stream,&mrcp_message) == APT_MESSAGE_STATUS_COMPLETE) { mrcp_message->channel_id.session_id = message->header.session_id; } else { @@ -255,15 +251,15 @@ static apt_bool_t mrcp_unirtsp_on_session_response(rtsp_client_t *rtsp_client, r const char *force_destination_ip = NULL; mrcp_session_descriptor_t *descriptor; - if(agent->config->force_destination == TRUE) { - force_destination_ip = agent->config->server_ip; + if(session->rtsp_settings->force_destination == TRUE) { + force_destination_ip = session->rtsp_settings->server_ip; } descriptor = mrcp_descriptor_generate_by_rtsp_response( request, response, force_destination_ip, - agent->config->resource_map, + session->rtsp_settings->resource_map, session->mrcp_session->pool, session->home); if(!descriptor) { @@ -286,7 +282,7 @@ static apt_bool_t mrcp_unirtsp_on_session_response(rtsp_client_t *rtsp_client, r request, response, NULL, - agent->config->resource_map, + session->rtsp_settings->resource_map, session->mrcp_session->pool, session->home); if(!descriptor) { @@ -299,7 +295,7 @@ static apt_bool_t mrcp_unirtsp_on_session_response(rtsp_client_t *rtsp_client, r { mrcp_unirtsp_agent_t *agent = rtsp_client_object_get(rtsp_client); const char *resource_name = mrcp_name_get_by_rtsp_name( - agent->config->resource_map, + session->rtsp_settings->resource_map, request->start_line.common.request_line.resource_name); mrcp_unirtsp_on_announce_response(agent,session,response,resource_name); break; @@ -322,7 +318,7 @@ static apt_bool_t mrcp_unirtsp_on_session_event(rtsp_client_t *rtsp_client, rtsp mrcp_unirtsp_agent_t *agent = rtsp_client_object_get(rtsp_client); mrcp_unirtsp_session_t *session = rtsp_client_session_object_get(rtsp_session); const char *resource_name = mrcp_name_get_by_rtsp_name( - agent->config->resource_map, + session->rtsp_settings->resource_map, message->start_line.common.request_line.resource_name); if(!session || !resource_name) { return FALSE; @@ -342,7 +338,7 @@ static apt_bool_t mrcp_unirtsp_session_offer(mrcp_session_t *mrcp_session, mrcp_ apt_string_set(&descriptor->origin,agent->config->origin); } - request = rtsp_request_generate_by_mrcp_descriptor(descriptor,agent->config->resource_map,mrcp_session->pool); + request = rtsp_request_generate_by_mrcp_descriptor(descriptor,session->rtsp_settings->resource_map,mrcp_session->pool); return rtsp_client_session_request(agent->rtsp_client,session->rtsp_session,request); } @@ -375,7 +371,7 @@ static apt_bool_t mrcp_unirtsp_session_control(mrcp_session_t *mrcp_session, mrc rtsp_message = rtsp_request_create(mrcp_session->pool); rtsp_message->start_line.common.request_line.resource_name = rtsp_name_get_by_mrcp_name( - agent->config->resource_map, + session->rtsp_settings->resource_map, mrcp_message->channel_id.resource_name.buf); rtsp_message->start_line.common.request_line.method_id = RTSP_METHOD_ANNOUNCE; @@ -389,9 +385,9 @@ static apt_bool_t mrcp_unirtsp_session_control(mrcp_session_t *mrcp_session, mrc body->buf[body->length] = '\0'; rtsp_message->header.content_type = RTSP_CONTENT_TYPE_MRCP; - rtsp_header_property_add(&rtsp_message->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE); + rtsp_header_property_add(&rtsp_message->header,RTSP_HEADER_FIELD_CONTENT_TYPE,rtsp_message->pool); rtsp_message->header.content_length = body->length; - rtsp_header_property_add(&rtsp_message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH); + rtsp_header_property_add(&rtsp_message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH,rtsp_message->pool); session->mrcp_message = mrcp_message; rtsp_client_session_request(agent->rtsp_client,session->rtsp_session,rtsp_message); @@ -409,7 +405,7 @@ static apt_bool_t mrcp_unirtsp_resource_discover(mrcp_session_t *mrcp_session, m } request = rtsp_resource_discovery_request_generate( descriptor->resource_name.buf, - agent->config->resource_map, + session->rtsp_settings->resource_map, mrcp_session->pool); if(request) { rtsp_client_session_request(agent->rtsp_client,session->rtsp_session,request); @@ -427,7 +423,7 @@ static apt_bool_t mrcp_unirtsp_on_resource_discover(mrcp_unirtsp_agent_t *agent, descriptor = mrcp_resource_discovery_response_generate( request, response, - agent->config->resource_map, + session->rtsp_settings->resource_map, session->mrcp_session->pool, session->home); if(descriptor) { diff --git a/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_sdp.c b/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_sdp.c index e35055fdc9..ebb31fa007 100644 --- a/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_sdp.c +++ b/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_sdp.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_unirtsp_sdp.c 1752 2010-08-09 19:05:23Z achaloyan $ */ #include @@ -190,8 +192,8 @@ MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_descriptor_generate_by_rtsp_reques } if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) { - if(rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && - rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && + if(rtsp_header_property_check(&request->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && + rtsp_header_property_check(&request->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && request->body.buf) { sdp_parser_t *parser; @@ -216,7 +218,7 @@ MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_descriptor_generate_by_rtsp_reques mpf_rtp_media_descriptor_init(media); media->state = MPF_MEDIA_ENABLED; media->id = mrcp_session_audio_media_add(descriptor,media); - if(rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_TRANSPORT) == TRUE) { + if(rtsp_header_property_check(&request->header,RTSP_HEADER_FIELD_TRANSPORT) == TRUE) { media->port = request->header.transport.client_port_range.min; media->ip = request->header.transport.destination; } @@ -253,8 +255,8 @@ MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_descriptor_generate_by_rtsp_respon } if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) { - if(rtsp_header_property_check(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && - rtsp_header_property_check(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && + if(rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && + rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && response->body.buf) { sdp_parser_t *parser; @@ -348,14 +350,14 @@ MRCP_DECLARE(rtsp_message_t*) rtsp_request_generate_by_mrcp_descriptor(const mrc request->header.transport.protocol = RTSP_TRANSPORT_RTP; request->header.transport.profile = RTSP_PROFILE_AVP; request->header.transport.delivery = RTSP_DELIVERY_UNICAST; - rtsp_header_property_add(&request->header.property_set,RTSP_HEADER_FIELD_TRANSPORT); + rtsp_header_property_add(&request->header,RTSP_HEADER_FIELD_TRANSPORT,request->pool); if(offset) { apt_string_assign_n(&request->body,buffer,offset,pool); request->header.content_type = RTSP_CONTENT_TYPE_SDP; - rtsp_header_property_add(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE); + rtsp_header_property_add(&request->header,RTSP_HEADER_FIELD_CONTENT_TYPE,request->pool); request->header.content_length = offset; - rtsp_header_property_add(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH); + rtsp_header_property_add(&request->header,RTSP_HEADER_FIELD_CONTENT_LENGTH,request->pool); } return request; } @@ -434,14 +436,14 @@ MRCP_DECLARE(rtsp_message_t*) rtsp_response_generate_by_mrcp_descriptor(const rt response->header.transport.protocol = RTSP_TRANSPORT_RTP; response->header.transport.profile = RTSP_PROFILE_AVP; response->header.transport.delivery = RTSP_DELIVERY_UNICAST; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_TRANSPORT); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_TRANSPORT,response->pool); if(offset) { apt_string_assign_n(&response->body,buffer,offset,pool); response->header.content_type = RTSP_CONTENT_TYPE_SDP; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_CONTENT_TYPE,response->pool); response->header.content_length = offset; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_CONTENT_LENGTH,response->pool); } } return response; @@ -481,8 +483,8 @@ MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_resource_discovery_response_genera descriptor = mrcp_session_descriptor_create(pool); apt_string_assign(&descriptor->resource_name,resource_name,pool); - if(rtsp_header_property_check(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && - rtsp_header_property_check(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && + if(rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && + rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && response->body.buf) { sdp_parser_t *parser; @@ -546,9 +548,9 @@ MRCP_DECLARE(rtsp_message_t*) rtsp_resource_discovery_response_generate( if(offset) { apt_string_assign_n(&response->body,buffer,offset,pool); response->header.content_type = RTSP_CONTENT_TYPE_SDP; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_CONTENT_TYPE,response->pool); response->header.content_length = offset; - rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH); + rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_CONTENT_LENGTH,response->pool); } } @@ -558,18 +560,20 @@ MRCP_DECLARE(rtsp_message_t*) rtsp_resource_discovery_response_generate( /** Get MRCP resource name by RTSP resource name */ MRCP_DECLARE(const char*) mrcp_name_get_by_rtsp_name(const apr_table_t *resource_map, const char *rtsp_name) { - const apr_array_header_t *header = apr_table_elts(resource_map); - apr_table_entry_t *entry = (apr_table_entry_t *)header->elts; - int i; - - for(i=0; inelts; i++) { - if(entry[i].val && rtsp_name) { - if(apr_strnatcasecmp(entry[i].val,rtsp_name) == 0) { + if(rtsp_name) { + const apr_array_header_t *header = apr_table_elts(resource_map); + apr_table_entry_t *entry = (apr_table_entry_t *)header->elts; + int i; + for(i=0; inelts; i++) { + if(!entry[i].val) continue; + + if(strcasecmp(entry[i].val,rtsp_name) == 0) { return entry[i].key; } } + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown RTSP Resource Name [%s]", rtsp_name); } - return rtsp_name; + return "unknown"; } /** Get RTSP resource name by MRCP resource name */ diff --git a/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_server_agent.c b/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_server_agent.c index 1ef05e193e..873b3d216d 100644 --- a/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_server_agent.c +++ b/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_server_agent.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_unirtsp_server_agent.c 1700 2010-05-21 18:56:06Z achaloyan $ */ #include @@ -28,8 +30,6 @@ #include "apt_consumer_task.h" #include "apt_log.h" -#define UNIRTSP_TASK_NAME "UniRTSP Agent" - typedef struct mrcp_unirtsp_agent_t mrcp_unirtsp_agent_t; typedef struct mrcp_unirtsp_session_t mrcp_unirtsp_session_t; @@ -72,12 +72,12 @@ static apt_bool_t rtsp_config_validate(mrcp_unirtsp_agent_t *agent, rtsp_server_ /** Create UniRTSP Signaling Agent */ -MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_server_agent_create(rtsp_server_config_t *config, apr_pool_t *pool) +MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_server_agent_create(const char *id, rtsp_server_config_t *config, apr_pool_t *pool) { apt_task_t *task; mrcp_unirtsp_agent_t *agent; agent = apr_palloc(pool,sizeof(mrcp_unirtsp_agent_t)); - agent->sig_agent = mrcp_signaling_agent_create(agent,MRCP_VERSION_1,pool); + agent->sig_agent = mrcp_signaling_agent_create(id,agent,MRCP_VERSION_1,pool); agent->config = config; if(rtsp_config_validate(agent,config,pool) == FALSE) { @@ -96,13 +96,14 @@ MRCP_DECLARE(mrcp_sig_agent_t*) mrcp_unirtsp_server_agent_create(rtsp_server_con } task = rtsp_server_task_get(agent->rtsp_server); - apt_task_name_set(task,UNIRTSP_TASK_NAME); + apt_task_name_set(task,id); agent->sig_agent->task = task; - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create "UNIRTSP_TASK_NAME" %s:%hu [%"APR_SIZE_T_FMT"]", - config->local_ip, - config->local_port, - config->max_connection_count); + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create UniRTSP Agent [%s] %s:%hu [%"APR_SIZE_T_FMT"]", + id, + config->local_ip, + config->local_port, + config->max_connection_count); return agent->sig_agent; } @@ -192,23 +193,23 @@ static apt_bool_t mrcp_unirtsp_session_announce(mrcp_unirtsp_agent_t *agent, mrc apt_bool_t status = TRUE; if(session && resource_name && - rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && + rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE && message->header.content_type == RTSP_CONTENT_TYPE_MRCP && - rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && + rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE && message->header.content_length > 0) { apt_text_stream_t text_stream; mrcp_parser_t *parser; apt_str_t resource_name_str; + mrcp_message_t *mrcp_message; text_stream.text = message->body; apt_text_stream_reset(&text_stream); apt_string_set(&resource_name_str,resource_name); parser = mrcp_parser_create(agent->sig_agent->resource_factory,session->mrcp_session->pool); - mrcp_parser_resource_name_set(parser,&resource_name_str); - if(mrcp_parser_run(parser,&text_stream) == MRCP_STREAM_STATUS_COMPLETE) { - mrcp_message_t *mrcp_message = mrcp_parser_message_get(parser); + mrcp_parser_resource_set(parser,&resource_name_str); + if(mrcp_parser_run(parser,&text_stream,&mrcp_message) == APT_MESSAGE_STATUS_COMPLETE) { mrcp_message->channel_id.session_id = message->header.session_id; status = mrcp_session_control_request(session->mrcp_session,mrcp_message); } @@ -375,9 +376,9 @@ static apt_bool_t mrcp_unirtsp_on_session_control(mrcp_session_t *mrcp_session, body->buf[body->length] = '\0'; rtsp_message->header.content_type = RTSP_CONTENT_TYPE_MRCP; - rtsp_header_property_add(&rtsp_message->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE); + rtsp_header_property_add(&rtsp_message->header,RTSP_HEADER_FIELD_CONTENT_TYPE,rtsp_message->pool); rtsp_message->header.content_length = body->length; - rtsp_header_property_add(&rtsp_message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH); + rtsp_header_property_add(&rtsp_message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH,rtsp_message->pool); rtsp_server_session_respond(agent->rtsp_server,session->rtsp_session,rtsp_message); return TRUE; diff --git a/libs/unimrcp/packages/inno-setup/setup.iss b/libs/unimrcp/packages/inno-setup/setup.iss deleted file mode 100644 index 98677b46c9..0000000000 --- a/libs/unimrcp/packages/inno-setup/setup.iss +++ /dev/null @@ -1,14 +0,0 @@ -#define uni_version "0.8.0" - -AppName=UniMRCP -AppVerName=UniMRCP-{#= uni_version} -AppPublisher=UniMRCP -AppPublisherURL=http://www.unimrcp.org/ -AppSupportURL=http://groups.google.com/group/unimrcp -AppUpdatesURL=http://code.google.com/p/unimrcp/downloads/list -DefaultDirName={pf}\UniMRCP -DefaultGroupName=UniMRCP -Compression=lzma -InternalCompressLevel=max -SolidCompression=true - diff --git a/libs/unimrcp/packages/inno-setup/setup.txt b/libs/unimrcp/packages/inno-setup/setup.txt index 6dd7582ded..45d6489f83 100644 --- a/libs/unimrcp/packages/inno-setup/setup.txt +++ b/libs/unimrcp/packages/inno-setup/setup.txt @@ -1,4 +1,4 @@ -#define uni_version "0.9.0" +#define uni_version "1.0.0" #define uni_src "..\.." AppName=UniMRCP diff --git a/libs/unimrcp/packages/inno-setup/unimrcp.iss b/libs/unimrcp/packages/inno-setup/unimrcp.iss index 0f17729874..9e65059430 100644 --- a/libs/unimrcp/packages/inno-setup/unimrcp.iss +++ b/libs/unimrcp/packages/inno-setup/unimrcp.iss @@ -31,6 +31,7 @@ Source: {#= uni_outdir}\plugin\demosynth.dll; DestDir: {app}\plugin; Components: Source: {#= uni_outdir}\plugin\demorecog.dll; DestDir: {app}\plugin; Components: server/demorecog Source: {#= uni_outdir}\conf\unimrcpserver.xml; DestDir: {app}\conf; Components: server Source: {#= uni_outdir}\conf\unimrcpclient.xml; DestDir: {app}\conf; Components: client +Source: {#= uni_outdir}\conf\client-profiles\*.xml; DestDir: {app}\conf\client-profiles; Components: client Source: {#= uni_outdir}\conf\umcscenarios.xml; DestDir: {app}\conf; Components: client Source: {#= uni_outdir}\data\*.pcm; DestDir: {app}\data; Components: server client Source: {#= uni_outdir}\data\*.xml; DestDir: {app}\data; Components: server client diff --git a/libs/unimrcp/platforms/asr-client/src/main.c b/libs/unimrcp/platforms/asr-client/src/main.c index 0861bf4200..8a3a1d06de 100644 --- a/libs/unimrcp/platforms/asr-client/src/main.c +++ b/libs/unimrcp/platforms/asr-client/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: main.c 1541 2010-02-22 20:20:10Z achaloyan $ */ #include @@ -44,7 +46,7 @@ static void* APR_THREAD_FUNC asr_session_run(apr_thread_t *thread, void *data) asr_params_t *params = data; asr_session_t *session = asr_session_create(params->engine,params->profile); if(session) { - const char *result = asr_session_recognize(session,params->grammar_file,params->input_file); + const char *result = asr_session_file_recognize(session,params->grammar_file,params->input_file); if(result) { printf("Recog Result [%s]",result); } @@ -87,7 +89,7 @@ static apt_bool_t asr_session_launch(asr_engine_t *engine, const char *grammar_f params->profile = apr_pstrdup(pool,profile); } else { - params->profile = "MRCPv2-Default"; + params->profile = "uni2"; } /* Launch a thread to run demo ASR session in */ @@ -126,11 +128,11 @@ static apt_bool_t cmdline_process(asr_engine_t *engine, char *cmdline) "\n- run [grammar_file] [audio_input_file] [profile_name] (run demo asr client)\n" " grammar_file is the name of grammar file, (path is relative to data dir)\n" " audio_input_file is the name of audio file, (path is relative to data dir)\n" - " profile_name is one of 'MRCPv2-Default', 'MRCPv1-Default', ...\n" + " profile_name is one of 'uni2', 'uni1', ...\n" "\n examples: \n" " run\n" " run grammar.xml one.pcm\n" - " run grammar.xml one.pcm MRCPv1-Default\n" + " run grammar.xml one.pcm uni1\n" "\n- loglevel [level] (set loglevel, one of 0,1...7)\n" "\n- quit, exit\n"); } diff --git a/libs/unimrcp/platforms/libasr-client/include/asr_engine.h b/libs/unimrcp/platforms/libasr-client/include/asr_engine.h index 6a9e62fbe5..065e7f83f9 100644 --- a/libs/unimrcp/platforms/libasr-client/include/asr_engine.h +++ b/libs/unimrcp/platforms/libasr-client/include/asr_engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2009 Arsen Chaloyan + * Copyright 2009-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: asr_engine.h 1566 2010-03-06 16:45:05Z achaloyan $ */ -#ifndef __ASR_ENGINE_H__ -#define __ASR_ENGINE_H__ +#ifndef ASR_ENGINE_H +#define ASR_ENGINE_H /** * @file asr_engine.h @@ -75,13 +77,42 @@ ASR_CLIENT_DECLARE(apt_bool_t) asr_engine_destroy(asr_engine_t *engine); ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, const char *profile); /** - * Initiate recognition. + * Initiate recognition based on specified grammar and input file. * @param session the session to run recognition in the scope of * @param grammar_file the name of the grammar file to use (path is relative to data dir) * @param input_file the name of the audio input file to use (path is relative to data dir) * @return the recognition result (input element of NLSML content) */ -ASR_CLIENT_DECLARE(const char*) asr_session_recognize(asr_session_t *session, const char *grammar_file, const char *input_file); +ASR_CLIENT_DECLARE(const char*) asr_session_file_recognize( + asr_session_t *session, + const char *grammar_file, + const char *input_file); + +/** + * Initiate recognition based on specified grammar and input stream. + * @param session the session to run recognition in the scope of + * @param grammar_file the name of the grammar file to use (path is relative to data dir) + * @param callback the callback to be called to get input media frames + * @param obj the object to pass to the callback + * @return the recognition result (input element of NLSML content) + * + * @remark Audio data should be streamed through + * asr_session_stream_write() function calls. + */ +ASR_CLIENT_DECLARE(const char*) asr_session_stream_recognize( + asr_session_t *session, + const char *grammar_file); + +/** + * Write audio data to recognize. + * @param session the session to write audio data for + * @param data the audio data + * @param size the size of data + */ +ASR_CLIENT_DECLARE(apt_bool_t) asr_session_stream_write( + asr_session_t *session, + char *data, + int size); /** * Destroy ASR session. @@ -99,4 +130,4 @@ ASR_CLIENT_DECLARE(apt_bool_t) asr_engine_log_priority_set(apt_log_priority_e lo APT_END_EXTERN_C -#endif /*__ASR_ENGINE_H__*/ +#endif /* ASR_ENGINE_H */ diff --git a/libs/unimrcp/platforms/libasr-client/src/asr_engine.c b/libs/unimrcp/platforms/libasr-client/src/asr_engine.c index 0879f4fe98..4048347a05 100644 --- a/libs/unimrcp/platforms/libasr-client/src/asr_engine.c +++ b/libs/unimrcp/platforms/libasr-client/src/asr_engine.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Arsen Chaloyan + * Copyright 2009-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: asr_engine.c 1785 2010-09-22 06:14:29Z achaloyan $ */ #include @@ -20,14 +22,16 @@ #include #include -/* common includes */ +/* Common includes */ #include "unimrcp_client.h" #include "mrcp_application.h" #include "mrcp_message.h" #include "mrcp_generic_header.h" -/* recognizer includes */ +/* Recognizer includes */ #include "mrcp_recog_header.h" #include "mrcp_recog_resource.h" +/* MPF includes */ +#include /* APT includes */ #include "apt_nlsml_doc.h" #include "apt_log.h" @@ -35,6 +39,11 @@ #include "asr_engine.h" +typedef enum { + INPUT_MODE_NONE, + INPUT_MODE_FILE, + INPUT_MODE_STREAM +} input_mode_e; /** ASR engine on top of UniMRCP client stack */ struct asr_engine_t { @@ -50,23 +59,27 @@ struct asr_engine_t { /** ASR session on top of UniMRCP session/channel */ struct asr_session_t { /** Back pointer to engine */ - asr_engine_t *engine; + asr_engine_t *engine; /** MRCP session */ - mrcp_session_t *mrcp_session; + mrcp_session_t *mrcp_session; /** MRCP channel */ - mrcp_channel_t *mrcp_channel; + mrcp_channel_t *mrcp_channel; /** RECOGNITION-COMPLETE message */ - mrcp_message_t *recog_complete; - - /** File to read audio stream from */ - FILE *audio_in; + mrcp_message_t *recog_complete; + + /** Input mode (either file or stream) */ + input_mode_e input_mode; + /** File to read media frames from */ + FILE *audio_in; + /* Buffer of media frames */ + mpf_frame_buffer_t *media_buffer; /** Streaming is in-progress */ - apt_bool_t streaming; + apt_bool_t streaming; /** Conditional wait object */ - apr_thread_cond_t *wait_object; + apr_thread_cond_t *wait_object; /** Mutex of the wait object */ - apr_thread_mutex_t *mutex; + apr_thread_mutex_t *mutex; /** Message sent from client stack */ const mrcp_app_message_t *app_message; @@ -114,7 +127,7 @@ ASR_CLIENT_DECLARE(asr_engine_t*) asr_engine_create( if((log_output & APT_LOG_OUTPUT_FILE) == APT_LOG_OUTPUT_FILE) { /* open the log file */ - apt_log_file_open(dir_layout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,pool); + apt_log_file_open(dir_layout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,FALSE,pool); } engine = apr_palloc(pool,sizeof(asr_engine_t)); @@ -204,12 +217,12 @@ static apt_bool_t asr_session_destroy_ex(asr_session_t *asr_session, apt_bool_t apr_thread_cond_destroy(asr_session->wait_object); asr_session->wait_object = NULL; } - if(asr_session->mrcp_session) { - mrcp_application_session_destroy(asr_session->mrcp_session); - asr_session->mrcp_session = NULL; + if(asr_session->media_buffer) { + mpf_frame_buffer_destroy(asr_session->media_buffer); + asr_session->media_buffer = NULL; } - free(asr_session); - return TRUE; + + return mrcp_application_session_destroy(asr_session->mrcp_session); } /** Open audio input file */ @@ -241,14 +254,21 @@ static apt_bool_t asr_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame { asr_session_t *asr_session = stream->obj; if(asr_session && asr_session->streaming == TRUE) { - if(asr_session->audio_in) { - if(fread(frame->codec_frame.buffer,1,frame->codec_frame.size,asr_session->audio_in) == frame->codec_frame.size) { - /* normal read */ - frame->type |= MEDIA_FRAME_TYPE_AUDIO; + if(asr_session->input_mode == INPUT_MODE_FILE) { + if(asr_session->audio_in) { + if(fread(frame->codec_frame.buffer,1,frame->codec_frame.size,asr_session->audio_in) == frame->codec_frame.size) { + /* normal read */ + frame->type |= MEDIA_FRAME_TYPE_AUDIO; + } + else { + /* file is over */ + asr_session->streaming = FALSE; + } } - else { - /* file is over */ - asr_session->streaming = FALSE; + } + if(asr_session->input_mode == INPUT_MODE_STREAM) { + if(asr_session->media_buffer) { + mpf_frame_buffer_read(asr_session->media_buffer,frame); } } } @@ -415,6 +435,11 @@ static apt_bool_t mrcp_response_check(const mrcp_app_message_t *app_message, mrc if(!mrcp_message || mrcp_message->start_line.message_type != MRCP_MESSAGE_TYPE_RESPONSE ) { return FALSE; } + + if(mrcp_message->start_line.status_code != MRCP_STATUS_CODE_SUCCESS && + mrcp_message->start_line.status_code != MRCP_STATUS_CODE_SUCCESS_WITH_IGNORE) { + return FALSE; + } return (mrcp_message->start_line.request_state == state) ? TRUE : FALSE; } @@ -440,23 +465,33 @@ ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, cons mrcp_session_t *session; const mrcp_app_message_t *app_message; apr_pool_t *pool; - - asr_session_t *asr_session = malloc(sizeof(asr_session_t)); + asr_session_t *asr_session; + mpf_stream_capabilities_t *capabilities; /* create session */ - session = mrcp_application_session_create(engine->mrcp_app,profile,asr_session); + session = mrcp_application_session_create(engine->mrcp_app,profile,NULL); if(!session) { - free(asr_session); return NULL; } pool = mrcp_application_session_pool_get(session); + + asr_session = apr_palloc(pool,sizeof(asr_session_t)); + mrcp_application_session_object_set(session,asr_session); - termination = mrcp_application_source_termination_create( + /* create source stream capabilities */ + capabilities = mpf_source_stream_capabilities_create(pool); + /* add codec capabilities (Linear PCM) */ + mpf_codec_capabilities_add( + &capabilities->codecs, + MPF_SAMPLE_RATE_8000, + "LPCM"); + + termination = mrcp_application_audio_termination_create( session, /* session, termination belongs to */ &audio_stream_vtable, /* virtual methods table of audio stream */ - NULL, /* codec descriptor of audio stream (NULL by default) */ - asr_session); /* object to associate */ - + capabilities, /* capabilities of audio stream */ + asr_session); /* object to associate */ + channel = mrcp_application_channel_create( session, /* session, channel belongs to */ MRCP_RECOGNIZER_RESOURCE, /* MRCP resource identifier */ @@ -466,7 +501,6 @@ ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, cons if(!channel) { mrcp_application_session_destroy(session); - free(asr_session); return NULL; } @@ -474,8 +508,10 @@ ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, cons asr_session->mrcp_session = session; asr_session->mrcp_channel = channel; asr_session->recog_complete = NULL; + asr_session->input_mode = INPUT_MODE_NONE; asr_session->streaming = FALSE; asr_session->audio_in = NULL; + asr_session->media_buffer = NULL; asr_session->mutex = NULL; asr_session->wait_object = NULL; asr_session->app_message = NULL; @@ -484,6 +520,9 @@ ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, cons apr_thread_mutex_create(&asr_session->mutex,APR_THREAD_MUTEX_DEFAULT,pool); apr_thread_cond_create(&asr_session->wait_object,pool); + /* Create media buffer */ + asr_session->media_buffer = mpf_frame_buffer_create(160,20,pool); + /* Send add channel request and wait for the response */ apr_thread_mutex_lock(asr_session->mutex); app_message = NULL; @@ -501,8 +540,11 @@ ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, cons return asr_session; } -/** Initiate recognition */ -ASR_CLIENT_DECLARE(const char*) asr_session_recognize(asr_session_t *asr_session, const char *grammar_file, const char *input_file) +/** Initiate recognition based on specified grammar and input file */ +ASR_CLIENT_DECLARE(const char*) asr_session_file_recognize( + asr_session_t *asr_session, + const char *grammar_file, + const char *input_file) { const mrcp_app_message_t *app_message; mrcp_message_t *mrcp_message; @@ -551,6 +593,7 @@ ASR_CLIENT_DECLARE(const char*) asr_session_recognize(asr_session_t *asr_session } /* Open input file and start streaming */ + asr_session->input_mode = INPUT_MODE_FILE; if(asr_input_file_open(asr_session,input_file) == FALSE) { return NULL; } @@ -579,6 +622,106 @@ ASR_CLIENT_DECLARE(const char*) asr_session_recognize(asr_session_t *asr_session return nlsml_input_get(asr_session->recog_complete); } +/** Initiate recognition based on specified grammar and input stream */ +ASR_CLIENT_DECLARE(const char*) asr_session_stream_recognize( + asr_session_t *asr_session, + const char *grammar_file) +{ + const mrcp_app_message_t *app_message; + mrcp_message_t *mrcp_message; + + app_message = NULL; + mrcp_message = define_grammar_message_create(asr_session,grammar_file); + if(!mrcp_message) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create DEFINE-GRAMMAR Request"); + return NULL; + } + + /* Send DEFINE-GRAMMAR request and wait for the response */ + apr_thread_mutex_lock(asr_session->mutex); + if(mrcp_application_message_send(asr_session->mrcp_session,asr_session->mrcp_channel,mrcp_message) == TRUE) { + apr_thread_cond_wait(asr_session->wait_object,asr_session->mutex); + app_message = asr_session->app_message; + asr_session->app_message = NULL; + } + apr_thread_mutex_unlock(asr_session->mutex); + + if(mrcp_response_check(app_message,MRCP_REQUEST_STATE_COMPLETE) == FALSE) { + return NULL; + } + + /* Reset prev recog result (if any) */ + asr_session->recog_complete = NULL; + + app_message = NULL; + mrcp_message = recognize_message_create(asr_session); + if(!mrcp_message) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create RECOGNIZE Request"); + return NULL; + } + + /* Send RECOGNIZE request and wait for the response */ + apr_thread_mutex_lock(asr_session->mutex); + if(mrcp_application_message_send(asr_session->mrcp_session,asr_session->mrcp_channel,mrcp_message) == TRUE) { + apr_thread_cond_wait(asr_session->wait_object,asr_session->mutex); + app_message = asr_session->app_message; + asr_session->app_message = NULL; + } + apr_thread_mutex_unlock(asr_session->mutex); + + if(mrcp_response_check(app_message,MRCP_REQUEST_STATE_INPROGRESS) == FALSE) { + return NULL; + } + + /* Reset media buffer */ + mpf_frame_buffer_restart(asr_session->media_buffer); + + /* Set input mode and start streaming */ + asr_session->input_mode = INPUT_MODE_STREAM; + asr_session->streaming = TRUE; + + /* Wait for events either START-OF-INPUT or RECOGNITION-COMPLETE */ + do { + apr_thread_mutex_lock(asr_session->mutex); + app_message = NULL; + if(apr_thread_cond_timedwait(asr_session->wait_object,asr_session->mutex, 60 * 1000000) != APR_SUCCESS) { + apr_thread_mutex_unlock(asr_session->mutex); + return NULL; + } + app_message = asr_session->app_message; + asr_session->app_message = NULL; + apr_thread_mutex_unlock(asr_session->mutex); + + mrcp_message = mrcp_event_get(app_message); + if(mrcp_message && mrcp_message->start_line.method_id == RECOGNIZER_RECOGNITION_COMPLETE) { + asr_session->recog_complete = mrcp_message; + } + } + while(!asr_session->recog_complete); + + /* Get results */ + return nlsml_input_get(asr_session->recog_complete); +} + +/** Write audio frame to recognize */ +ASR_CLIENT_DECLARE(apt_bool_t) asr_session_stream_write( + asr_session_t *asr_session, + char *data, + int size) +{ + mpf_frame_t frame; + frame.type = MEDIA_FRAME_TYPE_AUDIO; + frame.marker = MPF_MARKER_NONE; + frame.codec_frame.buffer = data; + frame.codec_frame.size = size; + + if(mpf_frame_buffer_write(asr_session->media_buffer,&frame) != TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Write Audio [%d]",size); + return FALSE; + } + return TRUE; +} + /** Destroy ASR session */ ASR_CLIENT_DECLARE(apt_bool_t) asr_session_destroy(asr_session_t *asr_session) { diff --git a/libs/unimrcp/platforms/libunimrcp-client/include/unimrcp_client.h b/libs/unimrcp/platforms/libunimrcp-client/include/unimrcp_client.h index 152f856374..2efff488c4 100644 --- a/libs/unimrcp/platforms/libunimrcp-client/include/unimrcp_client.h +++ b/libs/unimrcp/platforms/libunimrcp-client/include/unimrcp_client.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: unimrcp_client.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __UNIMRCP_CLIENT_H__ -#define __UNIMRCP_CLIENT_H__ +#ifndef UNIMRCP_CLIENT_H +#define UNIMRCP_CLIENT_H /** * @file unimrcp_client.h @@ -35,4 +37,4 @@ MRCP_DECLARE(mrcp_client_t*) unimrcp_client_create(apt_dir_layout_t *dir_layout) APT_END_EXTERN_C -#endif /*__UNIMRCP_CLIENT_H__*/ +#endif /* UNIMRCP_CLIENT_H */ diff --git a/libs/unimrcp/platforms/libunimrcp-client/libunimrcpclient.2008.vcproj b/libs/unimrcp/platforms/libunimrcp-client/libunimrcpclient.2008.vcproj deleted file mode 100644 index cee4d73515..0000000000 --- a/libs/unimrcp/platforms/libunimrcp-client/libunimrcpclient.2008.vcproj +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/platforms/libunimrcp-client/libunimrcpclient.vcproj b/libs/unimrcp/platforms/libunimrcp-client/libunimrcpclient.vcproj index 1d78a98519..170941bc41 100644 --- a/libs/unimrcp/platforms/libunimrcp-client/libunimrcpclient.vcproj +++ b/libs/unimrcp/platforms/libunimrcp-client/libunimrcpclient.vcproj @@ -244,6 +244,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + diff --git a/libs/unimrcp/platforms/libunimrcp-client/src/unimrcp_client.c b/libs/unimrcp/platforms/libunimrcp-client/src/unimrcp_client.c index b8eda6546d..3ef85f3329 100644 --- a/libs/unimrcp/platforms/libunimrcp-client/src/unimrcp_client.c +++ b/libs/unimrcp/platforms/libunimrcp-client/src/unimrcp_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,12 +12,16 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: unimrcp_client.c 1750 2010-07-23 19:33:34Z achaloyan $ */ #include #include -#include "unimrcp_client.h" +#include +#include #include "uni_version.h" +#include "unimrcp_client.h" #include "mrcp_resource_loader.h" #include "mpf_engine.h" #include "mpf_codec_manager.h" @@ -31,10 +35,8 @@ #define CONF_FILE_NAME "unimrcpclient.xml" #define DEFAULT_CONF_DIR_PATH "../conf" -#define DEFAULT_LOCAL_IP_ADDRESS "127.0.0.1" -#define DEFAULT_REMOTE_IP_ADDRESS "127.0.0.1" -#define DEFAULT_SIP_LOCAL_PORT 8062 -#define DEFAULT_SIP_REMOTE_PORT 8060 +#define DEFAULT_IP_ADDRESS "127.0.0.1" +#define DEFAULT_SIP_PORT 8062 #define DEFAULT_RTP_PORT_MIN 4000 #define DEFAULT_RTP_PORT_MAX 5000 @@ -42,17 +44,40 @@ #define DEFAULT_SDP_ORIGIN "UniMRCPClient" #define DEFAULT_RESOURCE_LOCATION "media" -#define XML_FILE_BUFFER_LENGTH 2000 +#define XML_FILE_BUFFER_LENGTH 16000 + +/** UniMRCP client loader */ +typedef struct unimrcp_client_loader_t unimrcp_client_loader_t; + +/** UniMRCP client loader */ +struct unimrcp_client_loader_t { + /** MRCP client */ + mrcp_client_t *client; + /** XML document */ + apr_xml_doc *doc; + /** Pool to allocate memory from */ + apr_pool_t *pool; + + /** Default ip address (named property) */ + const char *ip; + /** Default external (NAT) ip address (named property) */ + const char *ext_ip; + /** Default server ip address (named property) */ + const char *server_ip; + + /** Implicitly detected, cached ip address */ + const char *auto_ip; +}; -static apr_xml_doc* unimrcp_client_config_parse(const char *path, apr_pool_t *pool); -static apt_bool_t unimrcp_client_config_load(mrcp_client_t *client, const apr_xml_doc *doc, apr_pool_t *pool); +static apt_bool_t unimrcp_client_load(unimrcp_client_loader_t *loader, const char *dir_path, const char *file_name, apr_pool_t *pool); -/** Start UniMRCP client */ +/** Create and load UniMRCP client */ MRCP_DECLARE(mrcp_client_t*) unimrcp_client_create(apt_dir_layout_t *dir_layout) { apr_pool_t *pool; - apr_xml_doc *doc; mrcp_client_t *client; + const char *dir_path; + unimrcp_client_loader_t *loader; if(!dir_layout) { return NULL; @@ -69,51 +94,94 @@ MRCP_DECLARE(mrcp_client_t*) unimrcp_client_create(apt_dir_layout_t *dir_layout) return NULL; } - doc = unimrcp_client_config_parse(dir_layout->conf_dir_path,pool); - if(doc) { - unimrcp_client_config_load(client,doc,pool); + loader = apr_palloc(pool,sizeof(unimrcp_client_loader_t)); + loader->doc = NULL; + loader->client = client; + loader->pool = pool; + loader->ip = NULL; + loader->ext_ip = NULL; + loader->server_ip = NULL; + loader->auto_ip = NULL; + + dir_path = dir_layout->conf_dir_path; + if(!dir_path) { + dir_path = DEFAULT_CONF_DIR_PATH; + } + + if(unimrcp_client_load(loader,dir_path,CONF_FILE_NAME,pool) == FALSE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Load UniMRCP Client Document"); } return client; } -/** Parse config file */ -static apr_xml_doc* unimrcp_client_config_parse(const char *dir_path, apr_pool_t *pool) +/** Check whether specified attribute is valid */ +static APR_INLINE apt_bool_t is_attr_valid(const apr_xml_attr *attr) { - apr_xml_parser *parser = NULL; - apr_xml_doc *doc = NULL; - apr_file_t *fd = NULL; - apr_status_t rv; - const char *file_path; + return (attr && attr->value && attr->value != '\0'); +} - if(!dir_path) { - dir_path = DEFAULT_CONF_DIR_PATH; - } - if(*dir_path == '\0') { - file_path = CONF_FILE_NAME; - } - else { - file_path = apr_psprintf(pool,"%s/%s",dir_path,CONF_FILE_NAME); +/** Check whether specified attribute is enabled (true) */ +static APR_INLINE apt_bool_t is_attr_enabled(const apr_xml_attr *attr) +{ + if(attr && strcasecmp(attr->value,"false") == 0) { + return FALSE; } + return TRUE; +} - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Open Config File [%s]",file_path); - rv = apr_file_open(&fd,file_path,APR_READ|APR_BINARY,0,pool); - if(rv != APR_SUCCESS) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Config File [%s]",file_path); - return NULL; - } +/** Check whether cdata is valid */ +static APR_INLINE apt_bool_t is_cdata_valid(const apr_xml_elem *elem) +{ + return (elem->first_cdata.first && elem->first_cdata.first->text); +} - rv = apr_xml_parse_file(pool,&parser,&doc,fd,XML_FILE_BUFFER_LENGTH); - if(rv != APR_SUCCESS) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse Config File [%s]",file_path); - doc = NULL; +/** Get text cdata */ +static APR_INLINE const char* cdata_text_get(const apr_xml_elem *elem) +{ + return elem->first_cdata.first->text; +} + +/** Get boolean cdata */ +static APR_INLINE apt_bool_t cdata_bool_get(const apr_xml_elem *elem) +{ + return (strcasecmp(elem->first_cdata.first->text,"true") == 0) ? TRUE : FALSE; +} + +/** Copy cdata */ +static APR_INLINE char* cdata_copy(const apr_xml_elem *elem, apr_pool_t *pool) +{ + return apr_pstrdup(pool,elem->first_cdata.first->text); +} + +/** Get generic "id" and "enable" attributes */ +static apt_bool_t header_attribs_get(const apr_xml_elem *elem, const apr_xml_attr **id, const apr_xml_attr **enable) +{ + const apr_xml_attr *attr; + if(!id || !enable) { + return FALSE; } - apr_file_close(fd); - return doc; + *id = NULL; + *enable = NULL; + for(attr = elem->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"id") == 0) { + *id = attr; + } + else if(strcasecmp(attr->name,"enable") == 0) { + *enable = attr; + } + } + + if(is_attr_valid(*id) == FALSE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Missing Required Attribute in Element <%s>",elem->name); + return FALSE; + } + return TRUE; } -static apt_bool_t param_name_value_get(const apr_xml_elem *elem, const apr_xml_attr **name, const apr_xml_attr **value) +/** Get generic "name" and "value" attributes */ +static apt_bool_t name_value_attribs_get(const apr_xml_elem *elem, const apr_xml_attr **name, const apr_xml_attr **value) { const apr_xml_attr *attr; if(!name || !value) { @@ -133,531 +201,925 @@ static apt_bool_t param_name_value_get(const apr_xml_elem *elem, const apr_xml_a return (*name && *value) ? TRUE : FALSE; } -static char* ip_addr_get(const char *value, apr_pool_t *pool) +static char* unimrcp_client_ip_address_get(unimrcp_client_loader_t *loader, const apr_xml_elem *elem, const char *default_ip) { - if(!value || strcasecmp(value,"auto") == 0) { - char *addr = DEFAULT_LOCAL_IP_ADDRESS; - apt_ip_get(&addr,pool); - return addr; + const apr_xml_attr *attr = NULL; + for(attr = elem->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"type") == 0) { + break; + } + } + + if(attr && strcasecmp(attr->value,"auto") == 0) { + /* implicitly detect ip address, if not already detected */ + if(!loader->auto_ip) { + char *auto_addr = DEFAULT_IP_ADDRESS; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Detecting IP Address"); + apt_ip_get(&auto_addr,loader->pool); + loader->auto_ip = auto_addr; + } + return apr_pstrdup(loader->pool,loader->auto_ip); } - return apr_pstrdup(pool,value); + + if(is_cdata_valid(elem)) { + /* use specified ip address */ + return cdata_copy(elem,loader->pool); + } + + /* use default ip address */ + return apr_pstrdup(loader->pool,loader->ip); } -/** Load map of MRCP resource names */ -static apt_bool_t resource_map_load(apr_table_t *resource_map, const apr_xml_elem *root, apr_pool_t *pool) + + +/** Load resource */ +static apt_bool_t unimrcp_client_resource_load(mrcp_resource_loader_t *resource_loader, const apr_xml_elem *root, apr_pool_t *pool) +{ + apt_str_t resource_class; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + apt_string_reset(&resource_class); + + if(header_attribs_get(root,&id_attr,&enable_attr) == FALSE) { + return FALSE; + } + + if(is_attr_enabled(enable_attr) == FALSE) { + return TRUE; + } + + apt_string_set(&resource_class,id_attr->value); + return mrcp_resource_load(resource_loader,&resource_class); +} + +/** Load resource factory */ +static apt_bool_t unimrcp_client_resource_factory_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resource Map"); + mrcp_resource_factory_t *resource_factory; + mrcp_resource_loader_t *resource_loader = mrcp_resource_loader_create(FALSE,loader->pool); + if(!resource_loader) { + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resources"); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - apr_table_set(resource_map,attr_name->value,attr_value->value); - } + if(strcasecmp(elem->name,"resource") == 0) { + unimrcp_client_resource_load(resource_loader,elem,loader->pool); } - } - return TRUE; + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + resource_factory = mrcp_resource_factory_get(resource_loader); + return mrcp_client_resource_factory_register(loader->client,resource_factory); } /** Load SofiaSIP signaling agent */ -static mrcp_sig_agent_t* unimrcp_client_sofiasip_agent_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_client_sip_uac_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - mrcp_sofia_client_config_t *config = mrcp_sofiasip_client_config_alloc(pool); - config->local_ip = DEFAULT_LOCAL_IP_ADDRESS; - config->local_port = DEFAULT_SIP_LOCAL_PORT; - config->remote_ip = DEFAULT_REMOTE_IP_ADDRESS; - config->remote_port = DEFAULT_SIP_REMOTE_PORT; - config->ext_ip = NULL; + mrcp_sig_agent_t *agent; + mrcp_sofia_client_config_t *config; + + config = mrcp_sofiasip_client_config_alloc(loader->pool); + config->local_port = DEFAULT_SIP_PORT; config->user_agent_name = DEFAULT_SOFIASIP_UA_NAME; config->origin = DEFAULT_SDP_ORIGIN; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading SofiaSIP Agent"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading SofiaSIP Agent <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"client-ip") == 0) { - config->local_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"client-ext-ip") == 0) { - config->ext_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"client-port") == 0) { - config->local_port = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"server-ip") == 0) { - config->remote_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"server-port") == 0) { - config->remote_port = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"server-username") == 0) { - config->remote_user_name = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"force-destination") == 0) { - config->force_destination = atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"sip-transport") == 0) { - config->transport = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"ua-name") == 0) { - config->user_agent_name = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"sdp-origin") == 0) { - config->origin = apr_pstrdup(pool,attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"sip-ip") == 0) { + config->local_ip = unimrcp_client_ip_address_get(loader,elem,loader->ip); + } + else if(strcasecmp(elem->name,"sip-ext-ip") == 0) { + config->ext_ip = unimrcp_client_ip_address_get(loader,elem,loader->ext_ip); + } + else if(strcasecmp(elem->name,"sip-port") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->local_port = (apr_port_t)atol(cdata_text_get(elem)); } } - } - return mrcp_sofiasip_client_agent_create(config,pool); + else if(strcasecmp(elem->name,"sip-transport") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->transport = cdata_copy(elem,loader->pool); + } + } + else if(strcasecmp(elem->name,"ua-name") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->user_agent_name = cdata_copy(elem,loader->pool); + } + } + else if(strcasecmp(elem->name,"sdp-origin") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->origin = cdata_copy(elem,loader->pool); + } + } + else if(strcasecmp(elem->name,"sip-t1") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t1 = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"sip-t2") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t2 = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"sip-t4") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t4 = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"sip-t1x64") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t1x64 = atol(cdata_text_get(elem)); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + if(!config->local_ip) { + /* use default ip address if not specified */ + config->local_ip = apr_pstrdup(loader->pool,loader->ip); + } + if(!config->ext_ip && loader->ext_ip) { + /* use default ext ip address if not specified */ + config->ext_ip = apr_pstrdup(loader->pool,loader->ext_ip); + } + + agent = mrcp_sofiasip_client_agent_create(id,config,loader->pool); + return mrcp_client_signaling_agent_register(loader->client,agent); } /** Load UniRTSP signaling agent */ -static mrcp_sig_agent_t* unimrcp_client_rtsp_agent_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_client_rtsp_uac_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - rtsp_client_config_t *config = mrcp_unirtsp_client_config_alloc(pool); + mrcp_sig_agent_t *agent; + rtsp_client_config_t *config; + + config = mrcp_unirtsp_client_config_alloc(loader->pool); config->origin = DEFAULT_SDP_ORIGIN; - config->resource_location = DEFAULT_RESOURCE_LOCATION; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading UniRTSP Agent"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading UniRTSP Agent <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"server-ip") == 0) { - config->server_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"server-port") == 0) { - config->server_port = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"resource-location") == 0) { - config->resource_location = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"sdp-origin") == 0) { - config->origin = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"max-connection-count") == 0) { - config->max_connection_count = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"force-destination") == 0) { - config->force_destination = atoi(attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"sdp-origin") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->origin = cdata_copy(elem,loader->pool); } } - else if(strcasecmp(elem->name,"resourcemap") == 0) { - resource_map_load(config->resource_map,elem,pool); - } - } - return mrcp_unirtsp_client_agent_create(config,pool); -} - -/** Load signaling agents */ -static apt_bool_t unimrcp_client_signaling_agents_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) -{ - const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Signaling Agents"); - for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"agent") == 0) { - mrcp_sig_agent_t *sig_agent = NULL; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else if(strcasecmp(attr->name,"class") == 0) { - if(strcasecmp(attr->value,"SofiaSIP") == 0) { - sig_agent = unimrcp_client_sofiasip_agent_load(client,elem,pool); - } - else if(strcasecmp(attr->value,"UniRTSP") == 0) { - sig_agent = unimrcp_client_rtsp_agent_load(client,elem,pool); - } - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } + else if(strcasecmp(elem->name,"max-connection-count") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->max_connection_count = atol(cdata_text_get(elem)); } - if(sig_agent) { - mrcp_client_signaling_agent_register(client,sig_agent,name); + } + else if(strcasecmp(elem->name,"request-timeout") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->request_timeout = atol(cdata_text_get(elem)); } } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } - return TRUE; + } + + agent = mrcp_unirtsp_client_agent_create(id,config,loader->pool); + return mrcp_client_signaling_agent_register(loader->client,agent); } /** Load MRCPv2 connection agent */ -static mrcp_connection_agent_t* unimrcp_client_connection_agent_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_client_mrcpv2_uac_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; + mrcp_connection_agent_t *agent; apr_size_t max_connection_count = 100; apt_bool_t offer_new_connection = FALSE; + const char *rx_buffer_size = NULL; + const char *tx_buffer_size = NULL; + const char *request_timeout = NULL; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv2 Agent"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv2 Agent <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"max-connection-count") == 0) { - max_connection_count = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"offer-new-connection") == 0) { - offer_new_connection = atoi(attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"max-connection-count") == 0) { + if(is_cdata_valid(elem) == TRUE) { + max_connection_count = atol(cdata_text_get(elem)); } } - } - return mrcp_client_connection_agent_create(max_connection_count,offer_new_connection,pool); + else if(strcasecmp(elem->name,"offer-new-connection") == 0) { + if(is_cdata_valid(elem) == TRUE) { + offer_new_connection = atoi(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"rx-buffer-size") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rx_buffer_size = cdata_text_get(elem); + } + } + else if(strcasecmp(elem->name,"tx-buffer-size") == 0) { + if(is_cdata_valid(elem) == TRUE) { + tx_buffer_size = cdata_text_get(elem); + } + } + else if(strcasecmp(elem->name,"request-timeout") == 0) { + if(is_cdata_valid(elem) == TRUE) { + request_timeout = cdata_text_get(elem); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + agent = mrcp_client_connection_agent_create(id,max_connection_count,offer_new_connection,loader->pool); + if(agent) { + if(rx_buffer_size) { + mrcp_client_connection_rx_size_set(agent,atol(rx_buffer_size)); + } + if(tx_buffer_size) { + mrcp_client_connection_tx_size_set(agent,atol(tx_buffer_size)); + } + if(request_timeout) { + mrcp_client_connection_timeout_set(agent,atol(request_timeout)); + } + } + return mrcp_client_connection_agent_register(loader->client,agent); } -/** Load MRCPv2 conection agents */ -static apt_bool_t unimrcp_client_connection_agents_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +/** Load media engine */ +static apt_bool_t unimrcp_client_media_engine_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Connection Agents"); + mpf_engine_t *media_engine; + unsigned long realtime_rate = 1; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engine <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"agent") == 0) { - mrcp_connection_agent_t *connection_agent; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } - } - connection_agent = unimrcp_client_connection_agent_load(client,elem,pool); - if(connection_agent) { - mrcp_client_connection_agent_register(client,connection_agent,name); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"realtime-rate") == 0) { + if(is_cdata_valid(elem) == TRUE) { + realtime_rate = atol(cdata_text_get(elem)); } } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } - return TRUE; + } + + media_engine = mpf_engine_create(id,loader->pool); + if(media_engine) { + mpf_engine_scheduler_rate_set(media_engine,realtime_rate); + } + return mrcp_client_media_engine_register(loader->client,media_engine); } -/** Load RTP termination factory */ -static mpf_termination_factory_t* unimrcp_client_rtp_factory_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +/** Load RTP factory */ +static apt_bool_t unimrcp_client_rtp_factory_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - char *rtp_ip = DEFAULT_LOCAL_IP_ADDRESS; + char *rtp_ip = NULL; char *rtp_ext_ip = NULL; - mpf_rtp_config_t *rtp_config = mpf_rtp_config_create(pool); + mpf_termination_factory_t *rtp_factory; + mpf_rtp_config_t *rtp_config; + + rtp_config = mpf_rtp_config_alloc(loader->pool); rtp_config->rtp_port_min = DEFAULT_RTP_PORT_MIN; rtp_config->rtp_port_max = DEFAULT_RTP_PORT_MAX; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTP Termination Factory"); + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTP Factory <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"rtp-ip") == 0) { - rtp_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"rtp-ext-ip") == 0) { - rtp_ext_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"rtp-port-min") == 0) { - rtp_config->rtp_port_min = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtp-port-max") == 0) { - rtp_config->rtp_port_max = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"playout-delay") == 0) { - rtp_config->jb_config.initial_playout_delay = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"min-playout-delay") == 0) { - rtp_config->jb_config.min_playout_delay = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"max-playout-delay") == 0) { - rtp_config->jb_config.max_playout_delay = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"codecs") == 0) { - const mpf_codec_manager_t *codec_manager = mrcp_client_codec_manager_get(client); - if(codec_manager) { - mpf_codec_manager_codec_list_load(codec_manager,&rtp_config->codec_list,attr_value->value,pool); - } - } - else if(strcasecmp(attr_name->value,"ptime") == 0) { - rtp_config->ptime = (apr_uint16_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp") == 0) { - rtp_config->rtcp = atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp-bye") == 0) { - rtp_config->rtcp_bye_policy = atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp-tx-interval") == 0) { - rtp_config->rtcp_tx_interval = (apr_uint16_t)atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp-rx-resolution") == 0) { - rtp_config->rtcp_rx_resolution = (apr_uint16_t)atol(attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"rtp-ip") == 0) { + rtp_ip = unimrcp_client_ip_address_get(loader,elem,loader->ip); + } + else if(strcasecmp(elem->name,"rtp-ext-ip") == 0) { + rtp_ext_ip = unimrcp_client_ip_address_get(loader,elem,loader->ext_ip); + } + else if(strcasecmp(elem->name,"rtp-port-min") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtp_config->rtp_port_min = (apr_port_t)atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"rtp-port-max") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtp_config->rtp_port_max = (apr_port_t)atol(cdata_text_get(elem)); } } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } } - apt_string_set(&rtp_config->ip,rtp_ip); + + if(rtp_ip) { + apt_string_set(&rtp_config->ip,rtp_ip); + } + else { + apt_string_set(&rtp_config->ip,loader->ip); + } if(rtp_ext_ip) { apt_string_set(&rtp_config->ext_ip,rtp_ext_ip); } - return mpf_rtp_termination_factory_create(rtp_config,pool); + else if(loader->ext_ip){ + apt_string_set(&rtp_config->ext_ip,loader->ext_ip); + } + + rtp_factory = mpf_rtp_termination_factory_create(rtp_config,loader->pool); + return mrcp_client_rtp_factory_register(loader->client,rtp_factory,id); } -/** Load media engines */ -static apt_bool_t unimrcp_client_media_engines_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) + +/** Load SIP settings */ +static apt_bool_t unimrcp_client_sip_settings_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; + mrcp_sig_settings_t *settings = mrcp_signaling_settings_alloc(loader->pool); - /* create codec manager first */ - mpf_codec_manager_t *codec_manager = mpf_engine_codec_manager_create(pool); - if(codec_manager) { - mrcp_client_codec_manager_register(client,codec_manager); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading SIP Settings <%s>",id); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"server-ip") == 0) { + settings->server_ip = unimrcp_client_ip_address_get(loader,elem,loader->server_ip); + } + else if(strcasecmp(elem->name,"server-port") == 0) { + if(is_cdata_valid(elem) == TRUE) { + settings->server_port = (apr_port_t)atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"server-username") == 0) { + if(is_cdata_valid(elem) == TRUE) { + settings->user_name = cdata_copy(elem,loader->pool); + } + } + else if(strcasecmp(elem->name,"force-destination") == 0) { + if(is_cdata_valid(elem) == TRUE) { + settings->force_destination = cdata_bool_get(elem); + } + } + else if(strcasecmp(elem->name,"feature-tags") == 0) { + if(is_cdata_valid(elem) == TRUE) { + settings->feature_tags = cdata_copy(elem,loader->pool); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } } + + if(!settings->server_ip) { + settings->server_ip = apr_pstrdup(loader->pool,loader->server_ip); + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create SIP Settings %s:%hu",settings->server_ip,settings->server_port); + return mrcp_client_signaling_settings_register(loader->client,settings,id); +} - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engines"); +/** Load RTSP settings */ +static apt_bool_t unimrcp_client_rtsp_settings_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) +{ + const apr_xml_elem *elem; + mrcp_sig_settings_t *settings = mrcp_signaling_settings_alloc(loader->pool); + settings->resource_location = DEFAULT_RESOURCE_LOCATION; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTSP Settings <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"engine") == 0) { - mpf_engine_t *media_engine; - unsigned long realtime_rate = 1; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else if(strcasecmp(attr->name,"realtime-rate") == 0) { - realtime_rate = atol(attr->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"server-ip") == 0) { + settings->server_ip = unimrcp_client_ip_address_get(loader,elem,loader->server_ip); + } + else if(strcasecmp(elem->name,"server-port") == 0) { + if(is_cdata_valid(elem) == TRUE) { + settings->server_port = (apr_port_t)atol(cdata_text_get(elem)); } - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engine"); - media_engine = mpf_engine_create(pool); - if(media_engine) { - mpf_engine_scheduler_rate_set(media_engine,realtime_rate); - mrcp_client_media_engine_register(client,media_engine,name); + } + else if(strcasecmp(elem->name,"force-destination") == 0) { + if(is_cdata_valid(elem) == TRUE) { + settings->force_destination = cdata_bool_get(elem); } } - else if(strcasecmp(elem->name,"rtp") == 0) { - mpf_termination_factory_t *rtp_factory; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } + else if(strcasecmp(elem->name,"resource-location") == 0) { + if(is_cdata_valid(elem) == TRUE) { + settings->resource_location = cdata_copy(elem,loader->pool); } - rtp_factory = unimrcp_client_rtp_factory_load(client,elem,pool); - if(rtp_factory) { - mrcp_client_rtp_factory_register(client,rtp_factory,name); + else { + settings->resource_location = ""; } } + else if(strcasecmp(elem->name,"resource-map") == 0) { + const apr_xml_attr *name_attr; + const apr_xml_attr *value_attr; + const apr_xml_elem *child_elem; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resource Map"); + for(child_elem = elem->first_child; child_elem; child_elem = child_elem->next) { + if(name_value_attribs_get(child_elem,&name_attr,&value_attr) == TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",name_attr->value,value_attr->value); + apr_table_set(settings->resource_map,name_attr->value,value_attr->value); + } + } + } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } - return TRUE; + } + + if(!settings->server_ip) { + settings->server_ip = apr_pstrdup(loader->pool,loader->server_ip); + } + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create RTSP Settings %s:%hu",settings->server_ip,settings->server_port); + return mrcp_client_signaling_settings_register(loader->client,settings,id); } -/** Load resource */ -static apt_bool_t unimrcp_client_resource_load(mrcp_client_t *client, mrcp_resource_loader_t *resource_loader, const apr_xml_elem *root, apr_pool_t *pool) +/** Load jitter buffer settings */ +static apt_bool_t unimrcp_client_jb_settings_load(unimrcp_client_loader_t *loader, mpf_jb_config_t *jb, const apr_xml_elem *root) { - apt_str_t resource_class; - apt_bool_t resource_enabled = TRUE; - const apr_xml_attr *attr; - apt_string_reset(&resource_class); - for(attr = root->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"class") == 0) { - apt_string_set(&resource_class,attr->value); + const apr_xml_elem *elem; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Jitter Buffer Settings"); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"playout-delay") == 0) { + if(is_cdata_valid(elem) == TRUE) { + jb->initial_playout_delay = atol(cdata_text_get(elem)); + } } - else if(strcasecmp(attr->name,"enable") == 0) { - resource_enabled = atoi(attr->value); + else if(strcasecmp(elem->name,"min-playout-delay") == 0) { + if(is_cdata_valid(elem) == TRUE) { + jb->min_playout_delay = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"max-playout-delay") == 0) { + if(is_cdata_valid(elem) == TRUE) { + jb->max_playout_delay = atol(cdata_text_get(elem)); + } } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } + return TRUE; +} - if(!resource_class.buf || !resource_enabled) { - return FALSE; +/** Load RTCP settings */ +static apt_bool_t unimrcp_client_rtcp_settings_load(unimrcp_client_loader_t *loader, mpf_rtp_settings_t *rtcp_settings, const apr_xml_elem *root) +{ + const apr_xml_elem *elem; + const apr_xml_attr *attr = NULL; + for(attr = root->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"enable") == 0) { + break; + } } - return mrcp_resource_load(resource_loader,&resource_class); + if(is_attr_enabled(attr) == FALSE) { + /* RTCP is disabled, skip the rest */ + return TRUE; + } + + rtcp_settings->rtcp = TRUE; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTCP Settings"); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"rtcp-bye") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtcp_settings->rtcp_bye_policy = atoi(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"tx-interval") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtcp_settings->rtcp_tx_interval = (apr_uint16_t)atoi(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"rx-resolution") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtcp_settings->rtcp_rx_resolution = (apr_uint16_t)atol(cdata_text_get(elem)); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + return TRUE; } -/** Load resources */ -static apt_bool_t unimrcp_client_resources_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +/** Load RTP settings */ +static apt_bool_t unimrcp_client_rtp_settings_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - mrcp_resource_factory_t *resource_factory; - mrcp_resource_loader_t *resource_loader = mrcp_resource_loader_create(FALSE,pool); - if(!resource_loader) { - return FALSE; - } + mpf_rtp_settings_t *rtp_settings = mpf_rtp_settings_alloc(loader->pool); - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resources"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTP Settings <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"resource") == 0) { - unimrcp_client_resource_load(client,resource_loader,elem,pool); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"jitter-buffer") == 0) { + unimrcp_client_jb_settings_load(loader,&rtp_settings->jb_config,elem); + } + else if(strcasecmp(elem->name,"ptime") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtp_settings->ptime = (apr_uint16_t)atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"codecs") == 0) { + const mpf_codec_manager_t *codec_manager = mrcp_client_codec_manager_get(loader->client); + if(is_cdata_valid(elem) == TRUE && codec_manager) { + mpf_codec_manager_codec_list_load( + codec_manager, + &rtp_settings->codec_list, + cdata_text_get(elem), + loader->pool); + } + } + else if(strcasecmp(elem->name,"rtcp") == 0) { + unimrcp_client_rtcp_settings_load(loader,rtp_settings,elem); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } - - resource_factory = mrcp_resource_factory_get(resource_loader); - mrcp_client_resource_factory_register(client,resource_factory); - return TRUE; + + return mrcp_client_rtp_settings_register(loader->client,rtp_settings,id); } -/** Load settings */ -static apt_bool_t unimrcp_client_settings_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +/** Load MRCPv2 profile */ +static apt_bool_t unimrcp_client_mrcpv2_profile_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Settings"); + mrcp_profile_t *profile; + mrcp_sig_agent_t *sip_agent = NULL; + mrcp_connection_agent_t *mrcpv2_agent = NULL; + mpf_engine_t *media_engine = NULL; + mpf_termination_factory_t *rtp_factory = NULL; + mpf_rtp_settings_t *rtp_settings = NULL; + mrcp_sig_settings_t *sip_settings = NULL; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv2 Profile <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"signaling") == 0) { - unimrcp_client_signaling_agents_load(client,elem,pool); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + + if(is_cdata_valid(elem) == FALSE) { + continue; + } + + if(strcasecmp(elem->name,"sip-uac") == 0) { + sip_agent = mrcp_client_signaling_agent_get(loader->client,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"mrcpv2-uac") == 0) { + mrcpv2_agent = mrcp_client_connection_agent_get(loader->client,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"media-engine") == 0) { + media_engine = mrcp_client_media_engine_get(loader->client,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtp-factory") == 0) { + rtp_factory = mrcp_client_rtp_factory_get(loader->client,cdata_text_get(elem)); } - else if(strcasecmp(elem->name,"connection") == 0) { - unimrcp_client_connection_agents_load(client,elem,pool); + else if(strcasecmp(elem->name,"sip-settings") == 0) { + sip_settings = mrcp_client_signaling_settings_get(loader->client,cdata_text_get(elem)); } - else if(strcasecmp(elem->name,"media") == 0) { - unimrcp_client_media_engines_load(client,elem,pool); + else if(strcasecmp(elem->name,"rtp-settings") == 0) { + rtp_settings = mrcp_client_rtp_settings_get(loader->client,cdata_text_get(elem)); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } - return TRUE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv2 Profile [%s]",id); + profile = mrcp_client_profile_create( + NULL,sip_agent,mrcpv2_agent, + media_engine,rtp_factory, + rtp_settings,sip_settings, + loader->pool); + return mrcp_client_profile_register(loader->client,profile,id); } -/** Load profile */ -static apt_bool_t unimrcp_client_profile_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +/** Load MRCPv1 profile */ +static apt_bool_t unimrcp_client_mrcpv1_profile_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root, const char *id) { - const char *name = NULL; + const apr_xml_elem *elem; mrcp_profile_t *profile; - mrcp_sig_agent_t *sig_agent = NULL; - mrcp_connection_agent_t *cnt_agent = NULL; + mrcp_sig_agent_t *rtsp_agent = NULL; mpf_engine_t *media_engine = NULL; mpf_termination_factory_t *rtp_factory = NULL; + mpf_rtp_settings_t *rtp_settings = NULL; + mrcp_sig_settings_t *rtsp_settings = NULL; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv1 Profile <%s>",id); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + + if(is_cdata_valid(elem) == FALSE) { + continue; + } + + if(strcasecmp(elem->name,"rtsp-uac") == 0) { + rtsp_agent = mrcp_client_signaling_agent_get(loader->client,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"media-engine") == 0) { + media_engine = mrcp_client_media_engine_get(loader->client,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtp-factory") == 0) { + rtp_factory = mrcp_client_rtp_factory_get(loader->client,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtsp-settings") == 0) { + rtsp_settings = mrcp_client_signaling_settings_get(loader->client,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtp-settings") == 0) { + rtp_settings = mrcp_client_rtp_settings_get(loader->client,cdata_text_get(elem)); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv1 Profile [%s]",id); + profile = mrcp_client_profile_create( + NULL,rtsp_agent,NULL, + media_engine,rtp_factory, + rtp_settings,rtsp_settings, + loader->pool); + return mrcp_client_profile_register(loader->client,profile,id); +} + + +/** Load properties */ +static apt_bool_t unimrcp_client_properties_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root) +{ const apr_xml_elem *elem; - const apr_xml_attr *attr; - for(attr = root->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Profile [%s]",name); + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Properties"); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"ip") == 0) { + loader->ip = unimrcp_client_ip_address_get(loader,elem,DEFAULT_IP_ADDRESS); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set Property ip:%s",loader->ip); + } + else if(strcasecmp(elem->name,"ext-ip") == 0) { + loader->ext_ip = unimrcp_client_ip_address_get(loader,elem,DEFAULT_IP_ADDRESS); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set Property ext-ip:%s",loader->ext_ip); + } + else if(strcasecmp(elem->name,"server-ip") == 0) { + loader->server_ip = unimrcp_client_ip_address_get(loader,elem,DEFAULT_IP_ADDRESS); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set Property server-ip:%s",loader->server_ip); } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } - if(!name) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Load Profile: no profile name specified"); - return FALSE; + + if(!loader->ip) { + loader->ip = DEFAULT_IP_ADDRESS; + } + if(!loader->server_ip) { + loader->server_ip = loader->ip; + } + return TRUE; +} + +/** Load components */ +static apt_bool_t unimrcp_client_components_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root) +{ + const apr_xml_elem *elem; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + const char *id; + + /* Create codec manager first (probably it should be loaded from config either) */ + mpf_codec_manager_t *codec_manager = mpf_engine_codec_manager_create(loader->pool); + if(codec_manager) { + mrcp_client_codec_manager_register(loader->client,codec_manager); } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Components"); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Loading Profile %s [%s]",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"signaling-agent") == 0) { - sig_agent = mrcp_client_signaling_agent_get(client,attr_value->value); - } - else if(strcasecmp(attr_name->value,"connection-agent") == 0) { - cnt_agent = mrcp_client_connection_agent_get(client,attr_value->value); - } - else if(strcasecmp(attr_name->value,"media-engine") == 0) { - media_engine = mrcp_client_media_engine_get(client,attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtp-factory") == 0) { - rtp_factory = mrcp_client_rtp_factory_get(client,attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } - } + if(strcasecmp(elem->name,"resource-factory") == 0) { + unimrcp_client_resource_factory_load(loader,elem); + continue; } - } + + /* get common "id" and "enable" attributes */ + if(header_attribs_get(elem,&id_attr,&enable_attr) == FALSE) { + /* invalid id */ + continue; + } + if(is_attr_enabled(enable_attr) == FALSE) { + /* disabled element, just skip it */ + continue; + } + id = apr_pstrdup(loader->pool,id_attr->value); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create Profile [%s]",name); - profile = mrcp_client_profile_create(NULL,sig_agent,cnt_agent,media_engine,rtp_factory,pool); - return mrcp_client_profile_register(client,profile,name); + if(strcasecmp(elem->name,"sip-uac") == 0) { + unimrcp_client_sip_uac_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"rtsp-uac") == 0) { + unimrcp_client_rtsp_uac_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"mrcpv2-uac") == 0) { + unimrcp_client_mrcpv2_uac_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"media-engine") == 0) { + unimrcp_client_media_engine_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"rtp-factory") == 0) { + unimrcp_client_rtp_factory_load(loader,elem,id); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + return TRUE; +} + +/** Load settings */ +static apt_bool_t unimrcp_client_settings_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root) +{ + const apr_xml_elem *elem; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + const char *id; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Settings"); + for(elem = root->first_child; elem; elem = elem->next) { + /* get common "id" and "enable" attributes */ + if(header_attribs_get(elem,&id_attr,&enable_attr) == FALSE) { + /* invalid id */ + continue; + } + if(is_attr_enabled(enable_attr) == FALSE) { + /* disabled element, just skip it */ + continue; + } + id = apr_pstrdup(loader->pool,id_attr->value); + + if(strcasecmp(elem->name,"sip-settings") == 0) { + unimrcp_client_sip_settings_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"rtsp-settings") == 0) { + unimrcp_client_rtsp_settings_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"rtp-settings") == 0) { + unimrcp_client_rtp_settings_load(loader,elem,id); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + return TRUE; } /** Load profiles */ -static apt_bool_t unimrcp_client_profiles_load(mrcp_client_t *client, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_client_profiles_load(unimrcp_client_loader_t *loader, const apr_xml_elem *root) { const apr_xml_elem *elem; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + const char *id; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Profiles"); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"profile") == 0) { - unimrcp_client_profile_load(client,elem,pool); + /* get common "id" and "enable" attributes */ + if(header_attribs_get(elem,&id_attr,&enable_attr) == FALSE) { + /* invalid id */ + continue; + } + if(is_attr_enabled(enable_attr) == FALSE) { + /* disabled element, just skip it */ + continue; + } + id = apr_pstrdup(loader->pool,id_attr->value); + + if(strcasecmp(elem->name,"mrcpv2-profile") == 0) { + unimrcp_client_mrcpv2_profile_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"mrcpv1-profile") == 0) { + unimrcp_client_mrcpv1_profile_load(loader,elem,id); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } + } + return TRUE; +} + +/** Parse XML document */ +static apr_xml_doc* unimrcp_client_doc_parse(const char *file_path, apr_pool_t *pool) +{ + apr_xml_parser *parser = NULL; + apr_xml_doc *xml_doc = NULL; + apr_file_t *fd = NULL; + apr_status_t rv; + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Open Config File [%s]",file_path); + rv = apr_file_open(&fd,file_path,APR_READ|APR_BINARY,0,pool); + if(rv != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Config File [%s]",file_path); + return NULL; } - return TRUE; + + rv = apr_xml_parse_file(pool,&parser,&xml_doc,fd,XML_FILE_BUFFER_LENGTH); + if(rv != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse Config File [%s]",file_path); + xml_doc = NULL; + } + + apr_file_close(fd); + return xml_doc; } -/** Load configuration (settings and profiles) */ -static apt_bool_t unimrcp_client_config_load(mrcp_client_t *client, const apr_xml_doc *doc, apr_pool_t *pool) +/** Load UniMRCP client */ +static apt_bool_t unimrcp_client_load(unimrcp_client_loader_t *loader, const char *dir_path, const char *file_name, apr_pool_t *pool) { + apr_xml_doc *doc; const apr_xml_elem *elem; - const apr_xml_elem *root = doc->root; + const apr_xml_elem *root; + const apr_xml_attr *attr; + const char *file_path; + const char *version = NULL; + const char *subfolder = NULL; + + if(!dir_path || !file_name) { + return FALSE; + } + + if(*dir_path == '\0') { + file_path = file_name; + } + else { + file_path = apr_psprintf(pool,"%s/%s",dir_path,file_name); + } + + /* Parse XML document */ + doc = unimrcp_client_doc_parse(file_path,pool); + if(!doc) { + return FALSE; + } + + root = doc->root; + + /* Match document name */ if(!root || strcasecmp(root->name,"unimrcpclient") != 0) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document <%s>",root->name); + return FALSE; + } + + /* Read attributes */ + for(attr = root->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"version") == 0) { + version = attr->value; + } + else if(strcasecmp(attr->name,"subfolder") == 0) { + subfolder = attr->value; + } + } + + /* Check version number first */ + if(!version) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Version"); return FALSE; } + + loader->doc = doc; + + /* Navigate through document */ for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"resources") == 0) { - unimrcp_client_resources_load(client,elem,pool); + if(strcasecmp(elem->name,"properties") == 0) { + unimrcp_client_properties_load(loader,elem); + } + else if(strcasecmp(elem->name,"components") == 0) { + unimrcp_client_components_load(loader,elem); } else if(strcasecmp(elem->name,"settings") == 0) { - unimrcp_client_settings_load(client,elem,pool); + unimrcp_client_settings_load(loader,elem); } else if(strcasecmp(elem->name,"profiles") == 0) { - unimrcp_client_profiles_load(client,elem,pool); + unimrcp_client_profiles_load(loader,elem); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } - + + if(subfolder && subfolder != '\0') { + apr_dir_t *dir; + apr_finfo_t finfo; + apr_status_t rv; + + dir_path = apr_psprintf(pool,"%s/%s",dir_path,subfolder); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enter Directory [%s]",dir_path); + rv = apr_dir_open(&dir,dir_path,pool); + if(rv == APR_SUCCESS) { + while(apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { + if(apr_fnmatch("*.xml", finfo.name, 0) == APR_SUCCESS) { + unimrcp_client_load(loader,dir_path,finfo.name,pool); + } + } + apr_dir_close(dir); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Leave Directory [%s]",dir_path); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Directory %s",dir_path); + } + } return TRUE; } diff --git a/libs/unimrcp/platforms/libunimrcp-server/include/unimrcp_server.h b/libs/unimrcp/platforms/libunimrcp-server/include/unimrcp_server.h index 39f3813048..c66fb74e56 100644 --- a/libs/unimrcp/platforms/libunimrcp-server/include/unimrcp_server.h +++ b/libs/unimrcp/platforms/libunimrcp-server/include/unimrcp_server.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: unimrcp_server.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __UNIMRCP_SERVER_H__ -#define __UNIMRCP_SERVER_H__ +#ifndef UNIMRCP_SERVER_H +#define UNIMRCP_SERVER_H /** * @file unimrcp_server.h @@ -40,4 +42,4 @@ MRCP_DECLARE(apt_bool_t) unimrcp_server_shutdown(mrcp_server_t *server); APT_END_EXTERN_C -#endif /*__UNIMRCP_SERVER_H__*/ +#endif /* UNIMRCP_SERVER_H */ diff --git a/libs/unimrcp/platforms/libunimrcp-server/libunimrcpserver.2008.vcproj b/libs/unimrcp/platforms/libunimrcp-server/libunimrcpserver.2008.vcproj deleted file mode 100644 index d1b51c7929..0000000000 --- a/libs/unimrcp/platforms/libunimrcp-server/libunimrcpserver.2008.vcproj +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/platforms/libunimrcp-server/libunimrcpserver.vcproj b/libs/unimrcp/platforms/libunimrcp-server/libunimrcpserver.vcproj index 877610a9a3..0f5b68f4e9 100644 --- a/libs/unimrcp/platforms/libunimrcp-server/libunimrcpserver.vcproj +++ b/libs/unimrcp/platforms/libunimrcp-server/libunimrcpserver.vcproj @@ -244,6 +244,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + diff --git a/libs/unimrcp/platforms/libunimrcp-server/src/unimrcp_server.c b/libs/unimrcp/platforms/libunimrcp-server/src/unimrcp_server.c index d2532c6ebf..d7b23865c2 100644 --- a/libs/unimrcp/platforms/libunimrcp-server/src/unimrcp_server.c +++ b/libs/unimrcp/platforms/libunimrcp-server/src/unimrcp_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,12 +12,15 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: unimrcp_server.c 1711 2010-05-25 17:54:02Z achaloyan $ */ #include #include -#include "unimrcp_server.h" +#include #include "uni_version.h" +#include "unimrcp_server.h" #include "mrcp_resource_loader.h" #include "mpf_engine.h" #include "mpf_codec_manager.h" @@ -29,7 +32,6 @@ #include "apt_log.h" #define CONF_FILE_NAME "unimrcpserver.xml" -#define DEFAULT_CONF_DIR_PATH "../conf" #define DEFAULT_PLUGIN_DIR_PATH "../plugin" #ifdef WIN32 #define DEFAULT_PLUGIN_EXT "dll" @@ -47,16 +49,37 @@ #define DEFAULT_SOFIASIP_UA_NAME "UniMRCP SofiaSIP" #define DEFAULT_SDP_ORIGIN "UniMRCPServer" -#define XML_FILE_BUFFER_LENGTH 2000 +#define XML_FILE_BUFFER_LENGTH 16000 + +/** UniMRCP server loader */ +typedef struct unimrcp_server_loader_t unimrcp_server_loader_t; + +/** UniMRCP server loader */ +struct unimrcp_server_loader_t { + /** MRCP server */ + mrcp_server_t *server; + /** Directory layout */ + apt_dir_layout_t *dir_layout; + /** XML document */ + apr_xml_doc *doc; + /** Pool to allocate memory from */ + apr_pool_t *pool; -static apr_xml_doc* unimrcp_server_config_parse(const char *path, apr_pool_t *pool); -static apt_bool_t unimrcp_server_config_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_doc *doc, apr_pool_t *pool); + /** Default ip address (named property) */ + const char *ip; + /** Default external (NAT) ip address (named property) */ + const char *ext_ip; + + /** Implicitly detected, cached ip address */ + const char *auto_ip; +}; + +static apt_bool_t unimrcp_server_load(mrcp_server_t *mrcp_server, apt_dir_layout_t *dir_layout, apr_pool_t *pool); /** Start UniMRCP server */ MRCP_DECLARE(mrcp_server_t*) unimrcp_server_start(apt_dir_layout_t *dir_layout) { apr_pool_t *pool; - apr_xml_doc *doc; mrcp_server_t *server; if(!dir_layout) { @@ -74,9 +97,8 @@ MRCP_DECLARE(mrcp_server_t*) unimrcp_server_start(apt_dir_layout_t *dir_layout) return NULL; } - doc = unimrcp_server_config_parse(dir_layout->conf_dir_path,pool); - if(doc) { - unimrcp_server_config_load(server,dir_layout->plugin_dir_path,doc,pool); + if(unimrcp_server_load(server,dir_layout,pool) == FALSE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Load UniMRCP Server Document"); } mrcp_server_start(server); @@ -93,43 +115,73 @@ MRCP_DECLARE(apt_bool_t) unimrcp_server_shutdown(mrcp_server_t *server) } -/** Parse config file */ -static apr_xml_doc* unimrcp_server_config_parse(const char *dir_path, apr_pool_t *pool) +/** Check whether specified attribute is valid */ +static APR_INLINE apt_bool_t is_attr_valid(const apr_xml_attr *attr) { - apr_xml_parser *parser = NULL; - apr_xml_doc *doc = NULL; - apr_file_t *fd = NULL; - apr_status_t rv; - const char *file_path; + return (attr && attr->value && attr->value != '\0'); +} - if(!dir_path) { - dir_path = DEFAULT_CONF_DIR_PATH; - } - if(*dir_path == '\0') { - file_path = CONF_FILE_NAME; - } - else { - file_path = apr_psprintf(pool,"%s/%s",dir_path,CONF_FILE_NAME); +/** Check whether specified attribute is enabled (true) */ +static APR_INLINE apt_bool_t is_attr_enabled(const apr_xml_attr *attr) +{ + if(attr && strcasecmp(attr->value,"false") == 0) { + return FALSE; } + return TRUE; +} - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Open Config File [%s]",file_path); - rv = apr_file_open(&fd,file_path,APR_READ|APR_BINARY,0,pool); - if(rv != APR_SUCCESS) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Config File [%s]",file_path); - return NULL; - } +/** Check whether cdata is valid */ +static APR_INLINE apt_bool_t is_cdata_valid(const apr_xml_elem *elem) +{ + return (elem->first_cdata.first && elem->first_cdata.first->text); +} - rv = apr_xml_parse_file(pool,&parser,&doc,fd,XML_FILE_BUFFER_LENGTH); - if(rv != APR_SUCCESS) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse Config File [%s]",file_path); - doc = NULL; +/** Get text cdata */ +static APR_INLINE const char* cdata_text_get(const apr_xml_elem *elem) +{ + return elem->first_cdata.first->text; +} + +/** Get boolean cdata */ +static APR_INLINE apt_bool_t cdata_bool_get(const apr_xml_elem *elem) +{ + return (strcasecmp(elem->first_cdata.first->text,"true") == 0) ? TRUE : FALSE; +} + +/** Copy cdata */ +static APR_INLINE char* cdata_copy(const apr_xml_elem *elem, apr_pool_t *pool) +{ + return apr_pstrdup(pool,elem->first_cdata.first->text); +} + +/** Get generic "id" and "enable" attributes */ +static apt_bool_t header_attribs_get(const apr_xml_elem *elem, const apr_xml_attr **id, const apr_xml_attr **enable) +{ + const apr_xml_attr *attr; + if(!id || !enable) { + return FALSE; } - apr_file_close(fd); - return doc; + *id = NULL; + *enable = NULL; + for(attr = elem->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"id") == 0) { + *id = attr; + } + else if(strcasecmp(attr->name,"enable") == 0) { + *enable = attr; + } + } + + if(is_attr_valid(*id) == FALSE) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Missing Required Attribute in Element <%s>",elem->name); + return FALSE; + } + return TRUE; } -static apt_bool_t param_name_value_get(const apr_xml_elem *elem, const apr_xml_attr **name, const apr_xml_attr **value) +/** Get generic "name" and "value" attributes */ +static apt_bool_t name_value_attribs_get(const apr_xml_elem *elem, const apr_xml_attr **name, const apr_xml_attr **value) { const apr_xml_attr *attr; if(!name || !value) { @@ -149,491 +201,440 @@ static apt_bool_t param_name_value_get(const apr_xml_elem *elem, const apr_xml_a return (*name && *value) ? TRUE : FALSE; } -static char* ip_addr_get(const char *value, apr_pool_t *pool) +static char* unimrcp_server_ip_address_get(unimrcp_server_loader_t *loader, const apr_xml_elem *elem) { - if(!value || strcasecmp(value,"auto") == 0) { - char *addr = DEFAULT_IP_ADDRESS; - apt_ip_get(&addr,pool); - return addr; + const apr_xml_attr *attr = NULL; + for(attr = elem->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"type") == 0) { + break; + } + } + + if(attr && strcasecmp(attr->value,"auto") == 0) { + /* implicitly detect ip address, if not already detected */ + if(!loader->auto_ip) { + char *auto_addr = DEFAULT_IP_ADDRESS; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Detecting IP Address"); + apt_ip_get(&auto_addr,loader->pool); + loader->auto_ip = auto_addr; + } + return apr_pstrdup(loader->pool,loader->auto_ip); } - return apr_pstrdup(pool,value); + + if(is_cdata_valid(elem)) { + /* use provided ip address */ + return cdata_copy(elem,loader->pool); + } + + /* use default ip address */ + return apr_pstrdup(loader->pool,loader->ip); } -/** Load map of MRCP resource names */ -static apt_bool_t resource_map_load(apr_table_t *resource_map, const apr_xml_elem *root, apr_pool_t *pool) +/** Load resource */ +static apt_bool_t unimrcp_server_resource_load(mrcp_resource_loader_t *resource_loader, const apr_xml_elem *root, apr_pool_t *pool) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resource Map"); - for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - apr_table_set(resource_map,attr_name->value,attr_value->value); - } - } - } - return TRUE; + apt_str_t resource_class; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + apt_string_reset(&resource_class); + + if(header_attribs_get(root,&id_attr,&enable_attr) == FALSE) { + return FALSE; + } + + if(is_attr_enabled(enable_attr) == FALSE) { + return TRUE; + } + + apt_string_set(&resource_class,id_attr->value); + return mrcp_resource_load(resource_loader,&resource_class); } -/** Load map of plugins */ -static apt_bool_t plugin_map_load(apr_table_t *plugin_map, const apr_xml_elem *root, apr_pool_t *pool) +/** Load resource factory */ +static apt_bool_t unimrcp_server_resource_factory_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Plugin Map"); + mrcp_resource_factory_t *resource_factory; + mrcp_resource_loader_t *resource_loader = mrcp_resource_loader_create(FALSE,loader->pool); + if(!resource_loader) { + return FALSE; + } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resources"); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - apr_table_set(plugin_map,attr_name->value,attr_value->value); - } + if(strcasecmp(elem->name,"resource") == 0) { + unimrcp_server_resource_load(resource_loader,elem,loader->pool); } - } - return TRUE; + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + resource_factory = mrcp_resource_factory_get(resource_loader); + return mrcp_server_resource_factory_register(loader->server,resource_factory); } /** Load SofiaSIP signaling agent */ -static mrcp_sig_agent_t* unimrcp_server_sofiasip_agent_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_server_sip_uas_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - mrcp_sofia_server_config_t *config = mrcp_sofiasip_server_config_alloc(pool); - config->local_ip = DEFAULT_IP_ADDRESS; + mrcp_sig_agent_t *agent; + mrcp_sofia_server_config_t *config; + + config = mrcp_sofiasip_server_config_alloc(loader->pool); config->local_port = DEFAULT_SIP_PORT; - config->ext_ip = NULL; config->user_agent_name = DEFAULT_SOFIASIP_UA_NAME; config->origin = DEFAULT_SDP_ORIGIN; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading SofiaSIP Agent"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading SofiaSIP Agent <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"sip-ip") == 0) { - config->local_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"sip-ext-ip") == 0) { - config->ext_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"sip-port") == 0) { - config->local_port = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"sip-transport") == 0) { - config->transport = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"ua-name") == 0) { - config->user_agent_name = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"sdp-origin") == 0) { - config->origin = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"force-destination") == 0) { - config->force_destination = atoi(attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"sip-ip") == 0) { + config->local_ip = unimrcp_server_ip_address_get(loader,elem); + } + else if(strcasecmp(elem->name,"sip-ext-ip") == 0) { + config->ext_ip = unimrcp_server_ip_address_get(loader,elem); + } + else if(strcasecmp(elem->name,"sip-port") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->local_port = (apr_port_t)atol(cdata_text_get(elem)); } } - } - return mrcp_sofiasip_server_agent_create(config,pool); + else if(strcasecmp(elem->name,"sip-transport") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->transport = cdata_copy(elem,loader->pool); + } + } + else if(strcasecmp(elem->name,"ua-name") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->user_agent_name = cdata_copy(elem,loader->pool); + } + } + else if(strcasecmp(elem->name,"sdp-origin") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->origin = cdata_copy(elem,loader->pool); + } + } + else if(strcasecmp(elem->name,"force-destination") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->force_destination = cdata_bool_get(elem); + } + } + else if(strcasecmp(elem->name,"sip-t1") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t1 = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"sip-t2") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t2 = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"sip-t4") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t4 = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"sip-t1x64") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->sip_t1x64 = atol(cdata_text_get(elem)); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + if(!config->local_ip) { + /* use default ip address if not specified */ + config->local_ip = apr_pstrdup(loader->pool,loader->ip); + } + if(!config->ext_ip && loader->ext_ip) { + /* use default ext ip address if not specified */ + config->ext_ip = apr_pstrdup(loader->pool,loader->ext_ip); + } + + agent = mrcp_sofiasip_server_agent_create(id,config,loader->pool); + return mrcp_server_signaling_agent_register(loader->server,agent); } /** Load UniRTSP signaling agent */ -static mrcp_sig_agent_t* unimrcp_server_rtsp_agent_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_server_rtsp_uas_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - rtsp_server_config_t *config = mrcp_unirtsp_server_config_alloc(pool); - config->local_ip = DEFAULT_IP_ADDRESS; - config->local_port = DEFAULT_RTSP_PORT; - config->origin = DEFAULT_SDP_ORIGIN; + mrcp_sig_agent_t *agent; + rtsp_server_config_t *config; + config = mrcp_unirtsp_server_config_alloc(loader->pool); + config->origin = DEFAULT_SDP_ORIGIN; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading UniRTSP Agent"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading UniRTSP Agent <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"rtsp-ip") == 0) { - config->local_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"rtsp-port") == 0) { - config->local_port = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"sdp-origin") == 0) { - config->origin = apr_pstrdup(pool,attr_value->value); - } - else if(strcasecmp(attr_name->value,"max-connection-count") == 0) { - config->max_connection_count = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"force-destination") == 0) { - config->force_destination = atoi(attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"rtsp-ip") == 0) { + config->local_ip = unimrcp_server_ip_address_get(loader,elem); + } + else if(strcasecmp(elem->name,"rtsp-port") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->local_port = (apr_port_t)atol(cdata_text_get(elem)); } } - else if(strcasecmp(elem->name,"resourcemap") == 0) { - resource_map_load(config->resource_map,elem,pool); + else if(strcasecmp(elem->name,"sdp-origin") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->origin = cdata_copy(elem,loader->pool); + } } - } - return mrcp_unirtsp_server_agent_create(config,pool); -} - -/** Load signaling agents */ -static apt_bool_t unimrcp_server_signaling_agents_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) -{ - const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Signaling Agents"); - for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"agent") == 0) { - mrcp_sig_agent_t *sig_agent = NULL; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else if(strcasecmp(attr->name,"class") == 0) { - if(strcasecmp(attr->value,"SofiaSIP") == 0) { - sig_agent = unimrcp_server_sofiasip_agent_load(server,elem,pool); - } - else if(strcasecmp(attr->value,"UniRTSP") == 0) { - sig_agent = unimrcp_server_rtsp_agent_load(server,elem,pool); - } - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } + else if(strcasecmp(elem->name,"max-connection-count") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->max_connection_count = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"force-destination") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->force_destination = cdata_bool_get(elem); } - if(sig_agent) { - mrcp_server_signaling_agent_register(server,sig_agent,name); + } + else if(strcasecmp(elem->name,"resource-map") == 0) { + const apr_xml_attr *name_attr; + const apr_xml_attr *value_attr; + const apr_xml_elem *child_elem; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resource Map"); + for(child_elem = elem->first_child; child_elem; child_elem = child_elem->next) { + if(name_value_attribs_get(child_elem,&name_attr,&value_attr) == TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",name_attr->value,value_attr->value); + apr_table_set(config->resource_map,name_attr->value,value_attr->value); + } } } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } - return TRUE; + } + + if(!config->local_ip) { + /* use default ip address if not specified */ + config->local_ip = apr_pstrdup(loader->pool,loader->ip); + } + + agent = mrcp_unirtsp_server_agent_create(id,config,loader->pool); + return mrcp_server_signaling_agent_register(loader->server,agent); } /** Load MRCPv2 connection agent */ -static mrcp_connection_agent_t* unimrcp_server_connection_agent_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_server_mrcpv2_uas_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - char *mrcp_ip = DEFAULT_IP_ADDRESS; + mrcp_connection_agent_t *agent; + char *mrcp_ip = NULL; apr_port_t mrcp_port = DEFAULT_MRCP_PORT; apr_size_t max_connection_count = 100; apt_bool_t force_new_connection = FALSE; + apr_size_t rx_buffer_size = 0; + apr_size_t tx_buffer_size = 0; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv2 Agent"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv2 Agent <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"mrcp-ip") == 0) { - mrcp_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"mrcp-port") == 0) { - mrcp_port = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"max-connection-count") == 0) { - max_connection_count = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"force-new-connection") == 0) { - force_new_connection = atoi(attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"mrcp-ip") == 0) { + mrcp_ip = unimrcp_server_ip_address_get(loader,elem); + } + else if(strcasecmp(elem->name,"mrcp-port") == 0) { + if(is_cdata_valid(elem) == TRUE) { + mrcp_port = (apr_port_t)atol(cdata_text_get(elem)); } } - } - return mrcp_server_connection_agent_create(mrcp_ip,mrcp_port,max_connection_count,force_new_connection,pool); -} - -/** Load MRCPv2 conection agents */ -static apt_bool_t unimrcp_server_connection_agents_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) -{ - const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Connection Agents"); - for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"agent") == 0) { - mrcp_connection_agent_t *connection_agent; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } + else if(strcasecmp(elem->name,"max-connection-count") == 0) { + if(is_cdata_valid(elem) == TRUE) { + max_connection_count = atol(cdata_text_get(elem)); } - connection_agent = unimrcp_server_connection_agent_load(server,elem,pool); - if(connection_agent) { - mrcp_server_connection_agent_register(server,connection_agent,name); + } + else if(strcasecmp(elem->name,"force-new-connection") == 0) { + if(is_cdata_valid(elem) == TRUE) { + force_new_connection = cdata_bool_get(elem); + } + } + else if(strcasecmp(elem->name,"rx-buffer-size") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rx_buffer_size = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"tx-buffer-size") == 0) { + if(is_cdata_valid(elem) == TRUE) { + tx_buffer_size = atol(cdata_text_get(elem)); } } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } - return TRUE; -} + } -/** Load RTP termination factory */ -static mpf_termination_factory_t* unimrcp_server_rtp_factory_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) -{ - const apr_xml_elem *elem; - char *rtp_ip = DEFAULT_IP_ADDRESS; - char *rtp_ext_ip = NULL; - mpf_rtp_config_t *rtp_config = mpf_rtp_config_create(pool); - rtp_config->rtp_port_min = DEFAULT_RTP_PORT_MIN; - rtp_config->rtp_port_max = DEFAULT_RTP_PORT_MAX; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTP Termination Factory"); - for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"rtp-ip") == 0) { - rtp_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"rtp-ext-ip") == 0) { - rtp_ext_ip = ip_addr_get(attr_value->value,pool); - } - else if(strcasecmp(attr_name->value,"rtp-port-min") == 0) { - rtp_config->rtp_port_min = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtp-port-max") == 0) { - rtp_config->rtp_port_max = (apr_port_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"playout-delay") == 0) { - rtp_config->jb_config.initial_playout_delay = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"min-playout-delay") == 0) { - rtp_config->jb_config.min_playout_delay = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"max-playout-delay") == 0) { - rtp_config->jb_config.max_playout_delay = atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"codecs") == 0) { - const mpf_codec_manager_t *codec_manager = mrcp_server_codec_manager_get(server); - if(codec_manager) { - mpf_codec_manager_codec_list_load(codec_manager,&rtp_config->codec_list,attr_value->value,pool); - } - } - else if(strcasecmp(attr_name->value,"ptime") == 0) { - rtp_config->ptime = (apr_uint16_t)atol(attr_value->value); - } - else if(strcasecmp(attr_name->value,"own-preference") == 0) { - rtp_config->own_preferrence = atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp") == 0) { - rtp_config->rtcp = atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp-bye") == 0) { - rtp_config->rtcp_bye_policy = atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp-tx-interval") == 0) { - rtp_config->rtcp_tx_interval = (apr_uint16_t)atoi(attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtcp-rx-resolution") == 0) { - rtp_config->rtcp_rx_resolution = (apr_uint16_t)atol(attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } - } - } + if(!mrcp_ip) { + /* use default ip address if not specified */ + mrcp_ip = apr_pstrdup(loader->pool,loader->ip); } - apt_string_set(&rtp_config->ip,rtp_ip); - if(rtp_ext_ip) { - apt_string_set(&rtp_config->ext_ip,rtp_ext_ip); + + agent = mrcp_server_connection_agent_create(id,mrcp_ip,mrcp_port,max_connection_count,force_new_connection,loader->pool); + if(agent) { + if(rx_buffer_size) { + mrcp_server_connection_rx_size_set(agent,rx_buffer_size); + } + if(tx_buffer_size) { + mrcp_server_connection_tx_size_set(agent,tx_buffer_size); + } } - return mpf_rtp_termination_factory_create(rtp_config,pool); + return mrcp_server_connection_agent_register(loader->server,agent); } -/** Load media engines */ -static apt_bool_t unimrcp_server_media_engines_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) +/** Load media engine */ +static apt_bool_t unimrcp_server_media_engine_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; + mpf_engine_t *media_engine; + unsigned long realtime_rate = 1; - /* create codec manager first */ - mpf_codec_manager_t *codec_manager = mpf_engine_codec_manager_create(pool); - if(codec_manager) { - mrcp_server_codec_manager_register(server,codec_manager); - } - - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engines"); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engine <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"engine") == 0) { - mpf_engine_t *media_engine; - unsigned long realtime_rate = 1; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else if(strcasecmp(attr->name,"realtime-rate") == 0) { - realtime_rate = atol(attr->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } - } - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engine"); - media_engine = mpf_engine_create(pool); - if(media_engine) { - mpf_engine_scheduler_rate_set(media_engine,realtime_rate); - mrcp_server_media_engine_register(server,media_engine,name); - } - } - else if(strcasecmp(elem->name,"rtp") == 0) { - mpf_termination_factory_t *rtp_factory; - const char *name = NULL; - const apr_xml_attr *attr; - for(attr = elem->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } - } - rtp_factory = unimrcp_server_rtp_factory_load(server,elem,pool); - if(rtp_factory) { - mrcp_server_rtp_factory_register(server,rtp_factory,name); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"realtime-rate") == 0) { + if(is_cdata_valid(elem) == TRUE) { + realtime_rate = atol(cdata_text_get(elem)); } } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } - return TRUE; -} - -/** Load resource */ -static apt_bool_t unimrcp_server_resource_load(mrcp_server_t *server, mrcp_resource_loader_t *resource_loader, const apr_xml_elem *root, apr_pool_t *pool) -{ - apt_str_t resource_class; - apt_bool_t resource_enabled = TRUE; - const apr_xml_attr *attr; - apt_string_reset(&resource_class); - for(attr = root->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"class") == 0) { - apt_string_set(&resource_class,attr->value); - } - else if(strcasecmp(attr->name,"enable") == 0) { - resource_enabled = atoi(attr->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); - } } - - if(!resource_class.buf || !resource_enabled) { - return FALSE; + + media_engine = mpf_engine_create(id,loader->pool); + if(media_engine) { + mpf_engine_scheduler_rate_set(media_engine,realtime_rate); } - - return mrcp_resource_load(resource_loader,&resource_class); + return mrcp_server_media_engine_register(loader->server,media_engine); } -/** Load resources */ -static apt_bool_t unimrcp_server_resources_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) +/** Load RTP factory */ +static apt_bool_t unimrcp_server_rtp_factory_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) { const apr_xml_elem *elem; - mrcp_resource_factory_t *resource_factory; - mrcp_resource_loader_t *resource_loader = mrcp_resource_loader_create(FALSE,pool); - if(!resource_loader) { - return FALSE; - } + char *rtp_ip = NULL; + char *rtp_ext_ip = NULL; + mpf_termination_factory_t *rtp_factory; + mpf_rtp_config_t *rtp_config; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resources"); + rtp_config = mpf_rtp_config_alloc(loader->pool); + rtp_config->rtp_port_min = DEFAULT_RTP_PORT_MIN; + rtp_config->rtp_port_max = DEFAULT_RTP_PORT_MAX; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTP Factory <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"resource") == 0) { - unimrcp_server_resource_load(server,resource_loader,elem,pool); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"rtp-ip") == 0) { + rtp_ip = unimrcp_server_ip_address_get(loader,elem); + } + else if(strcasecmp(elem->name,"rtp-ext-ip") == 0) { + rtp_ext_ip = unimrcp_server_ip_address_get(loader,elem); + } + else if(strcasecmp(elem->name,"rtp-port-min") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtp_config->rtp_port_min = (apr_port_t)atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"rtp-port-max") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtp_config->rtp_port_max = (apr_port_t)atol(cdata_text_get(elem)); + } } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } - resource_factory = mrcp_resource_factory_get(resource_loader); - mrcp_server_resource_factory_register(server,resource_factory); - return TRUE; + if(rtp_ip) { + apt_string_set(&rtp_config->ip,rtp_ip); + } + else { + apt_string_set(&rtp_config->ip,loader->ip); + } + if(rtp_ext_ip) { + apt_string_set(&rtp_config->ext_ip,rtp_ext_ip); + } + else if(loader->ext_ip){ + apt_string_set(&rtp_config->ext_ip,loader->ext_ip); + } + + rtp_factory = mpf_rtp_termination_factory_create(rtp_config,loader->pool); + return mrcp_server_rtp_factory_register(loader->server,rtp_factory,id); } /** Load plugin */ -static apt_bool_t unimrcp_server_plugin_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_server_plugin_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root) { + mrcp_engine_t *engine; mrcp_engine_config_t *config; - const char *plugin_class = NULL; + const char *plugin_id = NULL; + const char *plugin_name = NULL; const char *plugin_ext = NULL; const char *plugin_path = NULL; apt_bool_t plugin_enabled = TRUE; const apr_xml_attr *attr; - config = mrcp_engine_config_alloc(pool); for(attr = root->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - config->name = apr_pstrdup(pool,attr->value); + if(strcasecmp(attr->name,"id") == 0) { + plugin_id = apr_pstrdup(loader->pool,attr->value); } - else if(strcasecmp(attr->name,"class") == 0) { - plugin_class = attr->value; + else if(strcasecmp(attr->name,"name") == 0) { + plugin_name = attr->value; } else if(strcasecmp(attr->name,"ext") == 0) { plugin_ext = attr->value; } else if(strcasecmp(attr->name,"enable") == 0) { - plugin_enabled = atoi(attr->value); - } - else if(strcasecmp(attr->name,"max-channel-count") == 0) { - config->max_channel_count = atol(attr->value); + plugin_enabled = is_attr_enabled(attr); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); } } - if(!plugin_class || !plugin_enabled) { + if(!plugin_id || !plugin_name) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Missing plugin id or name"); return FALSE; } - if(!plugin_dir_path) { - plugin_dir_path = DEFAULT_PLUGIN_DIR_PATH; + + if(!plugin_enabled) { + /* disabled plugin, just skip it */ + return TRUE; } + if(!plugin_ext) { plugin_ext = DEFAULT_PLUGIN_EXT; } - if(*plugin_dir_path == '\0') { - plugin_path = apr_psprintf(pool,"%s.%s",plugin_class,plugin_ext); + if(*loader->dir_layout->plugin_dir_path == '\0') { + plugin_path = apr_psprintf(loader->pool,"%s.%s", + plugin_name,plugin_ext); } else { - plugin_path = apr_psprintf(pool,"%s/%s.%s",plugin_dir_path,plugin_class,plugin_ext); + plugin_path = apr_psprintf(loader->pool,"%s/%s.%s", + loader->dir_layout->plugin_dir_path,plugin_name,plugin_ext); } - /* load optional name/value params */ + config = mrcp_engine_config_alloc(loader->pool); + + /* load optional named and generic name/value params */ if(root->first_child){ const apr_xml_attr *attr_name; const apr_xml_attr *attr_value; const apr_xml_elem *elem; apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Engine Params"); - config->params = apr_table_make(pool,1); + config->params = apr_table_make(loader->pool,1); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { + if(strcasecmp(elem->name,"max-channel-count") == 0) { + if(is_cdata_valid(elem) == TRUE) { + config->max_channel_count = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"param") == 0) { + if(name_value_attribs_get(elem,&attr_name,&attr_value) == TRUE) { apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); apr_table_set(config->params,attr_name->value,attr_value->value); } @@ -641,149 +642,520 @@ static apt_bool_t unimrcp_server_plugin_load(mrcp_server_t *server, const char * } } - return mrcp_server_plugin_register(server,plugin_path,config); + engine = mrcp_server_engine_load(loader->server,plugin_id,plugin_path,config); + return mrcp_server_engine_register(loader->server,engine); } -/** Load plugins */ -static apt_bool_t unimrcp_server_plugins_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_elem *root, apr_pool_t *pool) +/** Load plugin (engine) factory */ +static apt_bool_t unimrcp_server_plugin_factory_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root) { const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Engine Plugins"); + + if(!loader->dir_layout->plugin_dir_path) { + loader->dir_layout->plugin_dir_path = DEFAULT_PLUGIN_DIR_PATH; + } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Plugin Factory"); for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); if(strcasecmp(elem->name,"engine") == 0) { - unimrcp_server_plugin_load(server,plugin_dir_path,elem,pool); + unimrcp_server_plugin_load(loader,elem); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } - } + } return TRUE; } +/** Load jitter buffer settings */ +static apt_bool_t unimrcp_server_jb_settings_load(unimrcp_server_loader_t *loader, mpf_jb_config_t *jb, const apr_xml_elem *root) +{ + const apr_xml_elem *elem; -/** Load settings */ -static apt_bool_t unimrcp_server_settings_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_elem *root, apr_pool_t *pool) + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Jitter Buffer Settings"); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"playout-delay") == 0) { + if(is_cdata_valid(elem) == TRUE) { + jb->initial_playout_delay = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"min-playout-delay") == 0) { + if(is_cdata_valid(elem) == TRUE) { + jb->min_playout_delay = atol(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"max-playout-delay") == 0) { + if(is_cdata_valid(elem) == TRUE) { + jb->max_playout_delay = atol(cdata_text_get(elem)); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + return TRUE; +} + +/** Load RTCP settings */ +static apt_bool_t unimrcp_server_rtcp_settings_load(unimrcp_server_loader_t *loader, mpf_rtp_settings_t *rtcp_settings, const apr_xml_elem *root) { const apr_xml_elem *elem; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Settings"); + const apr_xml_attr *attr = NULL; + for(attr = root->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"enable") == 0) { + break; + } + } + + if(is_attr_enabled(attr) == FALSE) { + /* RTCP is disabled, skip the rest */ + return TRUE; + } + + rtcp_settings->rtcp = TRUE; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTCP Settings"); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"rtcp-bye") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtcp_settings->rtcp_bye_policy = atoi(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"tx-interval") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtcp_settings->rtcp_tx_interval = (apr_uint16_t)atoi(cdata_text_get(elem)); + } + } + else if(strcasecmp(elem->name,"rx-resolution") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtcp_settings->rtcp_rx_resolution = (apr_uint16_t)atol(cdata_text_get(elem)); + } + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + return TRUE; +} + +/** Load RTP settings */ +static apt_bool_t unimrcp_server_rtp_settings_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) +{ + const apr_xml_elem *elem; + mpf_rtp_settings_t *rtp_settings = mpf_rtp_settings_alloc(loader->pool); + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTP Settings <%s>",id); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"signaling") == 0) { - unimrcp_server_signaling_agents_load(server,elem,pool); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"jitter-buffer") == 0) { + unimrcp_server_jb_settings_load(loader,&rtp_settings->jb_config,elem); } - else if(strcasecmp(elem->name,"connection") == 0) { - unimrcp_server_connection_agents_load(server,elem,pool); + else if(strcasecmp(elem->name,"ptime") == 0) { + if(is_cdata_valid(elem) == TRUE) { + rtp_settings->ptime = (apr_uint16_t)atol(cdata_text_get(elem)); + } } - else if(strcasecmp(elem->name,"media") == 0) { - unimrcp_server_media_engines_load(server,elem,pool); + else if(strcasecmp(elem->name,"codecs") == 0) { + const apr_xml_attr *attr; + const mpf_codec_manager_t *codec_manager = mrcp_server_codec_manager_get(loader->server); + if(is_cdata_valid(elem) == TRUE && codec_manager) { + mpf_codec_manager_codec_list_load( + codec_manager, + &rtp_settings->codec_list, + cdata_text_get(elem), + loader->pool); + } + for(attr = elem->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"own-preference") == 0) { + rtp_settings->own_preferrence = is_attr_enabled(attr); + break; + } + } } - else if(strcasecmp(elem->name,"plugin") == 0) { - unimrcp_server_plugins_load(server,plugin_dir_path,elem,pool); + else if(strcasecmp(elem->name,"rtcp") == 0) { + unimrcp_server_rtcp_settings_load(loader,rtp_settings,elem); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } - return TRUE; + + return mrcp_server_rtp_settings_register(loader->server,rtp_settings,id); +} + +/** Load map of resources and engines */ +static apr_table_t* resource_engine_map_load(const apr_xml_elem *root, apr_pool_t *pool) +{ + const apr_xml_attr *attr_name; + const apr_xml_attr *attr_value; + const apr_xml_elem *elem; + apr_table_t *plugin_map = apr_table_make(pool,2); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Plugin Map"); + for(elem = root->first_child; elem; elem = elem->next) { + if(strcasecmp(elem->name,"param") == 0) { + if(name_value_attribs_get(elem,&attr_name,&attr_value) == TRUE) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value); + apr_table_set(plugin_map,attr_name->value,attr_value->value); + } + } + } + return plugin_map; +} + +/** Load MRCPv2 profile */ +static apt_bool_t unimrcp_server_mrcpv2_profile_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) +{ + const apr_xml_elem *elem; + mrcp_profile_t *profile; + mrcp_sig_agent_t *sip_agent = NULL; + mrcp_connection_agent_t *mrcpv2_agent = NULL; + mpf_engine_t *media_engine = NULL; + mpf_termination_factory_t *rtp_factory = NULL; + mpf_rtp_settings_t *rtp_settings = NULL; + apr_table_t *resource_engine_map = NULL; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv2 Profile <%s>",id); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + + if(is_cdata_valid(elem) == FALSE) { + continue; + } + + if(strcasecmp(elem->name,"sip-uas") == 0) { + sip_agent = mrcp_server_signaling_agent_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"mrcpv2-uas") == 0) { + mrcpv2_agent = mrcp_server_connection_agent_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"media-engine") == 0) { + media_engine = mrcp_server_media_engine_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtp-factory") == 0) { + rtp_factory = mrcp_server_rtp_factory_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtp-settings") == 0) { + rtp_settings = mrcp_server_rtp_settings_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"resource-engine-map") == 0) { + resource_engine_map = resource_engine_map_load(elem,loader->pool); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv2 Profile [%s]",id); + profile = mrcp_server_profile_create( + id, + NULL, + sip_agent, + mrcpv2_agent, + media_engine, + rtp_factory, + rtp_settings, + loader->pool); + return mrcp_server_profile_register(loader->server,profile,resource_engine_map); } -/** Load profile */ -static apt_bool_t unimrcp_server_profile_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) +/** Load MRCPv1 profile */ +static apt_bool_t unimrcp_server_mrcpv1_profile_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root, const char *id) { - const char *name = NULL; + const apr_xml_elem *elem; mrcp_profile_t *profile; - mrcp_sig_agent_t *sig_agent = NULL; - mrcp_connection_agent_t *cnt_agent = NULL; + mrcp_sig_agent_t *rtsp_agent = NULL; mpf_engine_t *media_engine = NULL; mpf_termination_factory_t *rtp_factory = NULL; - apr_table_t *plugin_map = NULL; + mpf_rtp_settings_t *rtp_settings = NULL; + apr_table_t *resource_engine_map = NULL; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv1 Profile <%s>",id); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + + if(is_cdata_valid(elem) == FALSE) { + continue; + } + + if(strcasecmp(elem->name,"rtsp-uas") == 0) { + rtsp_agent = mrcp_server_signaling_agent_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"media-engine") == 0) { + media_engine = mrcp_server_media_engine_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtp-factory") == 0) { + rtp_factory = mrcp_server_rtp_factory_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"rtp-settings") == 0) { + rtp_settings = mrcp_server_rtp_settings_get(loader->server,cdata_text_get(elem)); + } + else if(strcasecmp(elem->name,"resource-engine-map") == 0) { + resource_engine_map = resource_engine_map_load(elem,loader->pool); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create MRCPv1 Profile [%s]",id); + profile = mrcp_server_profile_create( + id, + NULL, + rtsp_agent, + NULL, + media_engine, + rtp_factory, + rtp_settings, + loader->pool); + return mrcp_server_profile_register(loader->server,profile,resource_engine_map); +} + + +/** Load properties */ +static apt_bool_t unimrcp_server_properties_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root) +{ const apr_xml_elem *elem; - const apr_xml_attr *attr; - for(attr = root->attr; attr; attr = attr->next) { - if(strcasecmp(attr->name,"name") == 0) { - name = apr_pstrdup(pool,attr->value); - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Profile [%s]",name); + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Properties"); + for(elem = root->first_child; elem; elem = elem->next) { + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Element <%s>",elem->name); + if(strcasecmp(elem->name,"ip") == 0) { + loader->ip = unimrcp_server_ip_address_get(loader,elem); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set Property ip:%s",loader->ip); + } + else if(strcasecmp(elem->name,"ext-ip") == 0) { + loader->ext_ip = unimrcp_server_ip_address_get(loader,elem); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set Property ext-ip:%s",loader->ext_ip); } else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } - if(!name) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Load Profile: no profile name specified"); - return FALSE; + return TRUE; +} + +/** Load components */ +static apt_bool_t unimrcp_server_components_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root) +{ + const apr_xml_elem *elem; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + const char *id; + + /* Create codec manager first (probably it should be loaded from config either) */ + mpf_codec_manager_t *codec_manager = mpf_engine_codec_manager_create(loader->pool); + if(codec_manager) { + mrcp_server_codec_manager_register(loader->server,codec_manager); } + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Components"); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"param") == 0) { - const apr_xml_attr *attr_name; - const apr_xml_attr *attr_value; - if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Loading Profile %s [%s]",attr_name->value,attr_value->value); - if(strcasecmp(attr_name->value,"signaling-agent") == 0) { - sig_agent = mrcp_server_signaling_agent_get(server,attr_value->value); - } - else if(strcasecmp(attr_name->value,"connection-agent") == 0) { - cnt_agent = mrcp_server_connection_agent_get(server,attr_value->value); - } - else if(strcasecmp(attr_name->value,"media-engine") == 0) { - media_engine = mrcp_server_media_engine_get(server,attr_value->value); - } - else if(strcasecmp(attr_name->value,"rtp-factory") == 0) { - rtp_factory = mrcp_server_rtp_factory_get(server,attr_value->value); - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value); - } - } + if(strcasecmp(elem->name,"resource-factory") == 0) { + unimrcp_server_resource_factory_load(loader,elem); + continue; + } + if(strcasecmp(elem->name,"plugin-factory") == 0) { + unimrcp_server_plugin_factory_load(loader,elem); + continue; + } + + /* get common "id" and "enable" attributes */ + if(header_attribs_get(elem,&id_attr,&enable_attr) == FALSE) { + /* invalid id */ + continue; + } + if(is_attr_enabled(enable_attr) == FALSE) { + /* disabled element, just skip it */ + continue; + } + id = apr_pstrdup(loader->pool,id_attr->value); + + if(strcasecmp(elem->name,"sip-uas") == 0) { + unimrcp_server_sip_uas_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"rtsp-uas") == 0) { + unimrcp_server_rtsp_uas_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"mrcpv2-uas") == 0) { + unimrcp_server_mrcpv2_uas_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"media-engine") == 0) { + unimrcp_server_media_engine_load(loader,elem,id); } - else if(strcasecmp(elem->name,"pluginmap") == 0) { - plugin_map = apr_table_make(pool,2); - plugin_map_load(plugin_map,elem,pool); + else if(strcasecmp(elem->name,"rtp-factory") == 0) { + unimrcp_server_rtp_factory_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"plugin-factory") == 0) { + unimrcp_server_plugin_factory_load(loader,elem); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } + return TRUE; +} + +/** Load settings */ +static apt_bool_t unimrcp_server_settings_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root) +{ + const apr_xml_elem *elem; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + const char *id; + + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Settings"); + for(elem = root->first_child; elem; elem = elem->next) { + /* get common "id" and "enable" attributes */ + if(header_attribs_get(elem,&id_attr,&enable_attr) == FALSE) { + /* invalid id */ + continue; + } + if(is_attr_enabled(enable_attr) == FALSE) { + /* disabled element, just skip it */ + continue; + } + id = apr_pstrdup(loader->pool,id_attr->value); - apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create Profile [%s]",name); - profile = mrcp_server_profile_create(NULL,sig_agent,cnt_agent,media_engine,rtp_factory,pool); - return mrcp_server_profile_register(server,profile,plugin_map,name); + if(strcasecmp(elem->name,"rtp-settings") == 0) { + unimrcp_server_rtp_settings_load(loader,elem,id); + } + else { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); + } + } + return TRUE; } /** Load profiles */ -static apt_bool_t unimrcp_server_profiles_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool) +static apt_bool_t unimrcp_server_profiles_load(unimrcp_server_loader_t *loader, const apr_xml_elem *root) { const apr_xml_elem *elem; + const apr_xml_attr *id_attr; + const apr_xml_attr *enable_attr; + const char *id; + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Profiles"); for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"profile") == 0) { - unimrcp_server_profile_load(server,elem,pool); + /* get common "id" and "enable" attributes */ + if(header_attribs_get(elem,&id_attr,&enable_attr) == FALSE) { + /* invalid id */ + continue; + } + if(is_attr_enabled(enable_attr) == FALSE) { + /* disabled element, just skip it */ + continue; + } + id = apr_pstrdup(loader->pool,id_attr->value); + + if(strcasecmp(elem->name,"mrcpv2-profile") == 0) { + unimrcp_server_mrcpv2_profile_load(loader,elem,id); + } + else if(strcasecmp(elem->name,"mrcpv1-profile") == 0) { + unimrcp_server_mrcpv1_profile_load(loader,elem,id); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } + } + return TRUE; +} + +/** Parse XML document */ +static apr_xml_doc* unimrcp_server_doc_parse(const char *file_path, apr_pool_t *pool) +{ + apr_xml_parser *parser = NULL; + apr_xml_doc *xml_doc = NULL; + apr_file_t *fd = NULL; + apr_status_t rv; + + apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Open Config File [%s]",file_path); + rv = apr_file_open(&fd,file_path,APR_READ|APR_BINARY,0,pool); + if(rv != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Config File [%s]",file_path); + return NULL; + } + + rv = apr_xml_parse_file(pool,&parser,&xml_doc,fd,XML_FILE_BUFFER_LENGTH); + if(rv != APR_SUCCESS) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse Config File [%s]",file_path); + xml_doc = NULL; } - return TRUE; + + apr_file_close(fd); + return xml_doc; } -/** Load configuration (settings and profiles) */ -static apt_bool_t unimrcp_server_config_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_doc *doc, apr_pool_t *pool) +static apt_bool_t unimrcp_server_load(mrcp_server_t *mrcp_server, apt_dir_layout_t *dir_layout, apr_pool_t *pool) { + const char *file_path; + apr_xml_doc *doc; const apr_xml_elem *elem; - const apr_xml_elem *root = doc->root; + const apr_xml_elem *root; + const apr_xml_attr *attr; + unimrcp_server_loader_t *loader; + const char *version = NULL; + + file_path = apt_confdir_filepath_get(dir_layout,CONF_FILE_NAME,pool); + if(!file_path) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Get Path to Conf File [%s]",CONF_FILE_NAME); + return FALSE; + } + + /* Parse XML document */ + doc = unimrcp_server_doc_parse(file_path,pool); + if(!doc) { + return FALSE; + } + + root = doc->root; + + /* Match document name */ if(!root || strcasecmp(root->name,"unimrcpserver") != 0) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document"); + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document <%s>",root->name); return FALSE; } + + /* Read attributes */ + for(attr = root->attr; attr; attr = attr->next) { + if(strcasecmp(attr->name,"version") == 0) { + version = attr->value; + } + } + + /* Check version number first */ + if(!version) { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Version"); + return FALSE; + } + + loader = apr_palloc(pool,sizeof(unimrcp_server_loader_t)); + loader->doc = doc; + loader->server = mrcp_server; + loader->dir_layout = dir_layout; + loader->pool = pool; + loader->ip = DEFAULT_IP_ADDRESS; + loader->ext_ip = NULL; + loader->auto_ip = NULL; + + /* Navigate through document */ for(elem = root->first_child; elem; elem = elem->next) { - if(strcasecmp(elem->name,"resources") == 0) { - unimrcp_server_resources_load(server,elem,pool); + if(strcasecmp(elem->name,"properties") == 0) { + unimrcp_server_properties_load(loader,elem); + } + else if(strcasecmp(elem->name,"components") == 0) { + unimrcp_server_components_load(loader,elem); } else if(strcasecmp(elem->name,"settings") == 0) { - unimrcp_server_settings_load(server,plugin_dir_path,elem,pool); + unimrcp_server_settings_load(loader,elem); } else if(strcasecmp(elem->name,"profiles") == 0) { - unimrcp_server_profiles_load(server,elem,pool); + unimrcp_server_profiles_load(loader,elem); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } - return TRUE; } diff --git a/libs/unimrcp/platforms/umc/Makefile.am b/libs/unimrcp/platforms/umc/Makefile.am index 9e450119c8..a33ddfdd0f 100644 --- a/libs/unimrcp/platforms/umc/Makefile.am +++ b/libs/unimrcp/platforms/umc/Makefile.am @@ -28,7 +28,10 @@ umc_SOURCES = src/main.cpp \ src/dtmfscenario.cpp \ src/dtmfsession.cpp \ src/setparamscenario.cpp \ - src/setparamsession.cpp + src/setparamsession.cpp \ + src/verifierscenario.cpp \ + src/verifiersession.cpp + umc_LDADD = $(top_builddir)/platforms/libunimrcp-client/libunimrcpclient.la if ISMAC diff --git a/libs/unimrcp/platforms/umc/include/dtmfscenario.h b/libs/unimrcp/platforms/umc/include/dtmfscenario.h index 63aab623c4..45a5430cf7 100644 --- a/libs/unimrcp/platforms/umc/include/dtmfscenario.h +++ b/libs/unimrcp/platforms/umc/include/dtmfscenario.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: dtmfscenario.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __DTMF_SCENARIO_H__ -#define __DTMF_SCENARIO_H__ +#ifndef DTMF_SCENARIO_H +#define DTMF_SCENARIO_H /** * @file dtmfscenario.h @@ -72,4 +74,4 @@ inline const char* DtmfScenario::GetDigits() const } -#endif /*__DTMF_SCENARIO_H__*/ +#endif /* DTMF_SCENARIO_H */ diff --git a/libs/unimrcp/platforms/umc/include/dtmfsession.h b/libs/unimrcp/platforms/umc/include/dtmfsession.h index 2bf21bc50c..e0a3f7ccd0 100644 --- a/libs/unimrcp/platforms/umc/include/dtmfsession.h +++ b/libs/unimrcp/platforms/umc/include/dtmfsession.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: dtmfsession.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __DTMF_SESSION_H__ -#define __DTMF_SESSION_H__ +#ifndef DTMF_SESSION_H +#define DTMF_SESSION_H /** * @file dtmfsession.h @@ -65,4 +67,4 @@ inline const DtmfScenario* DtmfSession::GetScenario() const return (DtmfScenario*)m_pScenario; } -#endif /*__DTMF_SESSION_H__*/ +#endif /* DTMF_SESSION_H */ diff --git a/libs/unimrcp/platforms/umc/include/recogscenario.h b/libs/unimrcp/platforms/umc/include/recogscenario.h index 1be4d739a9..fc20c10757 100644 --- a/libs/unimrcp/platforms/umc/include/recogscenario.h +++ b/libs/unimrcp/platforms/umc/include/recogscenario.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recogscenario.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __RECOG_SCENARIO_H__ -#define __RECOG_SCENARIO_H__ +#ifndef RECOG_SCENARIO_H +#define RECOG_SCENARIO_H /** * @file recogscenario.h @@ -85,4 +87,4 @@ inline bool RecogScenario::IsRecognizeEnabled() const return m_Recognize; } -#endif /*__RECOG_SCENARIO_H__*/ +#endif /* RECOG_SCENARIO_H */ diff --git a/libs/unimrcp/platforms/umc/include/recogsession.h b/libs/unimrcp/platforms/umc/include/recogsession.h index bca9f553e9..5cc44404e0 100644 --- a/libs/unimrcp/platforms/umc/include/recogsession.h +++ b/libs/unimrcp/platforms/umc/include/recogsession.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recogsession.h 1587 2010-03-12 19:40:02Z achaloyan $ */ -#ifndef __RECOG_SESSION_H__ -#define __RECOG_SESSION_H__ +#ifndef RECOG_SESSION_H +#define RECOG_SESSION_H /** * @file recogsession.h @@ -37,6 +39,7 @@ public: protected: /* ============================ MANIPULATORS =============================== */ virtual bool Start(); + virtual bool Stop(); RecogChannel* CreateRecogChannel(); bool StartRecognition(mrcp_channel_t* pMrcpChannel); @@ -69,4 +72,4 @@ inline const RecogScenario* RecogSession::GetScenario() const return (RecogScenario*)m_pScenario; } -#endif /*__RECOG_SESSION_H__*/ +#endif /* RECOG_SESSION_H */ diff --git a/libs/unimrcp/platforms/umc/include/recorderscenario.h b/libs/unimrcp/platforms/umc/include/recorderscenario.h index 9648fd3f2b..cc27b0a1e7 100644 --- a/libs/unimrcp/platforms/umc/include/recorderscenario.h +++ b/libs/unimrcp/platforms/umc/include/recorderscenario.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recorderscenario.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __RECORDER_SCENARIO_H__ -#define __RECORDER_SCENARIO_H__ +#ifndef RECORDER_SCENARIO_H +#define RECORDER_SCENARIO_H /** * @file recorderscenario.h @@ -63,4 +65,4 @@ inline bool RecorderScenario::IsRecordEnabled() const return m_Record; } -#endif /*__RECORDER_SCENARIO_H__*/ +#endif /* RECORDER_SCENARIO_H */ diff --git a/libs/unimrcp/platforms/umc/include/recordersession.h b/libs/unimrcp/platforms/umc/include/recordersession.h index d2497cd3e1..4f4200ef1c 100644 --- a/libs/unimrcp/platforms/umc/include/recordersession.h +++ b/libs/unimrcp/platforms/umc/include/recordersession.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recordersession.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __RECORDER_SESSION_H__ -#define __RECORDER_SESSION_H__ +#ifndef RECORDER_SESSION_H +#define RECORDER_SESSION_H /** * @file recordersession.h @@ -65,4 +67,4 @@ inline const RecorderScenario* RecorderSession::GetScenario() const return (RecorderScenario*)m_pScenario; } -#endif /*__RECORDER_SESSION_H__*/ +#endif /* RECORDER_SESSION_H */ diff --git a/libs/unimrcp/platforms/umc/include/setparamscenario.h b/libs/unimrcp/platforms/umc/include/setparamscenario.h index 3cbdf6a43f..75df62c6b2 100644 --- a/libs/unimrcp/platforms/umc/include/setparamscenario.h +++ b/libs/unimrcp/platforms/umc/include/setparamscenario.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: setparamscenario.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __SETPARAM_SCENARIO_H__ -#define __SETPARAM_SCENARIO_H__ +#ifndef SETPARAM_SCENARIO_H +#define SETPARAM_SCENARIO_H /** * @file setaparamscenario.h @@ -44,4 +46,4 @@ protected: /* ============================ INLINE METHODS ============================= */ -#endif /*__SETPARAM_SCENARIO_H__*/ +#endif /* SETPARAM_SCENARIO_H */ diff --git a/libs/unimrcp/platforms/umc/include/setparamsession.h b/libs/unimrcp/platforms/umc/include/setparamsession.h index e7fb24bb33..916a86ee40 100644 --- a/libs/unimrcp/platforms/umc/include/setparamsession.h +++ b/libs/unimrcp/platforms/umc/include/setparamsession.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: setparamsession.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __SETPARAM_SESSION_H__ -#define __SETPARAM_SESSION_H__ +#ifndef SETPARAM_SESSION_H +#define SETPARAM_SESSION_H /** * @file setparamsession.h @@ -73,4 +75,4 @@ inline const SetParamScenario* SetParamSession::GetScenario() const return (SetParamScenario*)m_pScenario; } -#endif /*__SETPARAM_SESSION_H__*/ +#endif /* SETPARAM_SESSION_H */ diff --git a/libs/unimrcp/platforms/umc/include/synthscenario.h b/libs/unimrcp/platforms/umc/include/synthscenario.h index fd5aa9557e..921a857905 100644 --- a/libs/unimrcp/platforms/umc/include/synthscenario.h +++ b/libs/unimrcp/platforms/umc/include/synthscenario.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: synthscenario.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __SYNTH_SCENARIO_H__ -#define __SYNTH_SCENARIO_H__ +#ifndef SYNTH_SCENARIO_H +#define SYNTH_SCENARIO_H /** * @file synthscenario.h @@ -71,4 +73,4 @@ inline bool SynthScenario::IsSpeakEnabled() const return m_Speak; } -#endif /*__SYNTH_SCENARIO_H__*/ +#endif /* SYNTH_SCENARIO_H */ diff --git a/libs/unimrcp/platforms/umc/include/synthsession.h b/libs/unimrcp/platforms/umc/include/synthsession.h index 59f88711c6..94a592c86d 100644 --- a/libs/unimrcp/platforms/umc/include/synthsession.h +++ b/libs/unimrcp/platforms/umc/include/synthsession.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: synthsession.h 1586 2010-03-12 19:39:02Z achaloyan $ */ -#ifndef __SYNTH_SESSION_H__ -#define __SYNTH_SESSION_H__ +#ifndef SYNTH_SESSION_H +#define SYNTH_SESSION_H /** * @file synthsession.h @@ -37,6 +39,7 @@ public: protected: /* ============================ MANIPULATORS =============================== */ virtual bool Start(); + virtual bool Stop(); SynthChannel* CreateSynthChannel(); @@ -50,7 +53,7 @@ protected: /* ============================ ACCESSORS ================================== */ const SynthScenario* GetScenario() const; - + private: /* ============================ DATA ======================================= */ SynthChannel* m_pSynthChannel; @@ -63,4 +66,4 @@ inline const SynthScenario* SynthSession::GetScenario() const return (SynthScenario*)m_pScenario; } -#endif /*__SYNTH_SESSION_H__*/ +#endif /* SYNTH_SESSION_H */ diff --git a/libs/unimrcp/platforms/umc/include/umcconsole.h b/libs/unimrcp/platforms/umc/include/umcconsole.h index c8bd7c6d64..23bf6b1882 100644 --- a/libs/unimrcp/platforms/umc/include/umcconsole.h +++ b/libs/unimrcp/platforms/umc/include/umcconsole.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcconsole.h 1525 2010-02-16 14:58:56Z achaloyan $ */ -#ifndef __UMC_CONSOLE_H__ -#define __UMC_CONSOLE_H__ +#ifndef UMC_CONSOLE_H +#define UMC_CONSOLE_H /** * @file umcconsole.h @@ -47,12 +49,12 @@ private: struct UmcOptions { const char* m_RootDirPath; - apt_log_priority_e m_LogPriority; - apt_log_output_e m_LogOutput; + const char* m_LogPriority; + const char* m_LogOutput; }; UmcOptions m_Options; UmcFramework* m_pFramework; }; -#endif /*__UMC_CONSOLE_H__*/ +#endif /* UMC_CONSOLE_H */ diff --git a/libs/unimrcp/platforms/umc/include/umcframework.h b/libs/unimrcp/platforms/umc/include/umcframework.h index 34b3dcc933..ef803cb184 100644 --- a/libs/unimrcp/platforms/umc/include/umcframework.h +++ b/libs/unimrcp/platforms/umc/include/umcframework.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcframework.h 1585 2010-03-12 19:12:05Z achaloyan $ */ -#ifndef __UMC_FRAMEWORK_H__ -#define __UMC_FRAMEWORK_H__ +#ifndef UMC_FRAMEWORK_H +#define UMC_FRAMEWORK_H /** * @file umcframework.h @@ -42,6 +44,7 @@ public: void Destroy(); void RunSession(const char* pScenarioName, const char* pProfileName); + void StopSession(const char* id); void KillSession(const char* id); void ShowScenarios(); @@ -61,6 +64,7 @@ protected: void DestroyScenarios(); bool ProcessRunRequest(const char* pScenarioName, const char* pProfileName); + void ProcessStopRequest(const char* id); void ProcessKillRequest(const char* id); void ProcessShowScenarios(); void ProcessShowSessions(); @@ -89,4 +93,4 @@ private: apr_hash_t* m_pSessionTable; }; -#endif /*__UMC_FRAMEWORK_H__*/ +#endif /* UMC_FRAMEWORK_H */ diff --git a/libs/unimrcp/platforms/umc/include/umcscenario.h b/libs/unimrcp/platforms/umc/include/umcscenario.h index 712eb666cc..2425fc968e 100644 --- a/libs/unimrcp/platforms/umc/include/umcscenario.h +++ b/libs/unimrcp/platforms/umc/include/umcscenario.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcscenario.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __UMC_SCENARIO_H__ -#define __UMC_SCENARIO_H__ +#ifndef UMC_SCENARIO_H +#define UMC_SCENARIO_H /** * @file umcscenario.h @@ -117,4 +119,4 @@ inline bool UmcScenario::IsDiscoveryEnabled() const } -#endif /*__UMC_SCENARIO_H__*/ +#endif /* UMC_SCENARIO_H */ diff --git a/libs/unimrcp/platforms/umc/include/umcsession.h b/libs/unimrcp/platforms/umc/include/umcsession.h index 2c2f729aec..308e1704ff 100644 --- a/libs/unimrcp/platforms/umc/include/umcsession.h +++ b/libs/unimrcp/platforms/umc/include/umcsession.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcsession.h 1585 2010-03-12 19:12:05Z achaloyan $ */ -#ifndef __UMC_SESSION_H__ -#define __UMC_SESSION_H__ +#ifndef UMC_SESSION_H +#define UMC_SESSION_H /** * @file umcsession.h @@ -35,6 +37,7 @@ public: /* ============================ MANIPULATORS =============================== */ virtual bool Run(); + virtual bool Stop(); virtual bool Terminate(); void SetMrcpProfile(const char* pMrcpProfile); @@ -82,6 +85,7 @@ protected: /* ============================ ACCESSORS ================================== */ apr_pool_t* GetSessionPool() const; const char* GetMrcpSessionId() const; + mrcp_message_t* GetMrcpMessage() const; /* ============================ DATA ======================================= */ const UmcScenario* m_pScenario; @@ -92,6 +96,7 @@ private: /* ============================ DATA ======================================= */ mrcp_application_t* m_pMrcpApplication; mrcp_session_t* m_pMrcpSession; + mrcp_message_t* m_pMrcpMessage; /* last message sent */ bool m_Running; bool m_Terminating; }; @@ -118,4 +123,9 @@ inline void UmcSession::SetMrcpProfile(const char* pMrcpProfile) m_pMrcpProfile = pMrcpProfile; } -#endif /*__UMC_SESSION_H__*/ +inline mrcp_message_t* UmcSession::GetMrcpMessage() const +{ + return m_pMrcpMessage; +} + +#endif /* UMC_SESSION_H */ diff --git a/libs/unimrcp/platforms/umc/include/verifierscenario.h b/libs/unimrcp/platforms/umc/include/verifierscenario.h new file mode 100644 index 0000000000..52856b077a --- /dev/null +++ b/libs/unimrcp/platforms/umc/include/verifierscenario.h @@ -0,0 +1,75 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: verifierscenario.h 1775 2010-08-26 18:23:38Z achaloyan $ + */ + +#ifndef VERIFIER_SCENARIO_H +#define VERIFIER_SCENARIO_H + +/** + * @file verifierscenario.h + * @brief Verifier Scenario + */ + +#include "umcscenario.h" + +class VerifierScenario : public UmcScenario +{ +public: +/* ============================ CREATORS =================================== */ + VerifierScenario(); + virtual ~VerifierScenario(); + +/* ============================ MANIPULATORS =============================== */ + virtual void Destroy(); + + virtual UmcSession* CreateSession(); + +/* ============================ ACCESSORS ================================== */ + const char* GetRepositoryURI() const; + const char* GetVerificationMode() const; + const char* GetVoiceprintIdentifier() const; + +/* ============================ INQUIRIES ================================== */ +protected: +/* ============================ MANIPULATORS =============================== */ + virtual bool LoadElement(const apr_xml_elem* pElem, apr_pool_t* pool); + + bool LoadVerify(const apr_xml_elem* pElem, apr_pool_t* pool); + +/* ============================ DATA ======================================= */ + const char* m_RepositoryURI; + const char* m_VerificationMode; + const char* m_VoiceprintIdentifier; +}; + +/* ============================ INLINE METHODS ============================= */ +inline const char* VerifierScenario::GetRepositoryURI() const +{ + return m_RepositoryURI; +} + +inline const char* VerifierScenario::GetVerificationMode() const +{ + return m_VerificationMode; +} + +inline const char* VerifierScenario::GetVoiceprintIdentifier() const +{ + return m_VoiceprintIdentifier; +} + +#endif /* VERIFIER_SCENARIO_H */ diff --git a/libs/unimrcp/platforms/umc/include/verifiersession.h b/libs/unimrcp/platforms/umc/include/verifiersession.h new file mode 100644 index 0000000000..856a889f91 --- /dev/null +++ b/libs/unimrcp/platforms/umc/include/verifiersession.h @@ -0,0 +1,74 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: verifiersession.h 1776 2010-08-27 16:36:38Z achaloyan $ + */ + +#ifndef VERIFIER_SESSION_H +#define VERIFIER_SESSION_H + +/** + * @file verifiersession.h + * @brief Verifier Session + */ + +#include "umcsession.h" + +class VerifierScenario; +struct VerifierChannel; + +class VerifierSession : public UmcSession +{ +public: +/* ============================ CREATORS =================================== */ + VerifierSession(const VerifierScenario* pScenario); + virtual ~VerifierSession(); + +protected: +/* ============================ MANIPULATORS =============================== */ + virtual bool Start(); + virtual bool Stop(); + + VerifierChannel* CreateVerifierChannel(); + bool StartVerification(mrcp_channel_t* pMrcpChannel); + + mrcp_message_t* CreateStartSessionRequest(mrcp_channel_t* pMrcpChannel); + mrcp_message_t* CreateEndSessionRequest(mrcp_channel_t* pMrcpChannel); + mrcp_message_t* CreateVerificationRequest(mrcp_channel_t* pMrcpChannel); + + FILE* GetAudioIn(const mpf_codec_descriptor_t* pDescriptor, apr_pool_t* pool) const; + +/* ============================ HANDLERS =================================== */ + virtual bool OnSessionTerminate(mrcp_sig_status_code_e status); + virtual bool OnChannelAdd(mrcp_channel_t* channel, mrcp_sig_status_code_e status); + virtual bool OnMessageReceive(mrcp_channel_t* channel, mrcp_message_t* message); + +/* ============================ ACCESSORS ================================== */ + const VerifierScenario* GetScenario() const; + +private: +/* ============================ DATA ======================================= */ + VerifierChannel* m_pVerifierChannel; + const char* m_ContentId; +}; + + +/* ============================ INLINE METHODS ============================= */ +inline const VerifierScenario* VerifierSession::GetScenario() const +{ + return (VerifierScenario*)m_pScenario; +} + +#endif /* VERIFIER_SESSION_H */ diff --git a/libs/unimrcp/platforms/umc/src/dtmfscenario.cpp b/libs/unimrcp/platforms/umc/src/dtmfscenario.cpp index ca644b382c..d61b528071 100644 --- a/libs/unimrcp/platforms/umc/src/dtmfscenario.cpp +++ b/libs/unimrcp/platforms/umc/src/dtmfscenario.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: dtmfscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/platforms/umc/src/dtmfsession.cpp b/libs/unimrcp/platforms/umc/src/dtmfsession.cpp index 83a2ee5ec2..8ce8f9767f 100644 --- a/libs/unimrcp/platforms/umc/src/dtmfsession.cpp +++ b/libs/unimrcp/platforms/umc/src/dtmfsession.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: dtmfsession.cpp 1780 2010-09-01 05:59:32Z achaloyan $ */ #include "dtmfsession.h" @@ -30,8 +32,6 @@ struct RecogChannel mrcp_channel_t* m_pMrcpChannel; /** DTMF generator */ mpf_dtmf_generator_t* m_pDtmfGenerator; - /** Audio stream */ - mpf_audio_stream_t* m_pStream; /** Streaming is in-progress */ bool m_Streaming; }; @@ -79,13 +79,6 @@ bool DtmfSession::OnSessionTerminate(mrcp_sig_status_code_e status) return UmcSession::OnSessionTerminate(status); } -static apt_bool_t OpenStream(mpf_audio_stream_t* pStream, mpf_codec_t *codec) -{ - RecogChannel* pRecogChannel = (RecogChannel*) pStream->obj; - pRecogChannel->m_pStream = pStream; - return TRUE; -} - static apt_bool_t ReadStream(mpf_audio_stream_t* pStream, mpf_frame_t* pFrame) { RecogChannel* pRecogChannel = (RecogChannel*) pStream->obj; @@ -110,7 +103,6 @@ RecogChannel* DtmfSession::CreateRecogChannel() RecogChannel *pRecogChannel = new RecogChannel; pRecogChannel->m_pMrcpChannel = NULL; pRecogChannel->m_pDtmfGenerator = NULL; - pRecogChannel->m_pStream = NULL; pRecogChannel->m_Streaming = false; /* create source stream capabilities */ @@ -120,7 +112,7 @@ RecogChannel* DtmfSession::CreateRecogChannel() static const mpf_audio_stream_vtable_t audio_stream_vtable = { NULL, - OpenStream, + NULL, NULL, ReadStream, NULL, @@ -162,7 +154,11 @@ bool DtmfSession::OnChannelAdd(mrcp_channel_t* pMrcpChannel, mrcp_sig_status_cod RecogChannel* pRecogChannel = (RecogChannel*) mrcp_application_channel_object_get(pMrcpChannel); if(pRecogChannel) { - pRecogChannel->m_pDtmfGenerator = mpf_dtmf_generator_create(pRecogChannel->m_pStream,GetSessionPool()); + const mpf_audio_stream_t* pStream = mrcp_application_audio_stream_get(pMrcpChannel); + if(pStream) + { + pRecogChannel->m_pDtmfGenerator = mpf_dtmf_generator_create(pStream,GetSessionPool()); + } } return StartRecognition(pMrcpChannel); diff --git a/libs/unimrcp/platforms/umc/src/main.cpp b/libs/unimrcp/platforms/umc/src/main.cpp index 089dee3cd5..08983a20ae 100644 --- a/libs/unimrcp/platforms/umc/src/main.cpp +++ b/libs/unimrcp/platforms/umc/src/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: main.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "umcconsole.h" diff --git a/libs/unimrcp/platforms/umc/src/recogscenario.cpp b/libs/unimrcp/platforms/umc/src/recogscenario.cpp index c7cfbcbc26..eb13a9a81d 100644 --- a/libs/unimrcp/platforms/umc/src/recogscenario.cpp +++ b/libs/unimrcp/platforms/umc/src/recogscenario.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recogscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/platforms/umc/src/recogsession.cpp b/libs/unimrcp/platforms/umc/src/recogsession.cpp index 6fd6adbe1d..c9a418d923 100644 --- a/libs/unimrcp/platforms/umc/src/recogsession.cpp +++ b/libs/unimrcp/platforms/umc/src/recogsession.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recogsession.cpp 1587 2010-03-12 19:40:02Z achaloyan $ */ #include "recogsession.h" @@ -27,12 +29,21 @@ struct RecogChannel { /** MRCP control channel */ mrcp_channel_t* m_pMrcpChannel; + /** IN-PROGRESS RECOGNIZE request */ + mrcp_message_t* m_pRecogRequest; /** Streaming is in-progress */ bool m_Streaming; /** File to read audio stream from */ FILE* m_pAudioIn; /** Estimated time to complete (used if no audio_in available) */ apr_size_t m_TimeToComplete; + + RecogChannel() : + m_pMrcpChannel(NULL), + m_pRecogRequest(NULL), + m_Streaming(false), + m_pAudioIn(NULL), + m_TimeToComplete(0) {} }; RecogSession::RecogSession(const RecogScenario* pScenario) : @@ -67,6 +78,37 @@ bool RecogSession::Start() return true; } +bool RecogSession::Stop() +{ + if(!UmcSession::Stop()) + return false; + + if(!m_pRecogChannel) + return false; + + mrcp_message_t* pStopMessage = CreateMrcpMessage(m_pRecogChannel->m_pMrcpChannel,RECOGNIZER_STOP); + if(!pStopMessage) + return false; + + if(m_pRecogChannel->m_pRecogRequest) + { + mrcp_generic_header_t* pGenericHeader; + /* get/allocate generic header */ + pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pStopMessage); + if(pGenericHeader) + { + pGenericHeader->active_request_id_list.count = 1; + pGenericHeader->active_request_id_list.ids[0] = + m_pRecogChannel->m_pRecogRequest->start_line.request_id; + mrcp_generic_header_property_add(pStopMessage,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); + } + + m_pRecogChannel->m_pRecogRequest = NULL; + } + + return SendMrcpRequest(m_pRecogChannel->m_pMrcpChannel,pStopMessage); +} + bool RecogSession::OnSessionTerminate(mrcp_sig_status_code_e status) { if(m_pRecogChannel) @@ -128,11 +170,7 @@ RecogChannel* RecogSession::CreateRecogChannel() apr_pool_t* pool = GetSessionPool(); /* create channel */ - RecogChannel *pRecogChannel = new RecogChannel; - pRecogChannel->m_pMrcpChannel = NULL; - pRecogChannel->m_Streaming = false; - pRecogChannel->m_pAudioIn = NULL; - pRecogChannel->m_TimeToComplete = 0; + RecogChannel* pRecogChannel = new RecogChannel; /* create source stream capabilities */ pCapabilities = mpf_source_stream_capabilities_create(pool); @@ -218,11 +256,13 @@ bool RecogSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t /* received the response to RECOGNIZE request */ if(pMrcpMessage->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS) { + RecogChannel* pRecogChannel = (RecogChannel*) mrcp_application_channel_object_get(pMrcpChannel); + if(pRecogChannel) + pRecogChannel->m_pRecogRequest = GetMrcpMessage(); + /* start to stream the speech to recognize */ if(pRecogChannel) - { pRecogChannel->m_Streaming = true; - } } else { @@ -241,9 +281,12 @@ bool RecogSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t { ParseNLSMLResult(pMrcpMessage); if(pRecogChannel) - { pRecogChannel->m_Streaming = false; - } + + RecogChannel* pRecogChannel = (RecogChannel*) mrcp_application_channel_object_get(pMrcpChannel); + if(pRecogChannel) + pRecogChannel->m_pRecogRequest = NULL; + Terminate(); } else if(pMrcpMessage->start_line.method_id == RECOGNIZER_START_OF_INPUT) diff --git a/libs/unimrcp/platforms/umc/src/recorderscenario.cpp b/libs/unimrcp/platforms/umc/src/recorderscenario.cpp index 398fc57c56..dd0ee2b1a9 100644 --- a/libs/unimrcp/platforms/umc/src/recorderscenario.cpp +++ b/libs/unimrcp/platforms/umc/src/recorderscenario.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recorderscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/platforms/umc/src/recordersession.cpp b/libs/unimrcp/platforms/umc/src/recordersession.cpp index 28a7138e80..e10369eeb5 100644 --- a/libs/unimrcp/platforms/umc/src/recordersession.cpp +++ b/libs/unimrcp/platforms/umc/src/recordersession.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: recordersession.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "recordersession.h" diff --git a/libs/unimrcp/platforms/umc/src/setparamscenario.cpp b/libs/unimrcp/platforms/umc/src/setparamscenario.cpp index 60e889297d..c2b62b1934 100644 --- a/libs/unimrcp/platforms/umc/src/setparamscenario.cpp +++ b/libs/unimrcp/platforms/umc/src/setparamscenario.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: setparamscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "setparamscenario.h" diff --git a/libs/unimrcp/platforms/umc/src/setparamsession.cpp b/libs/unimrcp/platforms/umc/src/setparamsession.cpp index 403629bfb4..cc60a020a7 100644 --- a/libs/unimrcp/platforms/umc/src/setparamsession.cpp +++ b/libs/unimrcp/platforms/umc/src/setparamsession.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: setparamsession.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "setparamsession.h" diff --git a/libs/unimrcp/platforms/umc/src/synthscenario.cpp b/libs/unimrcp/platforms/umc/src/synthscenario.cpp index 37c9d66f30..b104ef20a6 100644 --- a/libs/unimrcp/platforms/umc/src/synthscenario.cpp +++ b/libs/unimrcp/platforms/umc/src/synthscenario.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: synthscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/platforms/umc/src/synthsession.cpp b/libs/unimrcp/platforms/umc/src/synthsession.cpp index a0cb5082a5..003d2f6b62 100644 --- a/libs/unimrcp/platforms/umc/src/synthsession.cpp +++ b/libs/unimrcp/platforms/umc/src/synthsession.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: synthsession.cpp 1586 2010-03-12 19:39:02Z achaloyan $ */ #include "synthsession.h" @@ -23,9 +25,14 @@ struct SynthChannel { + /** MRCP channel */ mrcp_channel_t* m_pMrcpChannel; + /** IN-PROGRESS SPEAK request */ + mrcp_message_t* m_pSpeakRequest; /** File to write audio stream to */ FILE* m_pAudioOut; + + SynthChannel() : m_pMrcpChannel(NULL), m_pSpeakRequest(NULL), m_pAudioOut(NULL) {} }; SynthSession::SynthSession(const SynthScenario* pScenario) : @@ -58,6 +65,37 @@ bool SynthSession::Start() return true; } +bool SynthSession::Stop() +{ + if(!UmcSession::Stop()) + return false; + + if(!m_pSynthChannel) + return false; + + mrcp_message_t* pStopMessage = CreateMrcpMessage(m_pSynthChannel->m_pMrcpChannel,SYNTHESIZER_STOP); + if(!pStopMessage) + return false; + + if(m_pSynthChannel->m_pSpeakRequest) + { + mrcp_generic_header_t* pGenericHeader; + /* get/allocate generic header */ + pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pStopMessage); + if(pGenericHeader) + { + pGenericHeader->active_request_id_list.count = 1; + pGenericHeader->active_request_id_list.ids[0] = + m_pSynthChannel->m_pSpeakRequest->start_line.request_id; + mrcp_generic_header_property_add(pStopMessage,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST); + } + + m_pSynthChannel->m_pSpeakRequest = NULL; + } + + return SendMrcpRequest(m_pSynthChannel->m_pMrcpChannel,pStopMessage); +} + bool SynthSession::OnSessionTerminate(mrcp_sig_status_code_e status) { if(m_pSynthChannel) @@ -93,8 +131,7 @@ SynthChannel* SynthSession::CreateSynthChannel() apr_pool_t* pool = GetSessionPool(); /* create channel */ - SynthChannel *pSynthChannel = new SynthChannel; - pSynthChannel->m_pMrcpChannel = NULL; + SynthChannel* pSynthChannel = new SynthChannel; /* create sink stream capabilities */ pCapabilities = mpf_sink_stream_capabilities_create(pool); @@ -128,7 +165,6 @@ SynthChannel* SynthSession::CreateSynthChannel() } pSynthChannel->m_pMrcpChannel = pChannel; - pSynthChannel->m_pAudioOut = NULL; return pSynthChannel; } @@ -169,6 +205,10 @@ bool SynthSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t /* received the response to SPEAK request */ if(pMrcpMessage->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS) { + SynthChannel* pSynthChannel = (SynthChannel*) mrcp_application_channel_object_get(pMrcpChannel); + if(pSynthChannel) + pSynthChannel->m_pSpeakRequest = GetMrcpMessage(); + /* waiting for SPEAK-COMPLETE event */ } else @@ -187,6 +227,9 @@ bool SynthSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t /* received MRCP event */ if(pMrcpMessage->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE) { + SynthChannel* pSynthChannel = (SynthChannel*) mrcp_application_channel_object_get(pMrcpChannel); + if(pSynthChannel) + pSynthChannel->m_pSpeakRequest = NULL; /* received SPEAK-COMPLETE event, terminate the session */ Terminate(); } diff --git a/libs/unimrcp/platforms/umc/src/umcconsole.cpp b/libs/unimrcp/platforms/umc/src/umcconsole.cpp index 203bc442ef..feff85c6b2 100644 --- a/libs/unimrcp/platforms/umc/src/umcconsole.cpp +++ b/libs/unimrcp/platforms/umc/src/umcconsole.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcconsole.cpp 1785 2010-09-22 06:14:29Z achaloyan $ */ #include @@ -37,6 +39,7 @@ bool UmcConsole::Run(int argc, const char * const *argv) { apr_pool_t* pool = NULL; apt_dir_layout_t* pDirLayout = NULL; + const char *logConfPath; /* APR global initialization */ if(apr_initialize() != APR_SUCCESS) @@ -63,13 +66,27 @@ bool UmcConsole::Run(int argc, const char * const *argv) /* create the structure of default directories layout */ pDirLayout = apt_default_dir_layout_create(m_Options.m_RootDirPath,pool); - /* create singleton logger */ - apt_log_instance_create(m_Options.m_LogOutput,m_Options.m_LogPriority,pool); - if((m_Options.m_LogOutput & APT_LOG_OUTPUT_FILE) == APT_LOG_OUTPUT_FILE) + /* get path to logger configuration file */ + logConfPath = apt_confdir_filepath_get(pDirLayout,"logger.xml",pool); + /* create and load singleton logger */ + apt_log_instance_load(logConfPath,pool); + + if(m_Options.m_LogPriority) + { + /* override the log priority, if specified in command line */ + apt_log_priority_set((apt_log_priority_e)atoi(m_Options.m_LogPriority)); + } + if(m_Options.m_LogOutput) + { + /* override the log output mode, if specified in command line */ + apt_log_output_mode_set((apt_log_output_e)atoi(m_Options.m_LogOutput)); + } + + if(apt_log_output_mode_check(APT_LOG_OUTPUT_FILE) == TRUE) { /* open the log file */ - apt_log_file_open(pDirLayout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,pool); + apt_log_file_open(pDirLayout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,FALSE,pool); } /* create demo framework */ @@ -105,7 +122,7 @@ bool UmcConsole::ProcessCmdLine(char* pCmdLine) const char* pProfileName = apr_strtok(NULL, " ", &last); if(!pProfileName) { - pProfileName = "MRCPv2-Default"; + pProfileName = "uni2"; } m_pFramework->RunSession(pScenarioName,pProfileName); } @@ -118,6 +135,14 @@ bool UmcConsole::ProcessCmdLine(char* pCmdLine) m_pFramework->KillSession(pID); } } + else if(strcasecmp(name,"stop") == 0) + { + char* pID = apr_strtok(NULL, " ", &last); + if(pID) + { + m_pFramework->StopSession(pID); + } + } else if(strcasecmp(name,"show") == 0) { char* pWhat = apr_strtok(NULL, " ", &last); @@ -146,12 +171,12 @@ bool UmcConsole::ProcessCmdLine(char* pCmdLine) printf("usage:\n" "\n- run [scenario] [profile] (run new session)\n" " scenario is one of 'synth', 'recog', ... (use 'show scenarios')\n" - " profile is one of 'MRCPv2-Default', 'MRCPv1-Default', ... (see unimrcpclient.xml)\n" + " profile is one of 'uni2', 'uni1', ... (see unimrcpclient.xml)\n" "\n examples: \n" " run synth\n" " run recog\n" - " run synth MRCPv1-Default\n" - " run recog MRCPv1-Default\n" + " run synth uni1\n" + " run recog uni1\n" "\n- kill [id] (kill session)\n" " id is a session identifier: 1, 2, ... (use 'show sessions')\n" "\n example: \n" @@ -238,8 +263,8 @@ bool UmcConsole::LoadOptions(int argc, const char * const *argv, apr_pool_t *poo /* set the default options */ m_Options.m_RootDirPath = "../"; - m_Options.m_LogPriority = APT_PRIO_INFO; - m_Options.m_LogOutput = APT_LOG_OUTPUT_CONSOLE; + m_Options.m_LogPriority = NULL; + m_Options.m_LogOutput = NULL; rv = apr_getopt_init(&opt, pool , argc, argv); if(rv != APR_SUCCESS) @@ -254,15 +279,11 @@ bool UmcConsole::LoadOptions(int argc, const char * const *argv, apr_pool_t *poo break; case 'l': if(optarg) - { - m_Options.m_LogPriority = (apt_log_priority_e) atoi(optarg); - } + m_Options.m_LogPriority = optarg; break; case 'o': if(optarg) - { - m_Options.m_LogOutput = (apt_log_output_e) atoi(optarg); - } + m_Options.m_LogOutput = optarg; break; case 'h': Usage(); diff --git a/libs/unimrcp/platforms/umc/src/umcframework.cpp b/libs/unimrcp/platforms/umc/src/umcframework.cpp index a4620bbf8b..9c06064919 100644 --- a/libs/unimrcp/platforms/umc/src/umcframework.cpp +++ b/libs/unimrcp/platforms/umc/src/umcframework.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcframework.cpp 1767 2010-08-23 19:10:22Z achaloyan $ */ #include "umcframework.h" @@ -21,6 +23,7 @@ #include "recorderscenario.h" #include "dtmfscenario.h" #include "setparamscenario.h" +#include "verifierscenario.h" #include "unimrcp_client.h" #include "apt_log.h" @@ -36,6 +39,7 @@ enum UmcTaskMsgType { UMC_TASK_CLIENT_MSG, UMC_TASK_RUN_SESSION_MSG, + UMC_TASK_STOP_SESSION_MSG, UMC_TASK_KILL_SESSION_MSG, UMC_TASK_SHOW_SCENARIOS_MSG, UMC_TASK_SHOW_SESSIONS_MSG @@ -134,7 +138,7 @@ bool UmcFramework::CreateTask() return false; pTask = apt_consumer_task_base_get(m_pTask); - apt_task_name_set(pTask,"Framework Task"); + apt_task_name_set(pTask,"Framework Agent"); pVtable = apt_consumer_task_vtable_get(m_pTask); if(pVtable) { @@ -175,6 +179,8 @@ UmcScenario* UmcFramework::CreateScenario(const char* pType) return new DtmfScenario(); else if(strcasecmp(pType,"Params") == 0) return new SetParamScenario(); + else if(strcasecmp(pType,"Verifier") == 0) + return new VerifierScenario(); } return NULL; } @@ -335,6 +341,24 @@ bool UmcFramework::ProcessRunRequest(const char* pScenarioName, const char* pPro return true; } +void UmcFramework::ProcessStopRequest(const char* id) +{ + UmcSession* pSession; + void* pVal; + apr_hash_index_t* it = apr_hash_first(m_pPool,m_pSessionTable); + for(; it; it = apr_hash_next(it)) + { + apr_hash_this(it,NULL,NULL,&pVal); + pSession = (UmcSession*) pVal; + if(pSession && strcasecmp(pSession->GetId(),id) == 0) + { + /* stop in-progress request */ + pSession->Stop(); + return; + } + } +} + void UmcFramework::ProcessKillRequest(const char* id) { UmcSession* pSession; @@ -346,7 +370,7 @@ void UmcFramework::ProcessKillRequest(const char* id) pSession = (UmcSession*) pVal; if(pSession && strcasecmp(pSession->GetId(),id) == 0) { - /* first, terminate session */ + /* terminate session */ pSession->Terminate(); return; } @@ -403,6 +427,22 @@ void UmcFramework::RunSession(const char* pScenarioName, const char* pProfileNam apt_task_msg_signal(pTask,pTaskMsg); } +void UmcFramework::StopSession(const char* id) +{ + apt_task_t* pTask = apt_consumer_task_base_get(m_pTask); + apt_task_msg_t* pTaskMsg = apt_task_msg_get(pTask); + if(!pTaskMsg) + return; + + pTaskMsg->type = TASK_MSG_USER; + pTaskMsg->sub_type = UMC_TASK_STOP_SESSION_MSG; + + UmcTaskMsg* pUmcMsg = (UmcTaskMsg*) pTaskMsg->data; + strncpy(pUmcMsg->m_SessionId,id,sizeof(pUmcMsg->m_SessionId)-1); + pUmcMsg->m_pAppMessage = NULL; + apt_task_msg_signal(pTask,pTaskMsg); +} + void UmcFramework::KillSession(const char* id) { apt_task_t* pTask = apt_consumer_task_base_get(m_pTask); @@ -562,6 +602,11 @@ apt_bool_t UmcProcessMsg(apt_task_t *pTask, apt_task_msg_t *pMsg) pFramework->ProcessRunRequest(pUmcMsg->m_ScenarioName,pUmcMsg->m_ProfileName); break; } + case UMC_TASK_STOP_SESSION_MSG: + { + pFramework->ProcessStopRequest(pUmcMsg->m_SessionId); + break; + } case UMC_TASK_KILL_SESSION_MSG: { pFramework->ProcessKillRequest(pUmcMsg->m_SessionId); diff --git a/libs/unimrcp/platforms/umc/src/umcscenario.cpp b/libs/unimrcp/platforms/umc/src/umcscenario.cpp index e93c53a1b6..f48bea74c9 100644 --- a/libs/unimrcp/platforms/umc/src/umcscenario.cpp +++ b/libs/unimrcp/platforms/umc/src/umcscenario.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,14 +12,17 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcscenario.cpp 1571 2010-03-07 20:33:39Z achaloyan $ */ #include #include "umcscenario.h" +#include "apt_log.h" UmcScenario::UmcScenario() : m_pName(NULL), - m_pMrcpProfile("MRCPv2-Default"), + m_pMrcpProfile("uni2"), m_pDirLayout(NULL), m_ResourceDiscovery(false), m_pCapabilities(NULL), @@ -200,14 +203,31 @@ const char* UmcScenario::LoadFileContent(const char* pFileName, apr_pool_t* pool if(!pFilePath) return NULL; - FILE* pFile = fopen(pFilePath,"r"); - if(!pFile) + apr_file_t *pFile; + if(apr_file_open(&pFile,pFilePath,APR_FOPEN_READ|APR_FOPEN_BINARY,0,pool) != APR_SUCCESS) + { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open File %s",pFilePath); return NULL; + } - char text[1024]; - apr_size_t size; - size = fread(text,1,sizeof(text)-1,pFile); - text[size] = '\0'; - fclose(pFile); - return apr_pstrdup(pool,text); + apr_finfo_t finfo; + if(apr_file_info_get(&finfo,APR_FINFO_SIZE,pFile) != APR_SUCCESS) + { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Get File Info %s",pFilePath); + apr_file_close(pFile); + return NULL; + } + + apr_size_t size = (apr_size_t)finfo.size; + char* pContent = (char*) apr_palloc(pool,size+1); + apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Load File Content size [%"APR_SIZE_T_FMT" bytes] %s",size,pFilePath); + if(apr_file_read(pFile,pContent,&size) != APR_SUCCESS) + { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Read Content %s",pFilePath); + apr_file_close(pFile); + return NULL; + } + pContent[size] = '\0'; + apr_file_close(pFile); + return pContent; } diff --git a/libs/unimrcp/platforms/umc/src/umcsession.cpp b/libs/unimrcp/platforms/umc/src/umcsession.cpp index d19be46466..d619893cac 100644 --- a/libs/unimrcp/platforms/umc/src/umcsession.cpp +++ b/libs/unimrcp/platforms/umc/src/umcsession.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,16 +12,20 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: umcsession.cpp 1695 2010-05-19 18:56:15Z achaloyan $ */ #include "umcsession.h" #include "umcscenario.h" +#include "mrcp_message.h" UmcSession::UmcSession(const UmcScenario* pScenario) : m_pScenario(pScenario), m_pMrcpProfile(NULL), m_pMrcpApplication(NULL), m_pMrcpSession(NULL), + m_pMrcpMessage(NULL), m_Running(false), m_Terminating(false) { @@ -69,6 +73,14 @@ bool UmcSession::Run() return ret; } +bool UmcSession::Stop() +{ + if(m_Terminating) + return false; + + return true; +} + bool UmcSession::Terminate() { if(m_Terminating) @@ -105,7 +117,17 @@ bool UmcSession::OnChannelRemove(mrcp_channel_t *channel, mrcp_sig_status_code_e bool UmcSession::OnMessageReceive(mrcp_channel_t *channel, mrcp_message_t *message) { - return m_Running; + if(!m_Running) + return false; + + if(!m_pMrcpMessage) + return false; + + /* match request identifiers */ + if(m_pMrcpMessage->start_line.request_id != message->start_line.request_id) + return false; + + return true; } bool UmcSession::OnTerminateEvent(mrcp_channel_t *channel) @@ -129,6 +151,9 @@ bool UmcSession::OnResourceDiscover(mrcp_session_descriptor_t* descriptor, mrcp_ bool UmcSession::CreateMrcpSession(const char* pProfileName) { m_pMrcpSession = mrcp_application_session_create(m_pMrcpApplication,pProfileName,this); + char name[32]; + apr_snprintf(name,sizeof(name),"umc-%s",m_Id); + mrcp_application_session_name_set(m_pMrcpSession,name); return (m_pMrcpSession != NULL); } @@ -163,6 +188,7 @@ bool UmcSession::SendMrcpRequest(mrcp_channel_t* pMrcpChannel, mrcp_message_t* p if(!m_Running) return false; + m_pMrcpMessage = pMrcpMessage; return (mrcp_application_message_send(m_pMrcpSession,pMrcpChannel,pMrcpMessage) == TRUE); } diff --git a/libs/unimrcp/platforms/umc/src/verifierscenario.cpp b/libs/unimrcp/platforms/umc/src/verifierscenario.cpp new file mode 100644 index 0000000000..23ee362803 --- /dev/null +++ b/libs/unimrcp/platforms/umc/src/verifierscenario.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: verifierscenario.cpp 1775 2010-08-26 18:23:38Z achaloyan $ + */ + +#include +#include "verifierscenario.h" +#include "verifiersession.h" +#include "mrcp_message.h" +#include "mrcp_generic_header.h" +#include "mrcp_recog_header.h" +#include "mrcp_recog_resource.h" +#include "apt_log.h" + +VerifierScenario::VerifierScenario() : + m_RepositoryURI(NULL), + m_VerificationMode(NULL), + m_VoiceprintIdentifier(NULL) +{ +} + +VerifierScenario::~VerifierScenario() +{ +} + +void VerifierScenario::Destroy() +{ +} + +bool VerifierScenario::LoadElement(const apr_xml_elem* pElem, apr_pool_t* pool) +{ + if(UmcScenario::LoadElement(pElem,pool)) + return true; + + if(strcasecmp(pElem->name,"verify") == 0) + { + LoadVerify(pElem,pool); + return true; + } + return false; +} + +bool VerifierScenario::LoadVerify(const apr_xml_elem* pElem, apr_pool_t* pool) +{ + const apr_xml_attr* pAttr; + for(pAttr = pElem->attr; pAttr; pAttr = pAttr->next) + { + if(strcasecmp(pAttr->name,"repository-uri") == 0) + { + m_RepositoryURI = pAttr->value; + } + else if(strcasecmp(pAttr->name,"verification-mode") == 0) + { + m_VerificationMode = pAttr->value; + } + else if(strcasecmp(pAttr->name,"voiceprint-identifier") == 0) + { + m_VoiceprintIdentifier = pAttr->value; + } + } + + return true; +} + + +UmcSession* VerifierScenario::CreateSession() +{ + return new VerifierSession(this); +} diff --git a/libs/unimrcp/platforms/umc/src/verifiersession.cpp b/libs/unimrcp/platforms/umc/src/verifiersession.cpp new file mode 100644 index 0000000000..c44530e006 --- /dev/null +++ b/libs/unimrcp/platforms/umc/src/verifiersession.cpp @@ -0,0 +1,389 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: verifiersession.cpp 1778 2010-08-27 17:34:52Z achaloyan $ + */ + +#include "verifiersession.h" +#include "verifierscenario.h" +#include "mrcp_message.h" +#include "mrcp_generic_header.h" +#include "mrcp_verifier_header.h" +#include "mrcp_verifier_resource.h" +#include "apt_nlsml_doc.h" +#include "apt_log.h" + +struct VerifierChannel +{ + /** MRCP control channel */ + mrcp_channel_t* m_pMrcpChannel; + /** IN-PROGRESS VERIFY request */ + mrcp_message_t* m_pVerificationRequest; + /** Streaming is in-progress */ + bool m_Streaming; + /** File to read audio stream from */ + FILE* m_pAudioIn; + /** Estimated time to complete (used if no audio_in available) */ + apr_size_t m_TimeToComplete; + + VerifierChannel() : + m_pMrcpChannel(NULL), + m_pVerificationRequest(NULL), + m_Streaming(false), + m_pAudioIn(NULL), + m_TimeToComplete(0) {} +}; + +VerifierSession::VerifierSession(const VerifierScenario* pScenario) : + UmcSession(pScenario), + m_pVerifierChannel(NULL), + m_ContentId("request1@form-level") +{ +} + +VerifierSession::~VerifierSession() +{ +} + +bool VerifierSession::Start() +{ + /* create channel and associate all the required data */ + m_pVerifierChannel = CreateVerifierChannel(); + if(!m_pVerifierChannel) + return false; + + /* add channel to session (send asynchronous request) */ + if(!AddMrcpChannel(m_pVerifierChannel->m_pMrcpChannel)) + { + delete m_pVerifierChannel; + m_pVerifierChannel = NULL; + return false; + } + return true; +} + +bool VerifierSession::Stop() +{ + if(!UmcSession::Stop()) + return false; + + if(!m_pVerifierChannel) + return false; + + mrcp_message_t* pStopMessage = CreateMrcpMessage(m_pVerifierChannel->m_pMrcpChannel,VERIFIER_STOP); + if(!pStopMessage) + return false; + + return SendMrcpRequest(m_pVerifierChannel->m_pMrcpChannel,pStopMessage); +} + +bool VerifierSession::OnSessionTerminate(mrcp_sig_status_code_e status) +{ + if(m_pVerifierChannel) + { + FILE* pAudioIn = m_pVerifierChannel->m_pAudioIn; + if(pAudioIn) + { + m_pVerifierChannel->m_pAudioIn = NULL; + fclose(pAudioIn); + } + + delete m_pVerifierChannel; + m_pVerifierChannel = NULL; + } + return UmcSession::OnSessionTerminate(status); +} + +static apt_bool_t ReadStream(mpf_audio_stream_t* pStream, mpf_frame_t* pFrame) +{ + VerifierChannel* pVerifierChannel = (VerifierChannel*) pStream->obj; + if(pVerifierChannel && pVerifierChannel->m_Streaming) + { + if(pVerifierChannel->m_pAudioIn) + { + if(fread(pFrame->codec_frame.buffer,1,pFrame->codec_frame.size,pVerifierChannel->m_pAudioIn) == pFrame->codec_frame.size) + { + /* normal read */ + pFrame->type |= MEDIA_FRAME_TYPE_AUDIO; + } + else + { + /* file is over */ + pVerifierChannel->m_Streaming = false; + } + } + else + { + /* fill with silence in case no file available */ + if(pVerifierChannel->m_TimeToComplete >= CODEC_FRAME_TIME_BASE) + { + pFrame->type |= MEDIA_FRAME_TYPE_AUDIO; + memset(pFrame->codec_frame.buffer,0,pFrame->codec_frame.size); + pVerifierChannel->m_TimeToComplete -= CODEC_FRAME_TIME_BASE; + } + else + { + pVerifierChannel->m_Streaming = false; + } + } + } + return TRUE; +} + +VerifierChannel* VerifierSession::CreateVerifierChannel() +{ + mrcp_channel_t* pChannel; + mpf_termination_t* pTermination; + mpf_stream_capabilities_t* pCapabilities; + apr_pool_t* pool = GetSessionPool(); + + /* create channel */ + VerifierChannel* pVerifierChannel = new VerifierChannel; + + /* create source stream capabilities */ + pCapabilities = mpf_source_stream_capabilities_create(pool); + GetScenario()->InitCapabilities(pCapabilities); + + static const mpf_audio_stream_vtable_t audio_stream_vtable = + { + NULL, + NULL, + NULL, + ReadStream, + NULL, + NULL, + NULL + }; + + pTermination = CreateAudioTermination( + &audio_stream_vtable, /* virtual methods table of audio stream */ + pCapabilities, /* capabilities of audio stream */ + pVerifierChannel); /* object to associate */ + + pChannel = CreateMrcpChannel( + MRCP_VERIFIER_RESOURCE, /* MRCP resource identifier */ + pTermination, /* media termination, used to terminate audio stream */ + NULL, /* RTP descriptor, used to create RTP termination (NULL by default) */ + pVerifierChannel); /* object to associate */ + if(!pChannel) + { + delete pVerifierChannel; + return NULL; + } + + pVerifierChannel->m_pMrcpChannel = pChannel; + return pVerifierChannel; +} + +bool VerifierSession::OnChannelAdd(mrcp_channel_t* pMrcpChannel, mrcp_sig_status_code_e status) +{ + if(!UmcSession::OnChannelAdd(pMrcpChannel,status)) + return false; + + if(status != MRCP_SIG_STATUS_CODE_SUCCESS) + { + /* error case, just terminate the demo */ + return Terminate(); + } + + return StartVerification(pMrcpChannel); +} + +bool VerifierSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t* pMrcpMessage) +{ + if(!UmcSession::OnMessageReceive(pMrcpChannel,pMrcpMessage)) + return false; + + VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel); + if(pMrcpMessage->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE) + { + /* received MRCP response */ + if(pMrcpMessage->start_line.method_id == VERIFIER_START_SESSION) + { + /* received the response to START-SESSION request */ + /* create and send VERIFY request */ + mrcp_message_t* pMrcpMessage = CreateVerificationRequest(pMrcpChannel); + if(pMrcpMessage) + { + SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage); + } + } + else if(pMrcpMessage->start_line.method_id == VERIFIER_END_SESSION) + { + /* received the response to END-SESSION request */ + Terminate(); + } + else if(pMrcpMessage->start_line.method_id == VERIFIER_VERIFY) + { + /* received the response to VERIFY request */ + if(pMrcpMessage->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS) + { + VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel); + if(pVerifierChannel) + pVerifierChannel->m_pVerificationRequest = GetMrcpMessage(); + + /* start to stream the speech to Verify */ + if(pVerifierChannel) + pVerifierChannel->m_Streaming = true; + } + else + { + /* create and send END-SESSION request */ + mrcp_message_t* pMrcpMessage = CreateEndSessionRequest(pMrcpChannel); + if(pMrcpMessage) + { + SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage); + } + } + } + else + { + /* received unexpected response */ + } + } + else if(pMrcpMessage->start_line.message_type == MRCP_MESSAGE_TYPE_EVENT) + { + if(pMrcpMessage->start_line.method_id == VERIFIER_VERIFICATION_COMPLETE) + { + if(pVerifierChannel) + pVerifierChannel->m_Streaming = false; + + VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel); + if(pVerifierChannel) + pVerifierChannel->m_pVerificationRequest = NULL; + + /* create and send END-SESSION request */ + mrcp_message_t* pMrcpMessage = CreateEndSessionRequest(pMrcpChannel); + if(pMrcpMessage) + { + SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage); + } + } + else if(pMrcpMessage->start_line.method_id == VERIFIER_START_OF_INPUT) + { + /* received start-of-input, do whatever you need here */ + } + } + return true; +} + +bool VerifierSession::StartVerification(mrcp_channel_t* pMrcpChannel) +{ + VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel); + /* create and send Verification request */ + mrcp_message_t* pMrcpMessage = CreateStartSessionRequest(pMrcpChannel); + if(pMrcpMessage) + { + SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage); + } + + const mpf_codec_descriptor_t* pDescriptor = mrcp_application_source_descriptor_get(pMrcpChannel); + pVerifierChannel->m_pAudioIn = GetAudioIn(pDescriptor,GetSessionPool()); + if(!pVerifierChannel->m_pAudioIn) + { + /* no audio input availble, set some estimated time to complete instead */ + pVerifierChannel->m_TimeToComplete = 5000; // 5 sec + } + return true; +} + +mrcp_message_t* VerifierSession::CreateStartSessionRequest(mrcp_channel_t* pMrcpChannel) +{ + mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,VERIFIER_START_SESSION); + if(!pMrcpMessage) + return NULL; + + mrcp_verifier_header_t* pVerifierHeader; + + /* get/allocate verifier header */ + pVerifierHeader = (mrcp_verifier_header_t*) mrcp_resource_header_prepare(pMrcpMessage); + if(pVerifierHeader) + { + const VerifierScenario* pScenario = GetScenario(); + const char* pRepositoryURI = pScenario->GetRepositoryURI(); + if(pRepositoryURI) + { + apt_string_set(&pVerifierHeader->repository_uri,pRepositoryURI); + mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_REPOSITORY_URI); + } + const char* pVoiceprintIdentifier = pScenario->GetVoiceprintIdentifier(); + if(pVoiceprintIdentifier) + { + apt_string_set(&pVerifierHeader->voiceprint_identifier,pVoiceprintIdentifier); + mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_VOICEPRINT_IDENTIFIER); + } + const char* pVerificationMode = pScenario->GetVerificationMode(); + if(pVerificationMode) + { + apt_string_set(&pVerifierHeader->verification_mode,pVerificationMode); + mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_VERIFICATION_MODE); + } + } + return pMrcpMessage; +} + +mrcp_message_t* VerifierSession::CreateEndSessionRequest(mrcp_channel_t* pMrcpChannel) +{ + return CreateMrcpMessage(pMrcpChannel,VERIFIER_END_SESSION); +} + +mrcp_message_t* VerifierSession::CreateVerificationRequest(mrcp_channel_t* pMrcpChannel) +{ + mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,VERIFIER_VERIFY); + if(!pMrcpMessage) + return NULL; + + mrcp_verifier_header_t* pVerifierHeader; + + /* get/allocate verifier header */ + pVerifierHeader = (mrcp_verifier_header_t*) mrcp_resource_header_prepare(pMrcpMessage); + if(pVerifierHeader) + { + pVerifierHeader->no_input_timeout = 5000; + mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_NO_INPUT_TIMEOUT); + pVerifierHeader->start_input_timers = TRUE; + mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_START_INPUT_TIMERS); + } + return pMrcpMessage; +} + +FILE* VerifierSession::GetAudioIn(const mpf_codec_descriptor_t* pDescriptor, apr_pool_t* pool) const +{ + const VerifierScenario* pScenario = GetScenario(); + const char* pVoiceprintIdentifier = pScenario->GetVoiceprintIdentifier(); + if(!pVoiceprintIdentifier) + { + apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Voiceprint Specified"); + return NULL; + } + + const char* pFileName = apr_psprintf(pool,"%s-%dkHz.pcm", + pVoiceprintIdentifier, + pDescriptor ? pDescriptor->sampling_rate/1000 : 8); + apt_dir_layout_t* pDirLayout = pScenario->GetDirLayout(); + const char* pFilePath = apt_datadir_filepath_get(pDirLayout,pFileName,pool); + if(!pFilePath) + return NULL; + + FILE* pFile = fopen(pFilePath,"rb"); + if(!pFile) + { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Cannot Find [%s]",pFilePath); + return NULL; + } + + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set [%s] as Speech Source",pFilePath); + return pFile; +} diff --git a/libs/unimrcp/platforms/umc/umc.rc b/libs/unimrcp/platforms/umc/umc.rc new file mode 100644 index 0000000000..511efb81b6 --- /dev/null +++ b/libs/unimrcp/platforms/umc/umc.rc @@ -0,0 +1,39 @@ +#include "uni_version.h" + +1 VERSIONINFO + FILEVERSION UNI_VERSION_STRING_CSV,0 + PRODUCTVERSION UNI_VERSION_STRING_CSV,0 + FILEFLAGSMASK 0x3fL +#if defined(_DEBUG) + FILEFLAGS 0x01L +#else + FILEFLAGS 0x00L +#endif +#if defined(WINNT) || defined(WIN64) + FILEOS 0x40004L +#else + FILEOS 0x4L +#endif + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", UNI_LICENSE "\0" + VALUE "CompanyName", "UniMRCP\0" + VALUE "FileDescription", "UniMRCP Client Application\0" + VALUE "FileVersion", UNI_VERSION_STRING "\0" + VALUE "InternalName", "umc" "\0" + VALUE "LegalCopyright", UNI_COPYRIGHT "\0" + VALUE "OriginalFilename", "umc.exe" "\0" + VALUE "ProductName", "UniMRCP Project\0" + VALUE "ProductVersion", UNI_VERSION_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libs/unimrcp/platforms/umc/umc.vcproj b/libs/unimrcp/platforms/umc/umc.vcproj index 5862942a50..d003362f18 100644 --- a/libs/unimrcp/platforms/umc/umc.vcproj +++ b/libs/unimrcp/platforms/umc/umc.vcproj @@ -339,6 +339,14 @@ RelativePath=".\src\umcsession.cpp" > + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/unimrcp/platforms/unimrcp-client/include/demo_application.h b/libs/unimrcp/platforms/unimrcp-client/include/demo_application.h index 608d996f98..305858b642 100644 --- a/libs/unimrcp/platforms/unimrcp-client/include/demo_application.h +++ b/libs/unimrcp/platforms/unimrcp-client/include/demo_application.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_application.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __DEMO_APPLICATION_H__ -#define __DEMO_APPLICATION_H__ +#ifndef DEMO_APPLICATION_H +#define DEMO_APPLICATION_H /** * @file demo_application.h @@ -58,4 +60,4 @@ demo_application_t* demo_discover_application_create(apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__DEMO_APPLICATION_H__*/ +#endif /* DEMO_APPLICATION_H */ diff --git a/libs/unimrcp/platforms/unimrcp-client/include/demo_framework.h b/libs/unimrcp/platforms/unimrcp-client/include/demo_framework.h index 5cef92305d..ef173ef7de 100644 --- a/libs/unimrcp/platforms/unimrcp-client/include/demo_framework.h +++ b/libs/unimrcp/platforms/unimrcp-client/include/demo_framework.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_framework.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __DEMO_FRAMEWORK_H__ -#define __DEMO_FRAMEWORK_H__ +#ifndef DEMO_FRAMEWORK_H +#define DEMO_FRAMEWORK_H /** * @file demo_framework.h @@ -50,4 +52,4 @@ apt_bool_t demo_framework_destroy(demo_framework_t *framework); APT_END_EXTERN_C -#endif /*__DEMO_FRAMEWORK_H__*/ +#endif /* DEMO_FRAMEWORK_H */ diff --git a/libs/unimrcp/platforms/unimrcp-client/include/demo_util.h b/libs/unimrcp/platforms/unimrcp-client/include/demo_util.h index c3d6e793d9..82b1d5ada5 100644 --- a/libs/unimrcp/platforms/unimrcp-client/include/demo_util.h +++ b/libs/unimrcp/platforms/unimrcp-client/include/demo_util.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_util.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __DEMO_UTIL_H__ -#define __DEMO_UTIL_H__ +#ifndef DEMO_UTIL_H +#define DEMO_UTIL_H /** * @file demo_util.h @@ -42,4 +44,4 @@ mpf_rtp_termination_descriptor_t* demo_rtp_descriptor_create(apr_pool_t *pool); APT_END_EXTERN_C -#endif /*__DEMO_UTIL_H__*/ +#endif /* DEMO_UTIL_H */ diff --git a/libs/unimrcp/platforms/unimrcp-client/src/demo_bypass_application.c b/libs/unimrcp/platforms/unimrcp-client/src/demo_bypass_application.c index 6a9b660bce..5780a87ae5 100644 --- a/libs/unimrcp/platforms/unimrcp-client/src/demo_bypass_application.c +++ b/libs/unimrcp/platforms/unimrcp-client/src/demo_bypass_application.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_bypass_application.c 1474 2010-02-07 20:51:47Z achaloyan $ */ /* diff --git a/libs/unimrcp/platforms/unimrcp-client/src/demo_discover_application.c b/libs/unimrcp/platforms/unimrcp-client/src/demo_discover_application.c index a31b96873c..652fc72a07 100644 --- a/libs/unimrcp/platforms/unimrcp-client/src/demo_discover_application.c +++ b/libs/unimrcp/platforms/unimrcp-client/src/demo_discover_application.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_discover_application.c 1474 2010-02-07 20:51:47Z achaloyan $ */ /* diff --git a/libs/unimrcp/platforms/unimrcp-client/src/demo_framework.c b/libs/unimrcp/platforms/unimrcp-client/src/demo_framework.c index 9d65750fbd..69ac8b1a60 100644 --- a/libs/unimrcp/platforms/unimrcp-client/src/demo_framework.c +++ b/libs/unimrcp/platforms/unimrcp-client/src/demo_framework.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_framework.c 1571 2010-03-07 20:33:39Z achaloyan $ */ #include @@ -21,7 +23,7 @@ #include "apt_consumer_task.h" #include "apt_log.h" -#define FRAMEWORK_TASK_NAME "Framework Task" +#define FRAMEWORK_TASK_NAME "Framework Agent" #define MAX_APP_NAME_LENGTH 16 #define MAX_PROFILE_NAME_LENGTH 16 diff --git a/libs/unimrcp/platforms/unimrcp-client/src/demo_recog_application.c b/libs/unimrcp/platforms/unimrcp-client/src/demo_recog_application.c index 3235b2ad86..a4b4845741 100644 --- a/libs/unimrcp/platforms/unimrcp-client/src/demo_recog_application.c +++ b/libs/unimrcp/platforms/unimrcp-client/src/demo_recog_application.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_recog_application.c 1474 2010-02-07 20:51:47Z achaloyan $ */ /* diff --git a/libs/unimrcp/platforms/unimrcp-client/src/demo_synth_application.c b/libs/unimrcp/platforms/unimrcp-client/src/demo_synth_application.c index 4ad6a7d0d5..d010bb3883 100644 --- a/libs/unimrcp/platforms/unimrcp-client/src/demo_synth_application.c +++ b/libs/unimrcp/platforms/unimrcp-client/src/demo_synth_application.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_synth_application.c 1474 2010-02-07 20:51:47Z achaloyan $ */ /* diff --git a/libs/unimrcp/platforms/unimrcp-client/src/demo_util.c b/libs/unimrcp/platforms/unimrcp-client/src/demo_util.c index db873f288e..ebbc0a5c67 100644 --- a/libs/unimrcp/platforms/unimrcp-client/src/demo_util.c +++ b/libs/unimrcp/platforms/unimrcp-client/src/demo_util.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_util.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "demo_util.h" diff --git a/libs/unimrcp/platforms/unimrcp-client/src/main.c b/libs/unimrcp/platforms/unimrcp-client/src/main.c index 6a242ca4cd..5da982b533 100644 --- a/libs/unimrcp/platforms/unimrcp-client/src/main.c +++ b/libs/unimrcp/platforms/unimrcp-client/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: main.c 1785 2010-09-22 06:14:29Z achaloyan $ */ #include @@ -23,9 +25,9 @@ #include "apt_log.h" typedef struct { - const char *root_dir_path; - apt_log_priority_e log_priority; - apt_log_output_e log_output; + const char *root_dir_path; + const char *log_priority; + const char *log_output; } client_options_t; static apt_bool_t demo_framework_cmdline_process(demo_framework_t *framework, char *cmdline) @@ -40,7 +42,7 @@ static apt_bool_t demo_framework_cmdline_process(demo_framework_t *framework, ch if(app_name) { char *profile_name = apr_strtok(NULL, " ", &last); if(!profile_name) { - profile_name = "MRCPv2-Default"; + profile_name = "uni2"; } demo_framework_app_run(framework,app_name,profile_name); } @@ -58,12 +60,12 @@ static apt_bool_t demo_framework_cmdline_process(demo_framework_t *framework, ch printf("usage:\n" "\n- run [app_name] [profile_name] (run demo application)\n" " app_name is one of 'synth', 'recog', 'bypass', 'discover'\n" - " profile_name is one of 'MRCPv2-Default', 'MRCPv1-Default', ...\n" + " profile_name is one of 'uni2', 'uni1', ...\n" "\n examples: \n" " run synth\n" " run recog\n" - " run synth MRCPv1-Default\n" - " run recog MRCPv1-Default\n" + " run synth uni1\n" + " run recog uni1\n" "\n- loglevel [level] (set loglevel, one of 0,1...7)\n" "\n- quit, exit\n"); } @@ -145,14 +147,10 @@ static apt_bool_t demo_framework_options_load(client_options_t *options, int arg options->root_dir_path = optarg; break; case 'l': - if(optarg) { - options->log_priority = atoi(optarg); - } + options->log_priority = optarg; break; case 'o': - if(optarg) { - options->log_output = atoi(optarg); - } + options->log_output = optarg; break; case 'h': usage(); @@ -173,6 +171,7 @@ int main(int argc, const char * const *argv) apr_pool_t *pool = NULL; client_options_t options; apt_dir_layout_t *dir_layout; + const char *log_conf_path; demo_framework_t *framework; /* APR global initialization */ @@ -190,8 +189,8 @@ int main(int argc, const char * const *argv) /* set the default options */ options.root_dir_path = "../"; - options.log_priority = APT_PRIO_INFO; - options.log_output = APT_LOG_OUTPUT_CONSOLE; + options.log_priority = NULL; + options.log_output = NULL; /* load options */ if(demo_framework_options_load(&options,argc,argv,pool) != TRUE) { @@ -202,12 +201,24 @@ int main(int argc, const char * const *argv) /* create the structure of default directories layout */ dir_layout = apt_default_dir_layout_create(options.root_dir_path,pool); - /* create singleton logger */ - apt_log_instance_create(options.log_output,options.log_priority,pool); - if((options.log_output & APT_LOG_OUTPUT_FILE) == APT_LOG_OUTPUT_FILE) { + /* get path to logger configuration file */ + log_conf_path = apt_confdir_filepath_get(dir_layout,"logger.xml",pool); + /* create and load singleton logger */ + apt_log_instance_load(log_conf_path,pool); + + if(options.log_priority) { + /* override the log priority, if specified in command line */ + apt_log_priority_set(atoi(options.log_priority)); + } + if(options.log_output) { + /* override the log output mode, if specified in command line */ + apt_log_output_mode_set(atoi(options.log_output)); + } + + if(apt_log_output_mode_check(APT_LOG_OUTPUT_FILE) == TRUE) { /* open the log file */ - apt_log_file_open(dir_layout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,pool); + apt_log_file_open(dir_layout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,FALSE,pool); } /* create demo framework */ diff --git a/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.2008.vcproj b/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.2008.vcproj deleted file mode 100644 index 46cd13ccaa..0000000000 --- a/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.2008.vcproj +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.rc b/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.rc new file mode 100644 index 0000000000..b7d34091c4 --- /dev/null +++ b/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.rc @@ -0,0 +1,39 @@ +#include "uni_version.h" + +1 VERSIONINFO + FILEVERSION UNI_VERSION_STRING_CSV,0 + PRODUCTVERSION UNI_VERSION_STRING_CSV,0 + FILEFLAGSMASK 0x3fL +#if defined(_DEBUG) + FILEFLAGS 0x01L +#else + FILEFLAGS 0x00L +#endif +#if defined(WINNT) || defined(WIN64) + FILEOS 0x40004L +#else + FILEOS 0x4L +#endif + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", UNI_LICENSE "\0" + VALUE "CompanyName", "UniMRCP\0" + VALUE "FileDescription", "UniMRCP Client Application\0" + VALUE "FileVersion", UNI_VERSION_STRING "\0" + VALUE "InternalName", "unimrcpclient" "\0" + VALUE "LegalCopyright", UNI_COPYRIGHT "\0" + VALUE "OriginalFilename", "unimrcpclient.exe" "\0" + VALUE "ProductName", "UniMRCP Project\0" + VALUE "ProductVersion", UNI_VERSION_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.vcproj b/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.vcproj index 36b3bf1072..706498e4a4 100644 --- a/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.vcproj +++ b/libs/unimrcp/platforms/unimrcp-client/unimrcpclient.vcproj @@ -326,6 +326,42 @@ > + + + + + + + + + + + + + + diff --git a/libs/unimrcp/platforms/unimrcp-server/src/main.c b/libs/unimrcp/platforms/unimrcp-server/src/main.c index eb283f957c..3d2c75e78b 100644 --- a/libs/unimrcp/platforms/unimrcp-server/src/main.c +++ b/libs/unimrcp/platforms/unimrcp-server/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: main.c 1785 2010-09-22 06:14:29Z achaloyan $ */ #include @@ -22,10 +24,10 @@ #include "apt_log.h" typedef struct { - const char *root_dir_path; - apt_bool_t foreground; - apt_log_priority_e log_priority; - apt_log_output_e log_output; + const char *root_dir_path; + apt_bool_t foreground; + const char *log_priority; + const char *log_output; } server_options_t; #ifdef WIN32 @@ -98,14 +100,10 @@ static apt_bool_t options_load(server_options_t *options, int argc, const char * options->root_dir_path = optarg; break; case 'l': - if(optarg) { - options->log_priority = atoi(optarg); - } + options->log_priority = optarg; break; case 'o': - if(optarg) { - options->log_output = atoi(optarg); - } + options->log_output = optarg; break; #ifdef WIN32 case 's': @@ -135,6 +133,7 @@ int main(int argc, const char * const *argv) apr_pool_t *pool = NULL; server_options_t options; apt_dir_layout_t *dir_layout; + const char *log_conf_path; /* APR global initialization */ if(apr_initialize() != APR_SUCCESS) { @@ -152,8 +151,8 @@ int main(int argc, const char * const *argv) /* set the default options */ options.root_dir_path = "../"; options.foreground = TRUE; - options.log_priority = APT_PRIO_INFO; - options.log_output = APT_LOG_OUTPUT_CONSOLE; + options.log_priority = NULL; + options.log_output = NULL; /* load options */ if(options_load(&options,argc,argv,pool) != TRUE) { @@ -164,12 +163,24 @@ int main(int argc, const char * const *argv) /* create the structure of default directories layout */ dir_layout = apt_default_dir_layout_create(options.root_dir_path,pool); - /* create singleton logger */ - apt_log_instance_create(options.log_output,options.log_priority,pool); + + /* get path to logger configuration file */ + log_conf_path = apt_confdir_filepath_get(dir_layout,"logger.xml",pool); + /* create and load singleton logger */ + apt_log_instance_load(log_conf_path,pool); + + if(options.log_priority) { + /* override the log priority, if specified in command line */ + apt_log_priority_set(atoi(options.log_priority)); + } + if(options.log_output) { + /* override the log output mode, if specified in command line */ + apt_log_output_mode_set(atoi(options.log_output)); + } - if((options.log_output & APT_LOG_OUTPUT_FILE) == APT_LOG_OUTPUT_FILE) { + if(apt_log_output_mode_check(APT_LOG_OUTPUT_FILE) == TRUE) { /* open the log file */ - apt_log_file_open(dir_layout->log_dir_path,"unimrcpserver",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,pool); + apt_log_file_open(dir_layout->log_dir_path,"unimrcpserver",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,TRUE,pool); } if(options.foreground == TRUE) { diff --git a/libs/unimrcp/platforms/unimrcp-server/src/uni_cmdline.c b/libs/unimrcp/platforms/unimrcp-server/src/uni_cmdline.c index bac1d6685e..36db7f6412 100644 --- a/libs/unimrcp/platforms/unimrcp-server/src/uni_cmdline.c +++ b/libs/unimrcp/platforms/unimrcp-server/src/uni_cmdline.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: uni_cmdline.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/platforms/unimrcp-server/src/uni_daemon.c b/libs/unimrcp/platforms/unimrcp-server/src/uni_daemon.c index ee7287009b..76c1b00a87 100644 --- a/libs/unimrcp/platforms/unimrcp-server/src/uni_daemon.c +++ b/libs/unimrcp/platforms/unimrcp-server/src/uni_daemon.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: uni_daemon.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/platforms/unimrcp-server/src/uni_service.c b/libs/unimrcp/platforms/unimrcp-server/src/uni_service.c index 9b597d88d9..b179b90e7b 100644 --- a/libs/unimrcp/platforms/unimrcp-server/src/uni_service.c +++ b/libs/unimrcp/platforms/unimrcp-server/src/uni_service.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: uni_service.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include diff --git a/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.2008.vcproj b/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.2008.vcproj deleted file mode 100644 index 147b8dccde..0000000000 --- a/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.2008.vcproj +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.rc b/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.rc new file mode 100644 index 0000000000..7c562afc96 --- /dev/null +++ b/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.rc @@ -0,0 +1,39 @@ +#include "uni_version.h" + +1 VERSIONINFO + FILEVERSION UNI_VERSION_STRING_CSV,0 + PRODUCTVERSION UNI_VERSION_STRING_CSV,0 + FILEFLAGSMASK 0x3fL +#if defined(_DEBUG) + FILEFLAGS 0x01L +#else + FILEFLAGS 0x00L +#endif +#if defined(WINNT) || defined(WIN64) + FILEOS 0x40004L +#else + FILEOS 0x4L +#endif + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", UNI_LICENSE "\0" + VALUE "CompanyName", "UniMRCP\0" + VALUE "FileDescription", "UniMRCP Server Application\0" + VALUE "FileVersion", UNI_VERSION_STRING "\0" + VALUE "InternalName", "unimrcpserver" "\0" + VALUE "LegalCopyright", UNI_COPYRIGHT "\0" + VALUE "OriginalFilename", "unimrcpserver.exe" "\0" + VALUE "ProductName", "UniMRCP Project\0" + VALUE "ProductVersion", UNI_VERSION_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.vcproj b/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.vcproj index c2b6f6c3f7..46e57dab5a 100644 --- a/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.vcproj +++ b/libs/unimrcp/platforms/unimrcp-server/unimrcpserver.vcproj @@ -298,6 +298,42 @@ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + + + + + + + + + + + + + diff --git a/libs/unimrcp/plugins/Makefile.am b/libs/unimrcp/plugins/Makefile.am index 9bc7eb75c8..9d8b7b5964 100644 --- a/libs/unimrcp/plugins/Makefile.am +++ b/libs/unimrcp/plugins/Makefile.am @@ -10,12 +10,12 @@ if DEMORECOG_PLUGIN SUBDIRS += demo-recog endif -if RECORDER_PLUGIN -SUBDIRS += mrcp-recorder +if DEMOVERIFIER_PLUGIN +SUBDIRS += demo-verifier endif -if CEPSTRAL_PLUGIN -SUBDIRS += mrcp-cepstral +if RECORDER_PLUGIN +SUBDIRS += mrcp-recorder endif if POCKETSPHINX_PLUGIN diff --git a/libs/unimrcp/plugins/demo-recog/demorecog.2008.vcproj b/libs/unimrcp/plugins/demo-recog/demorecog.2008.vcproj deleted file mode 100644 index ff23c031b4..0000000000 --- a/libs/unimrcp/plugins/demo-recog/demorecog.2008.vcproj +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/plugins/demo-recog/src/demo_recog_engine.c b/libs/unimrcp/plugins/demo-recog/src/demo_recog_engine.c index 5c1e66f38b..95681c8c84 100644 --- a/libs/unimrcp/plugins/demo-recog/src/demo_recog_engine.c +++ b/libs/unimrcp/plugins/demo-recog/src/demo_recog_engine.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_recog_engine.c 1706 2010-05-23 14:11:11Z achaloyan $ */ /* @@ -175,7 +177,7 @@ static apt_bool_t demo_recog_engine_open(mrcp_engine_t *engine) apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); apt_task_start(task); } - return TRUE; + return mrcp_engine_open_respond(engine,TRUE); } /** Close recognizer engine */ @@ -186,7 +188,7 @@ static apt_bool_t demo_recog_engine_close(mrcp_engine_t *engine) apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); apt_task_terminate(task,TRUE); } - return TRUE; + return mrcp_engine_close_respond(engine); } static mrcp_engine_channel_t* demo_recog_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool) @@ -459,15 +461,18 @@ static apt_bool_t demo_recog_stream_write(mpf_audio_stream_t *stream, const mpf_ mpf_detector_event_e det_event = mpf_activity_detector_process(recog_channel->detector,frame); switch(det_event) { case MPF_DETECTOR_EVENT_ACTIVITY: - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Voice Activity"); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Voice Activity "APT_SIDRES_FMT, + MRCP_MESSAGE_SIDRES(recog_channel->recog_request)); demo_recog_start_of_input(recog_channel); break; case MPF_DETECTOR_EVENT_INACTIVITY: - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Voice Inactivity"); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Voice Inactivity "APT_SIDRES_FMT, + MRCP_MESSAGE_SIDRES(recog_channel->recog_request)); demo_recog_recognition_complete(recog_channel,RECOGNIZER_COMPLETION_CAUSE_SUCCESS); break; case MPF_DETECTOR_EVENT_NOINPUT: - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Noinput"); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Noinput "APT_SIDRES_FMT, + MRCP_MESSAGE_SIDRES(recog_channel->recog_request)); if(recog_channel->timers_started == TRUE) { demo_recog_recognition_complete(recog_channel,RECOGNIZER_COMPLETION_CAUSE_NO_INPUT_TIMEOUT); } @@ -478,11 +483,13 @@ static apt_bool_t demo_recog_stream_write(mpf_audio_stream_t *stream, const mpf_ if((frame->type & MEDIA_FRAME_TYPE_EVENT) == MEDIA_FRAME_TYPE_EVENT) { if(frame->marker == MPF_MARKER_START_OF_EVENT) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Start of Event: id [%d]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Start of Event "APT_SIDRES_FMT" id:%d", + MRCP_MESSAGE_SIDRES(recog_channel->recog_request), frame->event_frame.event_id); } else if(frame->marker == MPF_MARKER_END_OF_EVENT) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected End of Event: id [%d] duration [%d ts]", + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected End of Event "APT_SIDRES_FMT" id:%d duration:%d ts", + MRCP_MESSAGE_SIDRES(recog_channel->recog_request), frame->event_frame.event_id, frame->event_frame.duration); } diff --git a/libs/unimrcp/plugins/demo-synth/demosynth.2008.vcproj b/libs/unimrcp/plugins/demo-synth/demosynth.2008.vcproj deleted file mode 100644 index 3c5897e6ee..0000000000 --- a/libs/unimrcp/plugins/demo-synth/demosynth.2008.vcproj +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/plugins/demo-synth/src/demo_synth_engine.c b/libs/unimrcp/plugins/demo-synth/src/demo_synth_engine.c index 5374fdc75a..9daa99f5e3 100644 --- a/libs/unimrcp/plugins/demo-synth/src/demo_synth_engine.c +++ b/libs/unimrcp/plugins/demo-synth/src/demo_synth_engine.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: demo_synth_engine.c 1706 2010-05-23 14:11:11Z achaloyan $ */ /* @@ -177,7 +179,7 @@ static apt_bool_t demo_synth_engine_open(mrcp_engine_t *engine) apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); apt_task_start(task); } - return TRUE; + return mrcp_engine_open_respond(engine,TRUE); } /** Close synthesizer engine */ @@ -188,7 +190,7 @@ static apt_bool_t demo_synth_engine_close(mrcp_engine_t *engine) apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); apt_task_terminate(task,TRUE); } - return TRUE; + return mrcp_engine_close_respond(engine); } /** Create demo synthesizer channel derived from engine channel base */ @@ -270,10 +272,14 @@ static apt_bool_t demo_synth_channel_speak(mrcp_engine_channel_t *channel, mrcp_ if(file_path) { synth_channel->audio_file = fopen(file_path,"rb"); if(synth_channel->audio_file) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set [%s] as Speech Source",file_path); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set [%s] as Speech Source "APT_SIDRES_FMT, + file_path, + MRCP_MESSAGE_SIDRES(request)); } else { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"No Speech Source [%s] Found",file_path); + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"No Speech Source [%s] Found "APT_SIDRES_FMT, + file_path, + MRCP_MESSAGE_SIDRES(request)); /* calculate estimated time to complete */ if(mrcp_generic_header_property_check(request,GENERIC_HEADER_CONTENT_LENGTH) == TRUE) { mrcp_generic_header_t *generic_header = mrcp_generic_header_get(request); diff --git a/libs/unimrcp/plugins/mrcp-cepstral/Makefile.am b/libs/unimrcp/plugins/demo-verifier/Makefile.am similarity index 70% rename from libs/unimrcp/plugins/mrcp-cepstral/Makefile.am rename to libs/unimrcp/plugins/demo-verifier/Makefile.am index 38b9bab308..175950a055 100644 --- a/libs/unimrcp/plugins/mrcp-cepstral/Makefile.am +++ b/libs/unimrcp/plugins/demo-verifier/Makefile.am @@ -8,10 +8,9 @@ INCLUDES = -Iinclude \ -I$(top_srcdir)/libs/mrcp/resources/include \ -I$(top_srcdir)/libs/mpf/include \ -I$(top_srcdir)/libs/apr-toolkit/include \ - $(UNIMRCP_APR_INCLUDES) $(UNIMRCP_APU_INCLUDES) $(UNIMRCP_SWIFT_INCLUDES) + $(UNIMRCP_APR_INCLUDES) $(UNIMRCP_APU_INCLUDES) -plugin_LTLIBRARIES = mrcpcepstral.la +plugin_LTLIBRARIES = demoverifier.la -mrcpcepstral_la_SOURCES = src/mrcp_swift.c -mrcpcepstral_la_LDFLAGS = -module $(PLUGIN_LT_VERSION) $(UNIMRCP_SWIFT_LDFLAGS) -mrcpcepstral_la_LIBADD = $(UNIMRCP_SWIFT_LIBS) +demoverifier_la_SOURCES = src/demo_verifier_engine.c +demoverifier_la_LDFLAGS = -module $(PLUGIN_LT_VERSION) diff --git a/libs/unimrcp/plugins/mrcp-cepstral/mrcpcepstral.vcproj b/libs/unimrcp/plugins/demo-verifier/demoverifier.vcproj similarity index 93% rename from libs/unimrcp/plugins/mrcp-cepstral/mrcpcepstral.vcproj rename to libs/unimrcp/plugins/demo-verifier/demoverifier.vcproj index e5a57dea79..efe5f79423 100644 --- a/libs/unimrcp/plugins/mrcp-cepstral/mrcpcepstral.vcproj +++ b/libs/unimrcp/plugins/demo-verifier/demoverifier.vcproj @@ -2,9 +2,9 @@ @@ -21,7 +21,7 @@ @@ -146,7 +146,7 @@ @@ -286,7 +286,7 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" > diff --git a/libs/unimrcp/plugins/demo-verifier/src/demo_verifier_engine.c b/libs/unimrcp/plugins/demo-verifier/src/demo_verifier_engine.c new file mode 100644 index 0000000000..8918bedcbf --- /dev/null +++ b/libs/unimrcp/plugins/demo-verifier/src/demo_verifier_engine.c @@ -0,0 +1,577 @@ +/* + * Copyright 2008-2010 Arsen Chaloyan + * + * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id: demo_verifier_engine.c 1776 2010-08-27 16:36:38Z achaloyan $ + */ + +/* + * Mandatory rules concerning plugin implementation. + * 1. Each plugin MUST implement a plugin/engine creator function + * with the exact signature and name (the main entry point) + * MRCP_PLUGIN_DECLARE(mrcp_engine_t*) mrcp_plugin_create(apr_pool_t *pool) + * 2. Each plugin MUST declare its version number + * MRCP_PLUGIN_VERSION_DECLARE + * 3. One and only one response MUST be sent back to the received request. + * 4. Methods (callbacks) of the MRCP engine channel MUST not block. + * (asynchronous response can be sent from the context of other thread) + * 5. Methods (callbacks) of the MPF engine stream MUST not block. + */ + +#include "mrcp_verifier_engine.h" +#include "mpf_activity_detector.h" +#include "apt_consumer_task.h" +#include "apt_log.h" + +#define VERIFIER_ENGINE_TASK_NAME "Demo Verifier Engine" + +typedef struct demo_verifier_engine_t demo_verifier_engine_t; +typedef struct demo_verifier_channel_t demo_verifier_channel_t; +typedef struct demo_verifier_msg_t demo_verifier_msg_t; + +/** Declaration of verification engine methods */ +static apt_bool_t demo_verifier_engine_destroy(mrcp_engine_t *engine); +static apt_bool_t demo_verifier_engine_open(mrcp_engine_t *engine); +static apt_bool_t demo_verifier_engine_close(mrcp_engine_t *engine); +static mrcp_engine_channel_t* demo_verifier_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool); + +static const struct mrcp_engine_method_vtable_t engine_vtable = { + demo_verifier_engine_destroy, + demo_verifier_engine_open, + demo_verifier_engine_close, + demo_verifier_engine_channel_create +}; + + +/** Declaration of verification channel methods */ +static apt_bool_t demo_verifier_channel_destroy(mrcp_engine_channel_t *channel); +static apt_bool_t demo_verifier_channel_open(mrcp_engine_channel_t *channel); +static apt_bool_t demo_verifier_channel_close(mrcp_engine_channel_t *channel); +static apt_bool_t demo_verifier_channel_request_process(mrcp_engine_channel_t *channel, mrcp_message_t *request); + +static const struct mrcp_engine_channel_method_vtable_t channel_vtable = { + demo_verifier_channel_destroy, + demo_verifier_channel_open, + demo_verifier_channel_close, + demo_verifier_channel_request_process +}; + +/** Declaration of verification audio stream methods */ +static apt_bool_t demo_verifier_stream_destroy(mpf_audio_stream_t *stream); +static apt_bool_t demo_verifier_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec); +static apt_bool_t demo_verifier_stream_close(mpf_audio_stream_t *stream); +static apt_bool_t demo_verifier_stream_write(mpf_audio_stream_t *stream, const mpf_frame_t *frame); + +static const mpf_audio_stream_vtable_t audio_stream_vtable = { + demo_verifier_stream_destroy, + NULL, + NULL, + NULL, + demo_verifier_stream_open, + demo_verifier_stream_close, + demo_verifier_stream_write +}; + +/** Declaration of demo verification engine */ +struct demo_verifier_engine_t { + apt_consumer_task_t *task; +}; + +/** Declaration of demo verification channel */ +struct demo_verifier_channel_t { + /** Back pointer to engine */ + demo_verifier_engine_t *demo_engine; + /** Engine channel base */ + mrcp_engine_channel_t *channel; + + /** Active (in-progress) verification request */ + mrcp_message_t *verifier_request; + /** Pending stop response */ + mrcp_message_t *stop_response; + /** Indicates whether input timers are started */ + apt_bool_t timers_started; + /** Voice activity detector */ + mpf_activity_detector_t *detector; + /** File to write voiceprint to */ + FILE *audio_out; +}; + +typedef enum { + DEMO_VERIF_MSG_OPEN_CHANNEL, + DEMO_VERIF_MSG_CLOSE_CHANNEL, + DEMO_VERIF_MSG_REQUEST_PROCESS +} demo_verifier_msg_type_e; + +/** Declaration of demo verification task message */ +struct demo_verifier_msg_t { + demo_verifier_msg_type_e type; + mrcp_engine_channel_t *channel; + mrcp_message_t *request; +}; + +static apt_bool_t demo_verifier_msg_signal(demo_verifier_msg_type_e type, mrcp_engine_channel_t *channel, mrcp_message_t *request); +static apt_bool_t demo_verifier_msg_process(apt_task_t *task, apt_task_msg_t *msg); + +static apt_bool_t demo_verifier_result_load(demo_verifier_channel_t *verifier_channel, mrcp_message_t *message); + +/** Declare this macro to set plugin version */ +MRCP_PLUGIN_VERSION_DECLARE + +/** Declare this macro to use log routine of the server, plugin is loaded from */ +MRCP_PLUGIN_LOGGER_IMPLEMENT + +/** Create demo verification engine */ +MRCP_PLUGIN_DECLARE(mrcp_engine_t*) mrcp_plugin_create(apr_pool_t *pool) +{ + demo_verifier_engine_t *demo_engine = apr_palloc(pool,sizeof(demo_verifier_engine_t)); + apt_task_t *task; + apt_task_vtable_t *vtable; + apt_task_msg_pool_t *msg_pool; + + msg_pool = apt_task_msg_pool_create_dynamic(sizeof(demo_verifier_msg_t),pool); + demo_engine->task = apt_consumer_task_create(demo_engine,msg_pool,pool); + if(!demo_engine->task) { + return NULL; + } + task = apt_consumer_task_base_get(demo_engine->task); + apt_task_name_set(task,VERIFIER_ENGINE_TASK_NAME); + vtable = apt_task_vtable_get(task); + if(vtable) { + vtable->process_msg = demo_verifier_msg_process; + } + + /* create engine base */ + return mrcp_engine_create( + MRCP_VERIFIER_RESOURCE, /* MRCP resource identifier */ + demo_engine, /* object to associate */ + &engine_vtable, /* virtual methods table of engine */ + pool); /* pool to allocate memory from */ +} + +/** Destroy verification engine */ +static apt_bool_t demo_verifier_engine_destroy(mrcp_engine_t *engine) +{ + demo_verifier_engine_t *demo_engine = engine->obj; + if(demo_engine->task) { + apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); + apt_task_destroy(task); + demo_engine->task = NULL; + } + return TRUE; +} + +/** Open verification engine */ +static apt_bool_t demo_verifier_engine_open(mrcp_engine_t *engine) +{ + demo_verifier_engine_t *demo_engine = engine->obj; + if(demo_engine->task) { + apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); + apt_task_start(task); + } + return mrcp_engine_open_respond(engine,TRUE); +} + +/** Close verification engine */ +static apt_bool_t demo_verifier_engine_close(mrcp_engine_t *engine) +{ + demo_verifier_engine_t *demo_engine = engine->obj; + if(demo_engine->task) { + apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); + apt_task_terminate(task,TRUE); + } + return mrcp_engine_close_respond(engine); +} + +static mrcp_engine_channel_t* demo_verifier_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool) +{ + mpf_stream_capabilities_t *capabilities; + mpf_termination_t *termination; + + /* create demo verification channel */ + demo_verifier_channel_t *verifier_channel = apr_palloc(pool,sizeof(demo_verifier_channel_t)); + verifier_channel->demo_engine = engine->obj; + verifier_channel->verifier_request = NULL; + verifier_channel->stop_response = NULL; + verifier_channel->detector = mpf_activity_detector_create(pool); + verifier_channel->audio_out = NULL; + + capabilities = mpf_sink_stream_capabilities_create(pool); + mpf_codec_capabilities_add( + &capabilities->codecs, + MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000, + "LPCM"); + + /* create media termination */ + termination = mrcp_engine_audio_termination_create( + verifier_channel, /* object to associate */ + &audio_stream_vtable, /* virtual methods table of audio stream */ + capabilities, /* stream capabilities */ + pool); /* pool to allocate memory from */ + + /* create engine channel base */ + verifier_channel->channel = mrcp_engine_channel_create( + engine, /* engine */ + &channel_vtable, /* virtual methods table of engine channel */ + verifier_channel, /* object to associate */ + termination, /* associated media termination */ + pool); /* pool to allocate memory from */ + + return verifier_channel->channel; +} + +/** Destroy engine channel */ +static apt_bool_t demo_verifier_channel_destroy(mrcp_engine_channel_t *channel) +{ + /* nothing to destrtoy */ + return TRUE; +} + +/** Open engine channel (asynchronous response MUST be sent)*/ +static apt_bool_t demo_verifier_channel_open(mrcp_engine_channel_t *channel) +{ + return demo_verifier_msg_signal(DEMO_VERIF_MSG_OPEN_CHANNEL,channel,NULL); +} + +/** Close engine channel (asynchronous response MUST be sent)*/ +static apt_bool_t demo_verifier_channel_close(mrcp_engine_channel_t *channel) +{ + return demo_verifier_msg_signal(DEMO_VERIF_MSG_CLOSE_CHANNEL,channel,NULL); +} + +/** Process MRCP channel request (asynchronous response MUST be sent)*/ +static apt_bool_t demo_verifier_channel_request_process(mrcp_engine_channel_t *channel, mrcp_message_t *request) +{ + return demo_verifier_msg_signal(DEMO_VERIF_MSG_REQUEST_PROCESS,channel,request); +} + +/** Process VERIFY request */ +static apt_bool_t demo_verifier_channel_verify(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) +{ + /* process verify request */ + mrcp_verifier_header_t *verifier_header; + demo_verifier_channel_t *verifier_channel = channel->method_obj; + verifier_channel->timers_started = TRUE; + + /* get verifier header */ + verifier_header = mrcp_resource_header_get(request); + if(verifier_header) { + if(mrcp_resource_header_property_check(request,VERIFIER_HEADER_START_INPUT_TIMERS) == TRUE) { + verifier_channel->timers_started = verifier_header->start_input_timers; + } + if(mrcp_resource_header_property_check(request,VERIFIER_HEADER_NO_INPUT_TIMEOUT) == TRUE) { + mpf_activity_detector_noinput_timeout_set(verifier_channel->detector,verifier_header->no_input_timeout); + } + if(mrcp_resource_header_property_check(request,VERIFIER_HEADER_SPEECH_COMPLETE_TIMEOUT) == TRUE) { + mpf_activity_detector_silence_timeout_set(verifier_channel->detector,verifier_header->speech_complete_timeout); + } + } + + if(!verifier_channel->audio_out) { + const apt_dir_layout_t *dir_layout = channel->engine->dir_layout; + const mpf_codec_descriptor_t *descriptor = mrcp_engine_sink_stream_codec_get(channel); + char *file_name = apr_psprintf(channel->pool,"voiceprint-%dkHz-%s.pcm", + descriptor ? descriptor->sampling_rate/1000 : 8, + request->channel_id.session_id.buf); + char *file_path = apt_datadir_filepath_get(dir_layout,file_name,channel->pool); + if(file_path) { + verifier_channel->audio_out = fopen(file_path,"wb"); + } + } + + response->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS; + /* send asynchronous response */ + mrcp_engine_channel_message_send(channel,response); + verifier_channel->verifier_request = request; + return TRUE; +} + +/** Process STOP request */ +static apt_bool_t demo_verifier_channel_stop(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) +{ + /* process STOP request */ + demo_verifier_channel_t *verifier_channel = channel->method_obj; + /* store STOP request, make sure there is no more activity and only then send the response */ + verifier_channel->stop_response = response; + return TRUE; +} + +/** Process START-INPUT-TIMERS request */ +static apt_bool_t demo_verifier_channel_timers_start(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) +{ + demo_verifier_channel_t *verifier_channel = channel->method_obj; + verifier_channel->timers_started = TRUE; + return mrcp_engine_channel_message_send(channel,response); +} + +/** Process GET-INTERMEDIATE-RESULT request */ +static apt_bool_t demo_verifier_channel_get_result(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) +{ + demo_verifier_channel_t *verifier_channel = channel->method_obj; + demo_verifier_result_load(verifier_channel,response); + return mrcp_engine_channel_message_send(channel,response); +} + + +/** Dispatch MRCP request */ +static apt_bool_t demo_verifier_channel_request_dispatch(mrcp_engine_channel_t *channel, mrcp_message_t *request) +{ + apt_bool_t processed = FALSE; + mrcp_message_t *response = mrcp_response_create(request,request->pool); + switch(request->start_line.method_id) { + case VERIFIER_SET_PARAMS: + break; + case VERIFIER_GET_PARAMS: + break; + case VERIFIER_START_SESSION: + break; + case VERIFIER_END_SESSION: + break; + case VERIFIER_QUERY_VOICEPRINT: + break; + case VERIFIER_DELETE_VOICEPRINT: + break; + case VERIFIER_VERIFY: + processed = demo_verifier_channel_verify(channel,request,response); + break; + case VERIFIER_VERIFY_FROM_BUFFER: + break; + case VERIFIER_VERIFY_ROLLBACK: + break; + case VERIFIER_STOP: + processed = demo_verifier_channel_stop(channel,request,response); + break; + case VERIFIER_CLEAR_BUFFER: + break; + case VERIFIER_START_INPUT_TIMERS: + processed = demo_verifier_channel_timers_start(channel,request,response); + break; + case VERIFIER_GET_INTERMIDIATE_RESULT: + processed = demo_verifier_channel_get_result(channel,request,response); + break; + + default: + break; + } + if(processed == FALSE) { + /* send asynchronous response for not handled request */ + mrcp_engine_channel_message_send(channel,response); + } + return TRUE; +} + +/** Callback is called from MPF engine context to destroy any additional data associated with audio stream */ +static apt_bool_t demo_verifier_stream_destroy(mpf_audio_stream_t *stream) +{ + return TRUE; +} + +/** Callback is called from MPF engine context to perform any action before open */ +static apt_bool_t demo_verifier_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec) +{ + return TRUE; +} + +/** Callback is called from MPF engine context to perform any action after close */ +static apt_bool_t demo_verifier_stream_close(mpf_audio_stream_t *stream) +{ + return TRUE; +} + +/* Raise demo START-OF-INPUT event */ +static apt_bool_t demo_verifier_start_of_input(demo_verifier_channel_t *verifier_channel) +{ + /* create START-OF-INPUT event */ + mrcp_message_t *message = mrcp_event_create( + verifier_channel->verifier_request, + VERIFIER_START_OF_INPUT, + verifier_channel->verifier_request->pool); + if(!message) { + return FALSE; + } + + /* set request state */ + message->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS; + /* send asynch event */ + return mrcp_engine_channel_message_send(verifier_channel->channel,message); +} + +/* Load demo verification result */ +static apt_bool_t demo_verifier_result_load(demo_verifier_channel_t *verifier_channel, mrcp_message_t *message) +{ + FILE *file; + mrcp_engine_channel_t *channel = verifier_channel->channel; + const apt_dir_layout_t *dir_layout = channel->engine->dir_layout; + char *file_path = apt_datadir_filepath_get(dir_layout,"result-verification.xml",message->pool); + if(!file_path) { + return FALSE; + } + + /* read the demo result from file */ + file = fopen(file_path,"r"); + if(file) { + mrcp_generic_header_t *generic_header; + char text[1024]; + apr_size_t size; + size = fread(text,1,sizeof(text),file); + apt_string_assign_n(&message->body,text,size,message->pool); + fclose(file); + + /* get/allocate generic header */ + generic_header = mrcp_generic_header_prepare(message); + if(generic_header) { + /* set content types */ + apt_string_assign(&generic_header->content_type,"application/nlsml+xml",message->pool); + mrcp_generic_header_property_add(message,GENERIC_HEADER_CONTENT_TYPE); + } + } + return TRUE; +} + +/* Raise demo VERIFICATION-COMPLETE event */ +static apt_bool_t demo_verifier_verification_complete(demo_verifier_channel_t *verifier_channel, mrcp_verifier_completion_cause_e cause) +{ + mrcp_verifier_header_t *verifier_header; + /* create VERIFICATION-COMPLETE event */ + mrcp_message_t *message = mrcp_event_create( + verifier_channel->verifier_request, + VERIFIER_VERIFICATION_COMPLETE, + verifier_channel->verifier_request->pool); + if(!message) { + return FALSE; + } + + /* get/allocate verifier header */ + verifier_header = mrcp_resource_header_prepare(message); + if(verifier_header) { + /* set completion cause */ + verifier_header->completion_cause = cause; + mrcp_resource_header_property_add(message,VERIFIER_HEADER_COMPLETION_CAUSE); + } + /* set request state */ + message->start_line.request_state = MRCP_REQUEST_STATE_COMPLETE; + + if(cause == VERIFIER_COMPLETION_CAUSE_SUCCESS) { + demo_verifier_result_load(verifier_channel,message); + } + + verifier_channel->verifier_request = NULL; + /* send asynch event */ + return mrcp_engine_channel_message_send(verifier_channel->channel,message); +} + +/** Callback is called from MPF engine context to write/send new frame */ +static apt_bool_t demo_verifier_stream_write(mpf_audio_stream_t *stream, const mpf_frame_t *frame) +{ + demo_verifier_channel_t *verifier_channel = stream->obj; + if(verifier_channel->stop_response) { + /* send asynchronous response to STOP request */ + mrcp_engine_channel_message_send(verifier_channel->channel,verifier_channel->stop_response); + verifier_channel->stop_response = NULL; + verifier_channel->verifier_request = NULL; + return TRUE; + } + + if(verifier_channel->verifier_request) { + mpf_detector_event_e det_event = mpf_activity_detector_process(verifier_channel->detector,frame); + switch(det_event) { + case MPF_DETECTOR_EVENT_ACTIVITY: + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Voice Activity "APT_SIDRES_FMT, + MRCP_MESSAGE_SIDRES(verifier_channel->verifier_request)); + demo_verifier_start_of_input(verifier_channel); + break; + case MPF_DETECTOR_EVENT_INACTIVITY: + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Voice Inactivity "APT_SIDRES_FMT, + MRCP_MESSAGE_SIDRES(verifier_channel->verifier_request)); + demo_verifier_verification_complete(verifier_channel,VERIFIER_COMPLETION_CAUSE_SUCCESS); + break; + case MPF_DETECTOR_EVENT_NOINPUT: + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Noinput "APT_SIDRES_FMT, + MRCP_MESSAGE_SIDRES(verifier_channel->verifier_request)); + if(verifier_channel->timers_started == TRUE) { + demo_verifier_verification_complete(verifier_channel,VERIFIER_COMPLETION_CAUSE_NO_INPUT_TIMEOUT); + } + break; + default: + break; + } + + if((frame->type & MEDIA_FRAME_TYPE_EVENT) == MEDIA_FRAME_TYPE_EVENT) { + if(frame->marker == MPF_MARKER_START_OF_EVENT) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected Start of Event "APT_SIDRES_FMT" id:%d", + MRCP_MESSAGE_SIDRES(verifier_channel->verifier_request), + frame->event_frame.event_id); + } + else if(frame->marker == MPF_MARKER_END_OF_EVENT) { + apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Detected End of Event "APT_SIDRES_FMT" id:%d duration:%d ts", + MRCP_MESSAGE_SIDRES(verifier_channel->verifier_request), + frame->event_frame.event_id, + frame->event_frame.duration); + } + } + + if(verifier_channel->audio_out) { + fwrite(frame->codec_frame.buffer,1,frame->codec_frame.size,verifier_channel->audio_out); + } + } + return TRUE; +} + +static apt_bool_t demo_verifier_msg_signal(demo_verifier_msg_type_e type, mrcp_engine_channel_t *channel, mrcp_message_t *request) +{ + apt_bool_t status = FALSE; + demo_verifier_channel_t *demo_channel = channel->method_obj; + demo_verifier_engine_t *demo_engine = demo_channel->demo_engine; + apt_task_t *task = apt_consumer_task_base_get(demo_engine->task); + apt_task_msg_t *msg = apt_task_msg_get(task); + if(msg) { + demo_verifier_msg_t *demo_msg; + msg->type = TASK_MSG_USER; + demo_msg = (demo_verifier_msg_t*) msg->data; + + demo_msg->type = type; + demo_msg->channel = channel; + demo_msg->request = request; + status = apt_task_msg_signal(task,msg); + } + return status; +} + +static apt_bool_t demo_verifier_msg_process(apt_task_t *task, apt_task_msg_t *msg) +{ + demo_verifier_msg_t *demo_msg = (demo_verifier_msg_t*)msg->data; + switch(demo_msg->type) { + case DEMO_VERIF_MSG_OPEN_CHANNEL: + /* open channel and send asynch response */ + mrcp_engine_channel_open_respond(demo_msg->channel,TRUE); + break; + case DEMO_VERIF_MSG_CLOSE_CHANNEL: + { + /* close channel, make sure there is no activity and send asynch response */ + demo_verifier_channel_t *verifier_channel = demo_msg->channel->method_obj; + if(verifier_channel->audio_out) { + fclose(verifier_channel->audio_out); + verifier_channel->audio_out = NULL; + } + + mrcp_engine_channel_close_respond(demo_msg->channel); + break; + } + case DEMO_VERIF_MSG_REQUEST_PROCESS: + demo_verifier_channel_request_dispatch(demo_msg->channel,demo_msg->request); + break; + default: + break; + } + return TRUE; +} diff --git a/libs/unimrcp/plugins/mrcp-cepstral/mrcpcepstral.2008.vcproj b/libs/unimrcp/plugins/mrcp-cepstral/mrcpcepstral.2008.vcproj deleted file mode 100644 index abdb4cec4c..0000000000 --- a/libs/unimrcp/plugins/mrcp-cepstral/mrcpcepstral.2008.vcproj +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/plugins/mrcp-cepstral/src/mrcp_swift.c b/libs/unimrcp/plugins/mrcp-cepstral/src/mrcp_swift.c deleted file mode 100644 index 037939b8dd..0000000000 --- a/libs/unimrcp/plugins/mrcp-cepstral/src/mrcp_swift.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Copyright 2008 Arsen Chaloyan - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Mandatory rules concerning plugin implementation. - * 1. Each plugin MUST implement a plugin/engine creator function - * with the exact signature and name (the main entry point) - * MRCP_PLUGIN_DECLARE(mrcp_engine_t*) mrcp_plugin_create(apr_pool_t *pool) - * 2. Each plugin MUST declare its version number - * MRCP_PLUGIN_VERSION_DECLARE - * 3. One and only one response MUST be sent back to the received request. - * 4. Methods (callbacks) of the MRCP engine channel MUST not block. - * (asynchronous response can be sent from the context of other thread) - * 5. Methods (callbacks) of the MPF engine stream MUST not block. - */ - -#include -#include -#include "mrcp_synth_engine.h" -#include "mpf_buffer.h" -#include "apt_log.h" - -/** Declaration of synthesizer engine methods */ -static apt_bool_t mrcp_swift_engine_destroy(mrcp_engine_t *engine); -static apt_bool_t mrcp_swift_engine_open(mrcp_engine_t *engine); -static apt_bool_t mrcp_swift_engine_close(mrcp_engine_t *engine); -static mrcp_engine_channel_t* mrcp_swift_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool); - -static const struct mrcp_engine_method_vtable_t engine_vtable = { - mrcp_swift_engine_destroy, - mrcp_swift_engine_open, - mrcp_swift_engine_close, - mrcp_swift_engine_channel_create -}; - - -/** Declaration of synthesizer channel methods */ -static apt_bool_t mrcp_swift_channel_destroy(mrcp_engine_channel_t *channel); -static apt_bool_t mrcp_swift_channel_open(mrcp_engine_channel_t *channel); -static apt_bool_t mrcp_swift_channel_close(mrcp_engine_channel_t *channel); -static apt_bool_t mrcp_swift_channel_request_process(mrcp_engine_channel_t *channel, mrcp_message_t *request); - -static const struct mrcp_engine_channel_method_vtable_t channel_vtable = { - mrcp_swift_channel_destroy, - mrcp_swift_channel_open, - mrcp_swift_channel_close, - mrcp_swift_channel_request_process -}; - -/** Declaration of synthesizer audio stream methods */ -static apt_bool_t synth_stream_destroy(mpf_audio_stream_t *stream); -static apt_bool_t synth_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec); -static apt_bool_t synth_stream_close(mpf_audio_stream_t *stream); -static apt_bool_t synth_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame); - -static const mpf_audio_stream_vtable_t audio_stream_vtable = { - synth_stream_destroy, - synth_stream_open, - synth_stream_close, - synth_stream_read, - NULL, - NULL, - NULL -}; - -typedef struct mrcp_swift_engine_t mrcp_swift_engine_t; -/** Declaration of Swift synthesizer engine */ -struct mrcp_swift_engine_t { - /** Swift synthesizer engine */ - swift_engine *swift; - /** Speech language mapping */ - apr_table_t *language_table; - /** Sampling rates (bitmask of mpf_sample_rates_e) - installed voices support */ - int sample_rates; -}; - -typedef struct mrcp_swift_channel_t mrcp_swift_channel_t; -/** Declaration of Swift synthesizer channel */ -struct mrcp_swift_channel_t { - /** Swift port */ - swift_port *port; - swift_background_t tts_stream; - - /** Audio buffer */ - mpf_buffer_t *audio_buffer; - - /** Engine channel base */ - mrcp_engine_channel_t *channel; - - /** Active (in-progress) speak request */ - mrcp_message_t *speak_request; - /** Pending stop response */ - mrcp_message_t *stop_response; - /** Is paused */ - apt_bool_t paused; -}; - -/** Table of prosody volumes for Swift engine */ -static const int swift_prosody_volume_table[PROSODY_VOLUME_COUNT] = { - 25, /* PROSODY_VOLUME_SILENT */ - 50, /* PROSODY_VOLUME_XSOFT */ - 75, /* PROSODY_VOLUME_SOFT */ - 100, /* PROSODY_VOLUME_MEDIUM */ - 125, /* PROSODY_VOLUME_LOUD */ - 150, /* PROSODY_VOLUME_XLOUD */ - 100 /* PROSODY_VOLUME_DEFAULT */ -}; - -/** Table of prosody rates for Swift engine */ -static const int swift_prosody_rate_table[PROSODY_RATE_COUNT] = { - 85, /* PROSODY_RATE_XSLOW */ - 113, /* PROSODY_RATE_SLOW */ - 170, /* PROSODY_RATE_MEDIUM */ - 225, /* PROSODY_RATE_FAST */ - 340, /* PROSODY_RATE_XFAST */ - 170 /* PROSODY_RATE_DEFAULT */ -}; - - -static apr_table_t* mrcp_swift_language_table_create(apr_pool_t *pool); -static apt_bool_t mrcp_swift_voices_scan(mrcp_swift_engine_t *engine); -static swift_result_t mrcp_swift_write_audio(swift_event *event, swift_event_t type, void *udata); -static apt_bool_t mrcp_swift_channel_voice_set(mrcp_swift_channel_t *synth_channel, mrcp_message_t *message); -static apt_bool_t mrcp_swift_channel_params_set(mrcp_swift_channel_t *synth_channel, mrcp_message_t *message); - -/** Declare this macro to set plugin version */ -MRCP_PLUGIN_VERSION_DECLARE - -/** Declare this macro to use log routine of the server, plugin is loaded from */ -MRCP_PLUGIN_LOGGER_IMPLEMENT - -/** Create Swift synthesizer engine */ -MRCP_PLUGIN_DECLARE(mrcp_engine_t*) mrcp_plugin_create(apr_pool_t *pool) -{ - mrcp_swift_engine_t *synth_engine = apr_palloc(pool,sizeof(mrcp_swift_engine_t)); - synth_engine->swift = NULL; - synth_engine->language_table = mrcp_swift_language_table_create(pool); - synth_engine->sample_rates = MPF_SAMPLE_RATE_NONE; - - /* create engine base */ - return mrcp_engine_create( - MRCP_SYNTHESIZER_RESOURCE, /* MRCP resource identifier */ - synth_engine, /* object to associate */ - &engine_vtable, /* virtual methods table of engine */ - pool); /* pool to allocate memory from */ -} - -/** Destroy synthesizer engine */ -static apt_bool_t mrcp_swift_engine_destroy(mrcp_engine_t *engine) -{ - /* nothing to destroy */ - return TRUE; -} - -/** Open synthesizer engine */ -static apt_bool_t mrcp_swift_engine_open(mrcp_engine_t *engine) -{ - mrcp_swift_engine_t *synth_engine = engine->obj; - - /* open swift engine */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open Swift Engine [%s]",swift_version); - if((synth_engine->swift = swift_engine_open(NULL)) == NULL) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Swift Engine"); - return FALSE; - } - - if(mrcp_swift_voices_scan(synth_engine) == FALSE) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Scan Swift Voices"); - swift_engine_close(synth_engine->swift); - synth_engine->swift = NULL; - return FALSE; - } - return TRUE; -} - -/** Close synthesizer engine */ -static apt_bool_t mrcp_swift_engine_close(mrcp_engine_t *engine) -{ - mrcp_swift_engine_t *synth_engine = engine->obj; - - /* close swift engine */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close Swift Engine"); - if(synth_engine->swift) { - swift_engine_close(synth_engine->swift); - synth_engine->swift = NULL; - } - return TRUE; -} - -/** Create demo synthesizer channel derived from engine channel base */ -static mrcp_engine_channel_t* mrcp_swift_engine_channel_create(mrcp_engine_t *engine, apr_pool_t *pool) -{ - mrcp_swift_engine_t *synth_engine = engine->obj; - - mpf_stream_capabilities_t *capabilities; - mpf_termination_t *termination; - mrcp_engine_channel_t *channel; - - /* create swift synth channel */ - mrcp_swift_channel_t *synth_channel = apr_palloc(pool,sizeof(mrcp_swift_channel_t)); - synth_channel->port = NULL; - synth_channel->tts_stream = 0; - synth_channel->channel = NULL; - synth_channel->audio_buffer = NULL; - synth_channel->speak_request = NULL; - synth_channel->stop_response = NULL; - synth_channel->paused = FALSE; - - capabilities = mpf_source_stream_capabilities_create(pool); - mpf_codec_capabilities_add( - &capabilities->codecs, - synth_engine->sample_rates, - "LPCM"); - - /* create media termination */ - termination = mrcp_engine_audio_termination_create( - synth_channel, /* object to associate */ - &audio_stream_vtable, /* virtual methods table of audio stream */ - capabilities, /* stream capabilities */ - pool); /* pool to allocate memory from */ - - /* create engine channel base */ - channel = mrcp_engine_channel_create( - engine, /* engine */ - &channel_vtable, /* virtual methods table of engine channel */ - synth_channel, /* object to associate */ - termination, /* associated media termination */ - pool); /* pool to allocate memory from */ - - if(channel) { - synth_channel->audio_buffer = mpf_buffer_create(pool); - } - synth_channel->channel = channel; - return channel; -} - -/** Destroy engine channel */ -static apt_bool_t mrcp_swift_channel_destroy(mrcp_engine_channel_t *channel) -{ - /* nothing to destroy */ - return TRUE; -} - -/** Open engine channel (asynchronous response MUST be sent)*/ -static apt_bool_t mrcp_swift_channel_open(mrcp_engine_channel_t *channel) -{ - /* open channel and send asynch response */ - apt_bool_t status = FALSE; - mrcp_swift_channel_t *synth_channel = channel->method_obj; - mrcp_swift_engine_t *synth_engine = channel->engine->obj; - const mpf_codec_descriptor_t *descriptor = mrcp_engine_source_stream_codec_get(synth_channel->channel); - if(descriptor) { - swift_params *params; - swift_port *port; - - params = swift_params_new(NULL); - swift_params_set_string(params, "audio/encoding", "pcm16"); - swift_params_set_int(params, "audio/sampling-rate", descriptor->sampling_rate); - /* open swift port */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open Swift Port"); - port = swift_port_open(synth_engine->swift,params); - if(port) { - /* set swift_write_audio as a callback, with the output file as its param */ - swift_port_set_callback(port, &mrcp_swift_write_audio, SWIFT_EVENT_AUDIO | SWIFT_EVENT_END, synth_channel); - synth_channel->port = port; - status = TRUE; - } - else { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Swift Port"); - } - } - - return mrcp_engine_channel_open_respond(channel,status); -} - -/** Close engine channel (asynchronous response MUST be sent)*/ -static apt_bool_t mrcp_swift_channel_close(mrcp_engine_channel_t *channel) -{ - /* close channel, make sure there is no activity and send asynch response */ - mrcp_swift_channel_t *synth_channel = channel->method_obj; - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close Swift Port"); - if(synth_channel->port) { - /* close swift port */ - swift_port_close(synth_channel->port); - synth_channel->port = NULL; - } - - return mrcp_engine_channel_close_respond(channel); -} - -/** Process SPEAK request */ -static apt_bool_t mrcp_swift_channel_speak(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) -{ - mrcp_swift_channel_t *synth_channel = channel->method_obj; - - /* set voice */ - mrcp_swift_channel_voice_set(synth_channel,request); - /* set params */ - mrcp_swift_channel_params_set(synth_channel,request); - /* (re)start audio buffer */ - mpf_buffer_restart(synth_channel->audio_buffer); - response->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS; - /* start to synthesize */ - if(swift_port_speak_text(synth_channel->port,request->body.buf,0,NULL,&synth_channel->tts_stream,NULL) != SWIFT_SUCCESS) { - response->start_line.request_state = MRCP_REQUEST_STATE_COMPLETE; - response->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED; - } - /* send asynchronous response */ - mrcp_engine_channel_message_send(channel,response); - synth_channel->speak_request = request; - return TRUE; -} - -/** Process STOP request */ -static apt_bool_t mrcp_swift_channel_stop(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) -{ - mrcp_swift_channel_t *synth_channel = channel->method_obj; - /* store the request, make sure there is no more activity and only then send the response */ - swift_port_stop(synth_channel->port,synth_channel->tts_stream,SWIFT_EVENT_NOW); - synth_channel->stop_response = response; - return TRUE; -} - -/** Process PAUSE request */ -static apt_bool_t mrcp_swift_channel_pause(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) -{ - mrcp_swift_channel_t *synth_channel = channel->method_obj; - synth_channel->paused = TRUE; - /* send asynchronous response */ - mrcp_engine_channel_message_send(channel,response); - return TRUE; -} - -/** Process RESUME request */ -static apt_bool_t mrcp_swift_channel_resume(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) -{ - mrcp_swift_channel_t *synth_channel = channel->method_obj; - synth_channel->paused = FALSE; - /* send asynchronous response */ - mrcp_engine_channel_message_send(channel,response); - return TRUE; -} - -/** Process CONTROL request */ -static apt_bool_t mrcp_swift_channel_control(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response) -{ - mrcp_swift_channel_t *synth_channel = channel->method_obj; - /* set params */ - mrcp_swift_channel_params_set(synth_channel,request); - /* send asynchronous response */ - mrcp_engine_channel_message_send(channel,response); - return TRUE; -} - -/** Process MRCP channel request (asynchronous response MUST be sent)*/ -static apt_bool_t mrcp_swift_channel_request_process(mrcp_engine_channel_t *channel, mrcp_message_t *request) -{ - apt_bool_t processed = FALSE; - mrcp_message_t *response = mrcp_response_create(request,request->pool); - switch(request->start_line.method_id) { - case SYNTHESIZER_SET_PARAMS: - break; - case SYNTHESIZER_GET_PARAMS: - break; - case SYNTHESIZER_SPEAK: - processed = mrcp_swift_channel_speak(channel,request,response); - break; - case SYNTHESIZER_STOP: - processed = mrcp_swift_channel_stop(channel,request,response); - break; - case SYNTHESIZER_PAUSE: - processed = mrcp_swift_channel_pause(channel,request,response); - break; - case SYNTHESIZER_RESUME: - processed = mrcp_swift_channel_resume(channel,request,response); - break; - case SYNTHESIZER_BARGE_IN_OCCURRED: - processed = mrcp_swift_channel_stop(channel,request,response); - break; - case SYNTHESIZER_CONTROL: - processed = mrcp_swift_channel_control(channel,request,response); - break; - case SYNTHESIZER_DEFINE_LEXICON: - break; - default: - break; - } - if(processed == FALSE) { - /* send asynchronous response for not handled request */ - mrcp_engine_channel_message_send(channel,response); - } - return TRUE; -} - - - -/** Callback is called from MPF engine context to destroy any additional data associated with audio stream */ -static apt_bool_t synth_stream_destroy(mpf_audio_stream_t *stream) -{ - return TRUE; -} - -/** Callback is called from MPF engine context to perform any action before open */ -static apt_bool_t synth_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec) -{ - return TRUE; -} - -/** Callback is called from MPF engine context to perform any action after close */ -static apt_bool_t synth_stream_close(mpf_audio_stream_t *stream) -{ - return TRUE; -} - -/** Raise SPEAK-COMPLETE event */ -static apt_bool_t synth_speak_complete_raise(mrcp_swift_channel_t *synth_channel) -{ - mrcp_message_t *message; - mrcp_synth_header_t *synth_header; - if(!synth_channel->speak_request) { - return FALSE; - } - message = mrcp_event_create( - synth_channel->speak_request, - SYNTHESIZER_SPEAK_COMPLETE, - synth_channel->speak_request->pool); - if(!message) { - return FALSE; - } - - /* get/allocate synthesizer header */ - synth_header = mrcp_resource_header_prepare(message); - if(synth_header) { - /* set completion cause */ - synth_header->completion_cause = SYNTHESIZER_COMPLETION_CAUSE_NORMAL; - mrcp_resource_header_property_add(message,SYNTHESIZER_HEADER_COMPLETION_CAUSE); - } - /* set request state */ - message->start_line.request_state = MRCP_REQUEST_STATE_COMPLETE; - - synth_channel->speak_request = NULL; - /* send asynch event */ - return mrcp_engine_channel_message_send(synth_channel->channel,message); -} - -/** Callback is called from MPF engine context to read/get new frame */ -static apt_bool_t synth_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame) -{ - mrcp_swift_channel_t *synth_channel = stream->obj; - /* check if STOP was requested */ - if(synth_channel->stop_response) { - /* send asynchronous response to STOP request */ - mrcp_engine_channel_message_send(synth_channel->channel,synth_channel->stop_response); - synth_channel->stop_response = NULL; - synth_channel->speak_request = NULL; - synth_channel->paused = FALSE; - return TRUE; - } - - /* check if there is active SPEAK request and it isn't in paused state */ - if(synth_channel->speak_request && synth_channel->paused == FALSE) { - /* normal processing */ - mpf_buffer_frame_read(synth_channel->audio_buffer,frame); - - if((frame->type & MEDIA_FRAME_TYPE_EVENT) == MEDIA_FRAME_TYPE_EVENT) { - synth_speak_complete_raise(synth_channel); - } - } - return TRUE; -} - -/** Swift engine callback */ -static swift_result_t mrcp_swift_write_audio(swift_event *event, swift_event_t type, void *udata) -{ - void *buf; - int len; - mrcp_swift_channel_t *synth_channel = udata; - swift_event_t rv = SWIFT_SUCCESS; - - if(type & SWIFT_EVENT_END) { - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Swift Engine: Write End-of-Speech Event"); - mpf_buffer_event_write(synth_channel->audio_buffer,MEDIA_FRAME_TYPE_EVENT); - return rv; - } - - rv = swift_event_get_audio(event, &buf, &len); - if(!SWIFT_FAILED(rv)) { -#if 0 - /* Get the event times */ - float time_start, time_len; - swift_event_get_times(event, &time_start, &time_len); - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Swift Engine: Write Audio [%d | %0.4f | %0.4f]",len, time_start, time_len); -#endif - mpf_buffer_audio_write(synth_channel->audio_buffer,buf,len); - } - - return rv; -} - -/** Add delimiter (&) to search criteria */ -static APR_INLINE int search_criteria_delimiter_add(char *search_criteria, int size, apt_bool_t initial) -{ - if(initial == FALSE && size >= 3) { - search_criteria[0] = ' '; - search_criteria[1] = '&'; - search_criteria[2] = ' '; - return 3; - } - return 0; -} - -/** Set voice matching specified criteria */ -static apt_bool_t mrcp_swift_channel_voice_set(mrcp_swift_channel_t *synth_channel, mrcp_message_t *message) -{ - mrcp_synth_header_t *synth_header = mrcp_resource_header_get(message); - char search_criteria[1024]; - int offset = 0; - swift_voice *voice; - swift_result_t res; - - if(!synth_header) { - /* no params to set */ - return TRUE; - } - - if(mrcp_resource_header_property_check(message,SYNTHESIZER_HEADER_VOICE_NAME) == TRUE) { - offset += search_criteria_delimiter_add(search_criteria+offset,sizeof(search_criteria)-offset,(offset == 0)); - offset += apr_snprintf(search_criteria+offset,sizeof(search_criteria)-offset,"speaker/name=%s",synth_header->voice_param.name.buf); - } - if(mrcp_resource_header_property_check(message,SYNTHESIZER_HEADER_VOICE_GENDER) == TRUE) { - switch(synth_header->voice_param.gender) { - case VOICE_GENDER_MALE: - offset += search_criteria_delimiter_add(search_criteria+offset,sizeof(search_criteria)-offset,offset == 0); - offset += apr_snprintf(search_criteria+offset,sizeof(search_criteria)-offset,"speaker/gender=male"); - break; - case VOICE_GENDER_FEMALE: - offset += search_criteria_delimiter_add(search_criteria+offset,sizeof(search_criteria)-offset,offset == 0); - offset += apr_snprintf(search_criteria+offset,sizeof(search_criteria)-offset,"speaker/gender=female"); - break; - default: - break; - } - } - if(mrcp_resource_header_property_check(message,SYNTHESIZER_HEADER_VOICE_AGE) == TRUE) { - offset += search_criteria_delimiter_add(search_criteria+offset,sizeof(search_criteria)-offset,offset == 0); - offset += apr_snprintf(search_criteria+offset,sizeof(search_criteria)-offset,"speaker/age=%d",synth_header->voice_param.age); - } - if(mrcp_resource_header_property_check(message,SYNTHESIZER_HEADER_SPEECH_LANGUAGE) == TRUE) { - const char *swift_lang_name = NULL; - mrcp_engine_t *engine = synth_channel->channel->engine; - mrcp_swift_engine_t *synth_engine = engine->obj; - if(synth_engine && synth_engine->language_table) { - swift_lang_name = apr_table_get(synth_engine->language_table,synth_header->speech_language.buf); - } - if(!swift_lang_name) { - swift_lang_name = synth_header->speech_language.buf; - } - offset += search_criteria_delimiter_add(search_criteria+offset,sizeof(search_criteria)-offset,offset == 0); - offset += apr_snprintf(search_criteria+offset,sizeof(search_criteria)-offset,"language/name=%s",swift_lang_name); - } - - if(offset > 0) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Find Swift Voice Matching the Criteria [%s]", search_criteria); - voice = swift_port_find_first_voice(synth_channel->port,search_criteria,NULL); - if(!voice) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"No Swift Voice Available Matching the Criteria [%s]",search_criteria); - /* find the first available one */ - voice = swift_port_find_first_voice(synth_channel->port,NULL,NULL); - } - - if(voice) { - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set Swift Voice [%s]", - swift_voice_get_attribute(voice, "name")); - if(SWIFT_FAILED(res = swift_port_set_voice(synth_channel->port,voice)) ) { - const char *error_string = swift_strerror(res); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,error_string); - return FALSE; - } - } - } - return TRUE; -} - -/** Get volume by prosody params */ -static apt_bool_t swift_prosody_volume_get(const mrcp_prosody_volume_t *prosody_volume, int *volume) -{ - apt_bool_t res = FALSE; - if(prosody_volume->type == PROSODY_VOLUME_TYPE_LABEL) { - if(prosody_volume->value.label < PROSODY_VOLUME_COUNT) { - *volume = swift_prosody_volume_table[prosody_volume->value.label]; - res = TRUE; - } - } - else if(prosody_volume->type == PROSODY_VOLUME_TYPE_NUMERIC) { - *volume = (int)prosody_volume->value.numeric; - res = TRUE; - } - else if(prosody_volume->type == PROSODY_VOLUME_TYPE_RELATIVE_CHANGE) { - int def = swift_prosody_volume_table[PROSODY_VOLUME_DEFAULT]; - *volume = (int)(prosody_volume->value.relative * def); - res = TRUE; - } - return res; -} - -/** Get rate by prosody params */ -static apt_bool_t swift_prosody_rate_get(const mrcp_prosody_rate_t *prosody_rate, int *rate) -{ - apt_bool_t res = FALSE; - if(prosody_rate->type == PROSODY_RATE_TYPE_LABEL) { - if(prosody_rate->value.label < PROSODY_RATE_COUNT) { - *rate = swift_prosody_rate_table[prosody_rate->value.label]; - res = TRUE; - } - } - else if(prosody_rate->type == PROSODY_RATE_TYPE_RELATIVE_CHANGE) { - int def = swift_prosody_rate_table[PROSODY_RATE_DEFAULT]; - *rate = (int)(prosody_rate->value.relative * def); - res = TRUE; - } - return res; -} - - -/** Set Swift port param */ -static apt_bool_t mrcp_swift_channel_param_set(mrcp_swift_channel_t *synth_channel, const char *name, swift_val *val) -{ - swift_result_t res; - if(SWIFT_FAILED(res = swift_port_set_param(synth_channel->port,name,val,synth_channel->tts_stream)) ) { - const char *error_string = swift_strerror(res); - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Swift Param %s: %s",name,error_string); - return FALSE; - } - return TRUE; -} - -/** Set Swift port params */ -static apt_bool_t mrcp_swift_channel_params_set(mrcp_swift_channel_t *synth_channel, mrcp_message_t *message) -{ - const char *name; - mrcp_synth_header_t *synth_header = mrcp_resource_header_get(message); - mrcp_generic_header_t *generic_header = mrcp_generic_header_get(message); - - if(synth_header) { - if(mrcp_resource_header_property_check(message,SYNTHESIZER_HEADER_PROSODY_VOLUME) == TRUE) { - int volume = 0; - if(swift_prosody_volume_get(&synth_header->prosody_param.volume,&volume) == TRUE) { - name = "audio/volume"; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Swift Param %s=%d",name,volume); - mrcp_swift_channel_param_set(synth_channel,name,swift_val_int(volume)); - } - } - if(mrcp_resource_header_property_check(message,SYNTHESIZER_HEADER_PROSODY_RATE) == TRUE) { - int rate = 0; - if(swift_prosody_rate_get(&synth_header->prosody_param.rate,&rate) == TRUE) { - name = "speech/rate"; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Swift Param %s=%d",name,rate); - mrcp_swift_channel_param_set(synth_channel,name,swift_val_int(rate)); - } - } - } - - if(generic_header) { - if(mrcp_generic_header_property_check(message,GENERIC_HEADER_CONTENT_TYPE) == TRUE) { - name = "tts/content-type"; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Swift Param %s=%s",name,generic_header->content_type); - mrcp_swift_channel_param_set(synth_channel,name,swift_val_string(generic_header->content_type.buf)); - } - if(mrcp_generic_header_property_check(message,GENERIC_HEADER_CONTENT_ENCODING) == TRUE) { - name = "tts/text-encoding"; - apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Swift Param %s=%s",name,generic_header->content_encoding); - mrcp_swift_channel_param_set(synth_channel,name,swift_val_string(generic_header->content_encoding.buf)); - } - } - - return TRUE; -} - -static void mrcp_swift_sample_rates_set(mrcp_swift_engine_t *engine, const char *str) -{ - if(str) { - int value = atoi(str); - if(value == 8000) { - engine->sample_rates |= MPF_SAMPLE_RATE_8000; - } - else if(value == 16000) { - engine->sample_rates |= MPF_SAMPLE_RATE_8000 | MPF_SAMPLE_RATE_16000; - } - } -} - -/** Scan Swift available voices */ -static apt_bool_t mrcp_swift_voices_scan(mrcp_swift_engine_t *engine) -{ - swift_port *port; - swift_voice *voice; - const char *license_status; - const char *sample_rate; - - if(!engine->swift) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Invalid Swift Engine"); - return FALSE; - } - - /* open swift port*/ - if((port = swift_port_open(engine->swift, NULL)) == NULL) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Swift Port"); - return FALSE; - } - - engine->sample_rates = MPF_SAMPLE_RATE_NONE; - - /* find the first voice on the system */ - if((voice = swift_port_find_first_voice(port, NULL, NULL)) == NULL) { - apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Swift Voice Available"); - swift_port_close(port); - return FALSE; - } - /* go through all of the voices on the system and print some info about each */ - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Swift Available Voices:"); - for(; voice; voice = swift_port_find_next_voice(port)) { - if(swift_voice_get_attribute(voice, "license/key")) { - license_status = "licensed"; - } - else { - license_status = "unlicensed"; - } - sample_rate = swift_voice_get_attribute(voice, "sample-rate"); - apt_log(APT_LOG_MARK,APT_PRIO_INFO,"%s: %s, age %s, %s, %sHz, %s, %s", - swift_voice_get_attribute(voice, "name"), - swift_voice_get_attribute(voice, "speaker/gender"), - swift_voice_get_attribute(voice, "speaker/age"), - swift_voice_get_attribute(voice, "language/name"), - sample_rate, - swift_voice_get_attribute(voice, "version"), - license_status); - - mrcp_swift_sample_rates_set(engine,sample_rate); - } - - swift_port_close(port); - return TRUE; -} - -/** Create speech language lookup table */ -static apr_table_t* mrcp_swift_language_table_create(apr_pool_t *pool) -{ - apr_table_t *table = apr_table_make(pool,1); - if(!table) { - return NULL; - } - - apr_table_setn(table,"en-US","US English"); - apr_table_setn(table,"en-UK","UK English"); - apr_table_setn(table,"fr-CA","Canadian French"); - apr_table_setn(table,"es-MX","Americas Spanish"); - apr_table_setn(table,"de-DE","German"); - apr_table_setn(table,"it-IT","Italian"); - return table; -} diff --git a/libs/unimrcp/plugins/mrcp-flite/include/flite_voices.h b/libs/unimrcp/plugins/mrcp-flite/include/flite_voices.h index eb5a438368..59ebaf8b4d 100644 --- a/libs/unimrcp/plugins/mrcp-flite/include/flite_voices.h +++ b/libs/unimrcp/plugins/mrcp-flite/include/flite_voices.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: flite_voices.h 1474 2010-02-07 20:51:47Z achaloyan $ */ -#ifndef __FLITE_VOICES_H__ -#define __FLITE_VOICES_H__ +#ifndef FLITE_VOICES_H +#define FLITE_VOICES_H /** * @file flite_voices.h @@ -42,4 +44,4 @@ cst_voice* flite_voices_best_match_get(flite_voices_t *voices, mrcp_message_t *m APT_END_EXTERN_C -#endif /*__FLITE_VOICES_H__*/ +#endif /* FLITE_VOICES_H */ diff --git a/libs/unimrcp/plugins/mrcp-flite/mrcpflite.2008.vcproj b/libs/unimrcp/plugins/mrcp-flite/mrcpflite.2008.vcproj deleted file mode 100644 index 9767ed6e40..0000000000 --- a/libs/unimrcp/plugins/mrcp-flite/mrcpflite.2008.vcproj +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/unimrcp/plugins/mrcp-flite/src/flite_voices.c b/libs/unimrcp/plugins/mrcp-flite/src/flite_voices.c index eb37963b32..d3bfe293ae 100644 --- a/libs/unimrcp/plugins/mrcp-flite/src/flite_voices.c +++ b/libs/unimrcp/plugins/mrcp-flite/src/flite_voices.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: flite_voices.c 1474 2010-02-07 20:51:47Z achaloyan $ */ #include "flite_voices.h" diff --git a/libs/unimrcp/plugins/mrcp-flite/src/mrcp_flite.c b/libs/unimrcp/plugins/mrcp-flite/src/mrcp_flite.c index 5d691aca80..b3b3f80130 100644 --- a/libs/unimrcp/plugins/mrcp-flite/src/mrcp_flite.c +++ b/libs/unimrcp/plugins/mrcp-flite/src/mrcp_flite.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Arsen Chaloyan + * Copyright 2008-2010 Arsen Chaloyan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * $Id: mrcp_flite.c 1678 2010-05-01 18:54:07Z achaloyan $ */ /* @@ -158,7 +160,7 @@ static apt_bool_t flite_synth_engine_open(mrcp_engine_t *engine) flite_engine->voices = flite_voices_load(engine->pool); apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "flite init success"); - return TRUE; + return mrcp_engine_open_respond(engine,TRUE); } /** Close synthesizer engine */ @@ -169,7 +171,7 @@ static apt_bool_t flite_synth_engine_close(mrcp_engine_t *engine) flite_voices_unload(flite_engine->voices); - return TRUE; + return mrcp_engine_close_respond(engine); } static apt_bool_t flite_synth_task_create(flite_synth_channel_t *synth_channel) diff --git a/libs/unimrcp/plugins/mrcp-pocketsphinx/conf/pocketsphinx.xml b/libs/unimrcp/plugins/mrcp-pocketsphinx/conf/pocketsphinx.xml index f9bbb6a6b3..6d7bfa1ef5 100644 --- a/libs/unimrcp/plugins/mrcp-pocketsphinx/conf/pocketsphinx.xml +++ b/libs/unimrcp/plugins/mrcp-pocketsphinx/conf/pocketsphinx.xml @@ -1,9 +1,10 @@ + - + FreeSWITCH logging bridge */ -static apt_bool_t unimrcp_log(const char *file, int line, const char *id, apt_log_priority_e priority, const char *format, va_list arg_ptr); +static apt_bool_t unimrcp_log(const char *file, int line, const char *obj, apt_log_priority_e priority, const char *format, va_list arg_ptr); static apt_log_priority_e str_to_log_level(const char *level); static int get_next_speech_channel_number(void); @@ -1810,56 +1814,66 @@ static apt_bool_t speech_on_session_terminate(mrcp_application_t *application, m * @return TRUE */ static apt_bool_t speech_on_channel_add(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, - mrcp_sig_status_code_e status) + mrcp_sig_status_code_e status) { switch_event_t *event = NULL; speech_channel_t *schannel = (speech_channel_t *) mrcp_application_channel_object_get(channel); + char codec_name[60] = { 0 }; + const mpf_codec_descriptor_t *descriptor; /* check status */ - if (session && schannel && status == MRCP_SIG_STATUS_CODE_SUCCESS) { - char codec_name[60] = { 0 }; - const mpf_codec_descriptor_t *descriptor; - /* what sample rate did we negotiate? */ + if (!session || !schannel || status != MRCP_SIG_STATUS_CODE_SUCCESS) { + goto error; + } + + /* what sample rate did we negotiate? */ + if (schannel->type == SPEECH_CHANNEL_SYNTHESIZER) { + descriptor = mrcp_application_sink_descriptor_get(channel); + } else { + descriptor = mrcp_application_source_descriptor_get(channel); + } + if (!descriptor) { + goto error; + } + schannel->rate = descriptor->sampling_rate; + if (descriptor->name.length) { + strncpy(codec_name, descriptor->name.buf, sizeof(codec_name)); + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) %s channel is ready, codec = %s, sample rate = %d\n", schannel->name, + speech_channel_type_to_string(schannel->type), codec_name, schannel->rate); + speech_channel_set_state(schannel, SPEECH_CHANNEL_READY); + + /* notify of channel open */ + if (globals.enable_profile_events && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_PROFILE_OPEN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MRCP-Profile", schannel->profile->name); if (schannel->type == SPEECH_CHANNEL_SYNTHESIZER) { - descriptor = mrcp_application_sink_descriptor_get(channel); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MRCP-Resource-Type", "TTS"); } else { - descriptor = mrcp_application_source_descriptor_get(channel); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MRCP-Resource-Type", "ASR"); } - schannel->rate = descriptor->sampling_rate; - if (descriptor->name.length) { - strncpy(codec_name, descriptor->name.buf, sizeof(codec_name)); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) %s channel is ready, codec = %s, sample rate = %d\n", schannel->name, - speech_channel_type_to_string(schannel->type), codec_name, schannel->rate); - speech_channel_set_state(schannel, SPEECH_CHANNEL_READY); - /* notify of channel open */ - if (globals.enable_profile_events && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_PROFILE_OPEN) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MRCP-Profile", schannel->profile->name); - if (schannel->type == SPEECH_CHANNEL_SYNTHESIZER) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MRCP-Resource-Type", "TTS"); - } else { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MRCP-Resource-Type", "ASR"); - } - switch_event_fire(&event); - } - schannel->channel_opened = 1; + switch_event_fire(&event); + } + schannel->channel_opened = 1; + + return TRUE; + +error: + if (schannel) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) %s channel error!\n", schannel->name, + speech_channel_type_to_string(schannel->type)); } else { - if (schannel) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) %s channel error!\n", schannel->name, - speech_channel_type_to_string(schannel->type)); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(unknown) channel error!\n"); - } - if (session) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Terminating MRCP session\n"); - speech_channel_set_state(schannel, SPEECH_CHANNEL_ERROR); - mrcp_application_session_terminate(session); - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(unknown) channel error!\n"); + } + if (session) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Terminating MRCP session\n"); + speech_channel_set_state(schannel, SPEECH_CHANNEL_ERROR); + mrcp_application_session_terminate(session); } return TRUE; } + /** * Handle the UniMRCP responses sent to channel remove requests * @@ -3729,7 +3743,7 @@ static int process_profile_config(profile_t *profile, const char *param, const c * @param pool memory pool to use * @return true if this param belongs to RTP config */ -static int process_rtp_config(mrcp_client_t *client, mpf_rtp_config_t *rtp_config, const char *param, const char *val, apr_pool_t *pool) +static int process_rtp_config(mrcp_client_t *client, mpf_rtp_config_t *rtp_config, mpf_rtp_settings_t *rtp_settings, const char *param, const char *val, apr_pool_t *pool) { int mine = 1; if (strcasecmp(param, "rtp-ip") == 0) { @@ -3741,26 +3755,26 @@ static int process_rtp_config(mrcp_client_t *client, mpf_rtp_config_t *rtp_confi } else if (strcasecmp(param, "rtp-port-max") == 0) { rtp_config->rtp_port_max = (apr_port_t) atol(val); } else if (strcasecmp(param, "playout-delay") == 0) { - rtp_config->jb_config.initial_playout_delay = atol(val); + rtp_settings->jb_config.initial_playout_delay = atol(val); } else if (strcasecmp(param, "min-playout-delay") == 0) { - rtp_config->jb_config.min_playout_delay = atol(val); + rtp_settings->jb_config.min_playout_delay = atol(val); } else if (strcasecmp(param, "max-playout-delay") == 0) { - rtp_config->jb_config.max_playout_delay = atol(val); + rtp_settings->jb_config.max_playout_delay = atol(val); } else if (strcasecmp(param, "codecs") == 0) { const mpf_codec_manager_t *codec_manager = mrcp_client_codec_manager_get(client); if (codec_manager) { - mpf_codec_manager_codec_list_load(codec_manager, &rtp_config->codec_list, val, pool); + mpf_codec_manager_codec_list_load(codec_manager, &rtp_settings->codec_list, val, pool); } } else if (strcasecmp(param, "ptime") == 0) { - rtp_config->ptime = (apr_uint16_t) atol(val); + rtp_settings->ptime = (apr_uint16_t) atol(val); } else if (strcasecmp(param, "rtcp") == 0) { - rtp_config->rtcp = atoi(val); + rtp_settings->rtcp = atoi(val); } else if (strcasecmp(param, "rtcp-bye") == 0) { - rtp_config->rtcp_bye_policy = atoi(val); + rtp_settings->rtcp_bye_policy = atoi(val); } else if (strcasecmp(param, "rtcp-tx-interval") == 0) { - rtp_config->rtcp_tx_interval = (apr_uint16_t) atoi(val); + rtp_settings->rtcp_tx_interval = (apr_uint16_t) atoi(val); } else if (strcasecmp(param, "rtcp-rx-resolution") == 0) { - rtp_config->rtcp_rx_resolution = (apr_uint16_t) atol(val); + rtp_settings->rtcp_rx_resolution = (apr_uint16_t) atol(val); } else { mine = 0; } @@ -3771,28 +3785,29 @@ static int process_rtp_config(mrcp_client_t *client, mpf_rtp_config_t *rtp_confi /** * set RTSP client config struct with param, val pair * @param config the config struct to set + * @param sig_settings the sig settings struct to set * @param param the param name * @param val the param value * @param pool memory pool to use * @return true if this param belongs to RTSP config */ -static int process_mrcpv1_config(rtsp_client_config_t *config, const char *param, const char *val, apr_pool_t *pool) +static int process_mrcpv1_config(rtsp_client_config_t *config, mrcp_sig_settings_t *sig_settings, const char *param, const char *val, apr_pool_t *pool) { int mine = 1; if (strcasecmp(param, "server-ip") == 0) { - config->server_ip = ip_addr_get(val, pool); + sig_settings->server_ip = ip_addr_get(val, pool); } else if (strcasecmp(param, "server-port") == 0) { - config->server_port = (apr_port_t) atol(val); + sig_settings->server_port = (apr_port_t) atol(val); } else if (strcasecmp(param, "resource-location") == 0) { - config->resource_location = apr_pstrdup(pool, val); + sig_settings->resource_location = apr_pstrdup(pool, val); } else if (strcasecmp(param, "sdp-origin") == 0) { config->origin = apr_pstrdup(pool, val); } else if (strcasecmp(param, "max-connection-count") == 0) { config->max_connection_count = atol(val); } else if (strcasecmp(param, "force-destination") == 0) { - config->force_destination = atoi(val); + sig_settings->force_destination = atoi(val); } else if (strcasecmp(param, "speechsynth") == 0 || strcasecmp(param, "speechrecog") == 0) { - apr_table_set(config->resource_map, param, val); + apr_table_set(sig_settings->resource_map, param, val); } else { mine = 0; } @@ -3802,12 +3817,13 @@ static int process_mrcpv1_config(rtsp_client_config_t *config, const char *param /** * set SofiaSIP client config struct with param, val pair * @param config the config struct to set + * @param sig_settings the sig settings struct to set * @param param the param name * @param val the param value * @param pool memory pool to use * @return true if this param belongs to SofiaSIP config */ -static int process_mrcpv2_config(mrcp_sofia_client_config_t *config, const char *param, const char *val, apr_pool_t *pool) +static int process_mrcpv2_config(mrcp_sofia_client_config_t *config, mrcp_sig_settings_t *sig_settings, const char *param, const char *val, apr_pool_t *pool) { int mine = 1; if (strcasecmp(param, "client-ip") == 0) { @@ -3817,13 +3833,13 @@ static int process_mrcpv2_config(mrcp_sofia_client_config_t *config, const char } else if (strcasecmp(param, "client-port") == 0) { config->local_port = (apr_port_t) atol(val); } else if (strcasecmp(param, "server-ip") == 0) { - config->remote_ip = ip_addr_get(val, pool); + sig_settings->server_ip = ip_addr_get(val, pool); } else if (strcasecmp(param, "server-port") == 0) { - config->remote_port = (apr_port_t) atol(val); + sig_settings->server_port = (apr_port_t) atol(val); } else if (strcasecmp(param, "server-username") == 0) { - config->remote_user_name = apr_pstrdup(pool, val); + sig_settings->user_name = apr_pstrdup(pool, val); } else if (strcasecmp(param, "force-destination") == 0) { - config->force_destination = atoi(val); + sig_settings->force_destination = atoi(val); } else if (strcasecmp(param, "sip-transport") == 0) { config->transport = apr_pstrdup(pool, val); } else if (strcasecmp(param, "ua-name") == 0) { @@ -3905,15 +3921,21 @@ static mrcp_client_t *mod_unimrcp_client_create(switch_memory_pool_t *mod_pool) if (!zstr(globals.unimrcp_offer_new_connection)) { offer_new_connection = strcasecmp("true", globals.unimrcp_offer_new_connection); } - connection_agent = mrcp_client_connection_agent_create(max_connection_count, offer_new_connection, pool); + connection_agent = mrcp_client_connection_agent_create("MRCPv2ConnectionAgent", max_connection_count, offer_new_connection, pool); if (connection_agent) { - mrcp_client_connection_agent_register(client, connection_agent, "MRCPv2ConnectionAgent"); + if (!zstr(globals.unimrcp_request_timeout)) { + apr_size_t request_timeout = (apr_size_t)atol(globals.unimrcp_request_timeout); + if (request_timeout > 0) { + mrcp_client_connection_timeout_set(connection_agent, request_timeout); + } + } + mrcp_client_connection_agent_register(client, connection_agent); } /* Set up the media engine that will be shared with all profiles */ - media_engine = mpf_engine_create(pool); + media_engine = mpf_engine_create("MediaEngine", pool); if (media_engine) { - mrcp_client_media_engine_register(client, media_engine, "MediaEngine"); + mrcp_client_media_engine_register(client, media_engine); } /* configure the client profiles */ @@ -3929,6 +3951,8 @@ static mrcp_client_t *mod_unimrcp_client_create(switch_memory_pool_t *mod_pool) mpf_termination_factory_t *termination_factory = NULL; mrcp_profile_t *mprofile = NULL; mpf_rtp_config_t *rtp_config = NULL; + mpf_rtp_settings_t *rtp_settings = mpf_rtp_settings_alloc(pool); + mrcp_sig_settings_t *sig_settings = mrcp_signaling_settings_alloc(pool); profile_t *mod_profile = NULL; switch_xml_t default_params = NULL; @@ -3992,18 +4016,24 @@ static mrcp_client_t *mod_unimrcp_client_create(switch_memory_pool_t *mod_pool) } /* create RTP config, common to MRCPv1 and MRCPv2 */ - rtp_config = mpf_rtp_config_create(pool); + rtp_config = mpf_rtp_config_alloc(pool); rtp_config->rtp_port_min = DEFAULT_RTP_PORT_MIN; rtp_config->rtp_port_max = DEFAULT_RTP_PORT_MAX; apt_string_set(&rtp_config->ip, DEFAULT_LOCAL_IP_ADDRESS); if (strcmp("1", version) == 0) { /* MRCPv1 configuration */ - rtsp_client_config_t *config = mrcp_unirtsp_client_config_alloc(pool); switch_xml_t param = NULL; + rtsp_client_config_t *config = mrcp_unirtsp_client_config_alloc(pool); config->origin = DEFAULT_SDP_ORIGIN; - config->resource_location = DEFAULT_RESOURCE_LOCATION; + sig_settings->resource_location = DEFAULT_RESOURCE_LOCATION; + if (!zstr(globals.unimrcp_request_timeout)) { + apr_size_t request_timeout = (apr_size_t)atol(globals.unimrcp_request_timeout); + if (request_timeout > 0) { + config->request_timeout = request_timeout; + } + } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading MRCPv1 profile: %s\n", name); for (param = switch_xml_child(profile, "param"); param; param = switch_xml_next(param)) { const char *param_name = switch_xml_attr(param, "name"); @@ -4014,21 +4044,21 @@ static mrcp_client_t *mod_unimrcp_client_create(switch_memory_pool_t *mod_pool) goto done; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading Param %s:%s\n", param_name, param_value); - if (!process_mrcpv1_config(config, param_name, param_value, pool) && - !process_rtp_config(client, rtp_config, param_name, param_value, pool) && + if (!process_mrcpv1_config(config, sig_settings, param_name, param_value, pool) && + !process_rtp_config(client, rtp_config, rtp_settings, param_name, param_value, pool) && !process_profile_config(mod_profile, param_name, param_value, mod_pool)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown param %s\n", param_name); } } - agent = mrcp_unirtsp_client_agent_create(config, pool); + agent = mrcp_unirtsp_client_agent_create(name, config, pool); } else if (strcmp("2", version) == 0) { /* MRCPv2 configuration */ mrcp_sofia_client_config_t *config = mrcp_sofiasip_client_config_alloc(pool); switch_xml_t param = NULL; config->local_ip = DEFAULT_LOCAL_IP_ADDRESS; config->local_port = DEFAULT_SIP_LOCAL_PORT; - config->remote_ip = DEFAULT_REMOTE_IP_ADDRESS; - config->remote_port = DEFAULT_SIP_REMOTE_PORT; + sig_settings->server_ip = DEFAULT_REMOTE_IP_ADDRESS; + sig_settings->server_port = DEFAULT_SIP_REMOTE_PORT; config->ext_ip = NULL; config->user_agent_name = DEFAULT_SOFIASIP_UA_NAME; config->origin = DEFAULT_SDP_ORIGIN; @@ -4042,13 +4072,13 @@ static mrcp_client_t *mod_unimrcp_client_create(switch_memory_pool_t *mod_pool) goto done; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading Param %s:%s\n", param_name, param_value); - if (!process_mrcpv2_config(config, param_name, param_value, pool) && - !process_rtp_config(client, rtp_config, param_name, param_value, pool) && + if (!process_mrcpv2_config(config, sig_settings, param_name, param_value, pool) && + !process_rtp_config(client, rtp_config, rtp_settings, param_name, param_value, pool) && !process_profile_config(mod_profile, param_name, param_value, mod_pool)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown param %s\n", param_name); } } - agent = mrcp_sofiasip_client_agent_create(config, pool); + agent = mrcp_sofiasip_client_agent_create(name, config, pool); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "version must be either \"1\" or \"2\"\n"); client = NULL; @@ -4060,11 +4090,11 @@ static mrcp_client_t *mod_unimrcp_client_create(switch_memory_pool_t *mod_pool) mrcp_client_rtp_factory_register(client, termination_factory, name); } if (agent) { - mrcp_client_signaling_agent_register(client, agent, name); + mrcp_client_signaling_agent_register(client, agent); } /* create the profile and register it */ - mprofile = mrcp_client_profile_create(NULL, agent, connection_agent, media_engine, termination_factory, pool); + mprofile = mrcp_client_profile_create(NULL, agent, connection_agent, media_engine, termination_factory, rtp_settings, sig_settings, pool); if (mprofile) { mrcp_client_profile_register(client, mprofile, name); } @@ -4195,11 +4225,12 @@ static apt_log_priority_e str_to_log_level(const char *level) * Connects UniMRCP logging to FreeSWITCH * @return TRUE */ -static apt_bool_t unimrcp_log(const char *file, int line, const char *id, apt_log_priority_e priority, const char *format, va_list arg_ptr) +static apt_bool_t unimrcp_log(const char *file, int line, const char *obj, apt_log_priority_e priority, const char *format, va_list arg_ptr) { switch_log_level_t level; char log_message[4096] = { 0 }; /* same size as MAX_LOG_ENTRY_SIZE in UniMRCP apt_log.c */ size_t msglen; + const char *id = (obj == NULL) ? "" : ((speech_channel_t *)obj)->name; if (zstr(format)) { return TRUE; @@ -4237,10 +4268,10 @@ static apt_bool_t unimrcp_log(const char *file, int line, const char *id, apt_lo msglen = strlen(log_message); if (msglen >= 2 && log_message[msglen - 2] == '\\' && log_message[msglen - 1] == 'n') { /* log_message already ends in \n */ - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, id, level, "%s", log_message); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, NULL, level, "(%s) %s", id, log_message); } else if (msglen > 0) { /* log message needs \n appended */ - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, id, level, "%s\n", log_message); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, NULL, level, "(%s) %s\n", id, log_message); } return TRUE;