Revision
14260
Author
mikej
Date
2009-07-15 15:30:39 -0500 (Wed, 15 Jul 2009)

Log Message

commit 027047ed7b07832456cd5d13f4c85da24aca26b5
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Tue Jul 14 18:17:37 2009 +0000

    Added missing UNIMRCP_APU_INCLUDES in pkg-config files
    
    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1054 f001bc3a-424a-0410-80a0-a715b8f413a8

commit b0e1c8251f8039a8a22662120e5a362340733a9e
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Mon Jul 13 17:25:34 2009 +0000

    if state != RECOGNIZING, there is nothing to do on deactivation
    
    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1053 f001bc3a-424a-0410-80a0-a715b8f413a8

commit 3581b9d3ba59177f4aaced327e20b8dc53e234e3
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Mon Jul 13 16:14:38 2009 +0000

    Do not include Completion-Cause header field in the IN-PROGRESS response sent by PocketSphinx plugin
    
    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1052 f001bc3a-424a-0410-80a0-a715b8f413a8

commit 831f43f9071e491169d4d5a7e3d0cb2009c3af21
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Mon Jul 13 15:27:33 2009 +0000

    Using MRCP_SESSION_SID(session) macro wherever session id is logged
    
    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1051 f001bc3a-424a-0410-80a0-a715b8f413a8

commit 9349bd2b393ee0b300942bfa8cacc264687ecea9
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Sat Jul 11 15:17:42 2009 +0000

    Sent async channel_open and channel_close responses
    
    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1050 f001bc3a-424a-0410-80a0-a715b8f413a8

commit 5775dfc74e8fe982735da32dfa12dc05f0d20892
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Sat Jul 11 15:15:47 2009 +0000

    Sent async channel_close response
    
    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1049 f001bc3a-424a-0410-80a0-a715b8f413a8

commit efa4d10b2dc3de238dfb4a26b25ef3a580fb0bf0
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Sat Jul 11 12:54:47 2009 +0000

    Enhanced state machine to STOP in-progress SPEAK or RECOGNIZE requests on session termination, thus guarantee there is no remaining request, when plugin cha
nnel_close() method is called.

    channel_open() -> SPEAK -> STOP -> channel_close()
    channel_open() -> SPEAK -> SPEAK-COMPLETE -> channel_close()

    This allows to simplify implementation of plugins (nothing has to be changed).

    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1048 f001bc3a-424a-0410-80a0-a715b8f413a8

commit aaf53907ea0705bc2a44fe785c8f7762e20e52cf
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Fri Jul 10 12:57:33 2009 +0000

    Added utility function to get attributes of NLSML results such as confidence and grammar

    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1047 f001bc3a-424a-0410-80a0-a715b8f413a8

commit f7c4dff83199cb9af8dc7ec6f121c384d2b6cea0
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Fri Jul 10 09:51:23 2009 +0000

    Added missing includes for <stdlib.h> and <stdio.h> required on some platforms

    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1046 f001bc3a-424a-0410-80a0-a715b8f413a8

commit 1cb7ccb6e63f4d34b6cfcbdc386446a36d052af1
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Thu Jul 9 19:05:18 2009 +0000

    Using NLSML processor in demo

    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1045 f001bc3a-424a-0410-80a0-a715b8f413a8

commit cd74eee440dd94cabe814c7d4f64dfef187b7445
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date:   Thu Jul 9 18:52:49 2009 +0000

    Added basic NLSML document processor

    git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1044 f001bc3a-424a-0410-80a0-a715b8f413a8

Modified Paths

Added Paths

Diff

Modified: freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpclient.pc.in (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpclient.pc.in	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpclient.pc.in	2009-07-15 20:30:39 UTC (rev 14260)
@@ -1,7 +1,7 @@
 prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
-includedir=@includedir@ @UNIMRCP_APR_INCLUDES@
+includedir=@includedir@ @UNIMRCP_APR_INCLUDES@ @UNIMRCP_APU_INCLUDES@
 
 Name: unimrcpclient
 Description: UniMRCP Client Stack

Modified: freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpplugin.pc.in (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpplugin.pc.in	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpplugin.pc.in	2009-07-15 20:30:39 UTC (rev 14260)
@@ -1,7 +1,7 @@
 prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
-includedir=@includedir@ @UNIMRCP_APR_INCLUDES@
+includedir=@includedir@ @UNIMRCP_APR_INCLUDES@ @UNIMRCP_APU_INCLUDES@
 
 Name: unimrcpplugin
 Description: UniMRCP Server Plugin

Modified: freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpserver.pc.in (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpserver.pc.in	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/build/pkgconfig/unimrcpserver.pc.in	2009-07-15 20:30:39 UTC (rev 14260)
@@ -1,7 +1,7 @@
 prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
-includedir=@includedir@ @UNIMRCP_APR_INCLUDES@
+includedir=@includedir@ @UNIMRCP_APR_INCLUDES@ @UNIMRCP_APU_INCLUDES@
 
 Name: unimrcpserver
 Description: UniMRCP Server Stack

Modified: freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/Makefile.am (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/Makefile.am	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/Makefile.am	2009-07-15 20:30:39 UTC (rev 14260)
@@ -21,6 +21,7 @@
                            include/apt_string_table.h \
                            include/apt_text_stream.h \
                            include/apt_net.h \
+                           include/apt_nlsml_doc.h \
                            include/apt_dir_layout.h \
                            include/apt_test_suite.h
 
@@ -38,6 +39,7 @@
                            src/apt_string_table.c \
                            src/apt_text_stream.c \
                            src/apt_net.c \
+                           src/apt_nlsml_doc.c \
                            src/apt_dir_layout.c \
                            src/apt_test_suite.c
                            

Modified: freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/aprtoolkit.vcproj (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/aprtoolkit.vcproj	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/aprtoolkit.vcproj	2009-07-15 20:30:39 UTC (rev 14260)
@@ -162,6 +162,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\include\apt_nlsml_doc.h"
+				>
+			</File>
+			<File
 				RelativePath=".\include\apt_obj_list.h"
 				>
 			</File>
@@ -235,6 +239,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\src\apt_nlsml_doc.c"
+				>
+			</File>
+			<File
 				RelativePath=".\src\apt_obj_list.c"
 				>
 			</File>

Added: freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/include/apt_nlsml_doc.h (0 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/include/apt_nlsml_doc.h	                        (rev 0)
+++ freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/include/apt_nlsml_doc.h	2009-07-15 20:30:39 UTC (rev 14260)
@@ -0,0 +1,48 @@
+/*
+ * 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_NLSML_DOC_H__
+#define __APT_NLSML_DOC_H__
+
+/**
+ * @file apt_nlsml_doc.h
+ * @brief Basic NLSML Routine
+ */ 
+
+#include "apr_xml.h"
+#include "apt_string.h"
+
+APT_BEGIN_EXTERN_C
+
+/** Load NLSML document */
+APT_DECLARE(apr_xml_doc*) nlsml_doc_load(const apt_str_t *data, apr_pool_t *pool);
+
+/** Get the first <interpretation> element */
+APT_DECLARE(apr_xml_elem*) nlsml_first_interpret_get(const apr_xml_doc *doc);
+
+/** Get the next <interpretation> element */
+APT_DECLARE(apr_xml_elem*) nlsml_next_interpret_get(const apr_xml_elem *interpret);
+
+/** Get <instance> and <input> elements of <interpretation> element */
+APT_DECLARE(apt_bool_t) nlsml_interpret_results_get(const apr_xml_elem *interpret, apr_xml_elem **instance, apr_xml_elem **input);
+
+/** Get specified atrribute of <input> */
+APT_DECLARE(const char *) nlsml_input_attrib_get(const apr_xml_elem *input, const char *attrib, apt_bool_t recursive);
+
+
+APT_END_EXTERN_C
+
+#endif /*__APT_NLSML_DOC_H__*/

Added: freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/src/apt_nlsml_doc.c (0 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/src/apt_nlsml_doc.c	                        (rev 0)
+++ freeswitch/trunk/libs/unimrcp/libs/apr-toolkit/src/apt_nlsml_doc.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -0,0 +1,108 @@
+/*
+ * 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_nlsml_doc.h"
+
+/** Load NLSML document */
+APT_DECLARE(apr_xml_doc*) nlsml_doc_load(const apt_str_t *data, apr_pool_t *pool)
+{
+	apr_xml_parser *parser;
+	apr_xml_doc *doc = NULL;
+	const apr_xml_elem *root;
+
+	/* create XML parser */
+	parser = apr_xml_parser_create(pool);
+	if(apr_xml_parser_feed(parser,data->buf,data->length) != APR_SUCCESS) {
+		return NULL;
+	}
+
+	/* done with XML tree creation */
+	if(apr_xml_parser_done(parser,&doc) != APR_SUCCESS) {
+		return NULL;
+	}
+
+	if(!doc || !doc->root) {
+		return NULL;
+	}
+	root = doc->root;
+
+	/* NLSML validity check: root element must be <result> */
+	if(strcmp(root->name,"result") != 0) {
+		return NULL;
+	}
+
+	return doc;
+}
+
+/** Get the first <interpretation> element */
+APT_DECLARE(apr_xml_elem*) nlsml_first_interpret_get(const apr_xml_doc *doc)
+{
+	apr_xml_elem *child_elem;
+	for(child_elem = doc->root->first_child; child_elem; child_elem = child_elem->next) {
+		if(strcmp(child_elem->name,"interpretation") == 0) {
+			return child_elem;
+		}
+	}
+
+	return NULL;
+}
+
+/** Get the next <interpretation> element */
+APT_DECLARE(apr_xml_elem*) nlsml_next_interpret_get(const apr_xml_elem *elem)
+{
+	apr_xml_elem *child_elem;
+	for(child_elem = elem->next; child_elem; child_elem = child_elem->next) {
+		if(strcmp(child_elem->name,"interpretation") == 0) {
+			return child_elem;
+		}
+	}
+
+	return NULL;
+}
+
+/** Get <instance> and <input> elements of <interpretation> element */
+APT_DECLARE(apt_bool_t) nlsml_interpret_results_get(const apr_xml_elem *interpret, apr_xml_elem **instance, apr_xml_elem **input)
+{
+	apr_xml_elem *child_elem;
+	*input = NULL;
+	*instance = NULL;
+	for(child_elem = interpret->first_child; child_elem; child_elem = child_elem->next) {
+		if(strcmp(child_elem->name,"input") == 0) {
+			*input = child_elem;
+		}
+		else if(strcmp(child_elem->name,"instance") == 0) {
+			*instance = child_elem;
+		}
+	}
+	return TRUE;
+}
+
+/** Get specified atrribute of <input> */
+APT_DECLARE(const char *) nlsml_input_attrib_get(const apr_xml_elem *input, const char *attrib, apt_bool_t recursive)
+{
+	const apr_xml_attr *xml_attr;
+	for(xml_attr = input->attr; xml_attr; xml_attr = xml_attr->next) {
+		if(strcasecmp(xml_attr->name,attrib) == 0) {
+			return xml_attr->value;
+		}
+	}
+
+	if(recursive && input->parent) {
+		return nlsml_input_attrib_get(input->parent,attrib,recursive);
+	}
+
+	return NULL;
+}

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/control/include/mrcp_resource.h (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/control/include/mrcp_resource.h	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/control/include/mrcp_resource.h	2009-07-15 20:30:39 UTC (rev 14260)
@@ -40,9 +40,9 @@
 	apt_bool_t (*resourcify_message_by_name)(mrcp_resource_t *resource, mrcp_message_t *message);
 
 	/** Create client side state machine */
-	mrcp_state_machine_t* (*create_client_state_machine)(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool);
+	mrcp_state_machine_t* (*create_client_state_machine)(void *obj, mrcp_version_e version, apr_pool_t *pool);
 	/** Create server side state machine */
-	mrcp_state_machine_t* (*create_server_state_machine)(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool);
+	mrcp_state_machine_t* (*create_server_state_machine)(void *obj, mrcp_version_e version, apr_pool_t *pool);
 };
 
 /** Initialize MRCP resource */

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/control/include/mrcp_state_machine.h (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/control/include/mrcp_state_machine.h	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/control/include/mrcp_state_machine.h	2009-07-15 20:30:39 UTC (rev 14260)
@@ -29,34 +29,56 @@
 /** MRCP state machine declaration */
 typedef struct mrcp_state_machine_t mrcp_state_machine_t;
 
-/** MRCP message dispatcher */
-typedef apt_bool_t (*mrcp_message_dispatcher_f)(mrcp_state_machine_t *state_machine, mrcp_message_t *message);
 
-
 /** MRCP state machine */
 struct mrcp_state_machine_t {
 	/** External object associated with state machine */
 	void *obj;
-	/** Message dispatcher */
-	mrcp_message_dispatcher_f dispatcher;
+	/** State either active or deactivating */
+	apt_bool_t active;
 
 	/** Virtual update */
 	apt_bool_t (*update)(mrcp_state_machine_t *state_machine, mrcp_message_t *message);
+	/** Deactivate */
+	apt_bool_t (*deactivate)(mrcp_state_machine_t *state_machine);
+
+
+	/** Message dispatcher */
+	apt_bool_t (*on_dispatch)(mrcp_state_machine_t *state_machine, mrcp_message_t *message);
+	/** Deactivated */
+	apt_bool_t (*on_deactivate)(mrcp_state_machine_t *state_machine);
 };
 
 /** Initialize MRCP state machine */
-static APR_INLINE void mrcp_state_machine_init(mrcp_state_machine_t *state_machine, void *obj, mrcp_message_dispatcher_f dispatcher)
+static APR_INLINE void mrcp_state_machine_init(mrcp_state_machine_t *state_machine, void *obj)
 {
 	state_machine->obj = obj;
-	state_machine->dispatcher = dispatcher;
+	state_machine->active = TRUE;
+	state_machine->on_dispatch = NULL;
+	state_machine->on_deactivate = NULL;
+	state_machine->update = NULL;
+	state_machine->deactivate = NULL;
 }
 
 /** Update MRCP state machine */
 static APR_INLINE apt_bool_t mrcp_state_machine_update(mrcp_state_machine_t *state_machine, mrcp_message_t *message)
 {
-	return state_machine->update(state_machine,message);
+	if(state_machine->update) {
+		return state_machine->update(state_machine,message);
+	}
+	return FALSE;
 }
 
+/** Deactivate MRCP state machine */
+static APR_INLINE apt_bool_t mrcp_state_machine_deactivate(mrcp_state_machine_t *state_machine)
+{
+	if(state_machine->deactivate) {
+		state_machine->active = FALSE;
+		return state_machine->deactivate(state_machine);
+	}
+	return FALSE;
+}
+
 APT_END_EXTERN_C
 
 #endif /*__MRCP_STATE_MACHINE_H__*/

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_state_machine.h (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_state_machine.h	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/include/mrcp_recog_state_machine.h	2009-07-15 20:30:39 UTC (rev 14260)
@@ -27,10 +27,10 @@
 APT_BEGIN_EXTERN_C
 
 /** Create MRCP recognizer server state machine */
-mrcp_state_machine_t* mrcp_recog_server_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool);
+mrcp_state_machine_t* mrcp_recog_server_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool);
 
 /** Create MRCP recognizer client state machine */
-mrcp_state_machine_t* mrcp_recog_client_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool);
+mrcp_state_machine_t* mrcp_recog_client_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool);
 
 APT_END_EXTERN_C
 

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_state_machine.h (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_state_machine.h	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/include/mrcp_synth_state_machine.h	2009-07-15 20:30:39 UTC (rev 14260)
@@ -27,10 +27,10 @@
 APT_BEGIN_EXTERN_C
 
 /** Create MRCP synthesizer server state machine */
-mrcp_state_machine_t* mrcp_synth_server_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool);
+mrcp_state_machine_t* mrcp_synth_server_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool);
 
 /** Create MRCP synthesizer client state machine */
-mrcp_state_machine_t* mrcp_synth_client_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool);
+mrcp_state_machine_t* mrcp_synth_client_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool);
 
 APT_END_EXTERN_C
 

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_client_state_machine.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_client_state_machine.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_client_state_machine.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -23,14 +23,14 @@
 static apt_bool_t recog_state_update(mrcp_state_machine_t *state_machine, mrcp_message_t *message)
 {
 	/* no actual state machine processing yet, dispatch whatever received */
-	return state_machine->dispatcher(state_machine,message);
+	return state_machine->on_dispatch(state_machine,message);
 }
 
 /** Create MRCP recognizer client state machine */
-mrcp_state_machine_t* mrcp_recog_client_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool)
+mrcp_state_machine_t* mrcp_recog_client_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool)
 {
 	mrcp_state_machine_t *state_machine = apr_palloc(pool,sizeof(mrcp_state_machine_t));
-	mrcp_state_machine_init(state_machine,obj,dispatcher);
+	mrcp_state_machine_init(state_machine,obj);
 	state_machine->update = recog_state_update;
 	return state_machine;
 }

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_header.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_header.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_header.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <stdio.h>
 #include "mrcp_recog_header.h"
 
 /** String table of MRCPv1 recognizer headers (mrcp_recog_header_id) */

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_server_state_machine.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_server_state_machine.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_recog_server_state_machine.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -61,18 +61,26 @@
 static APR_INLINE apt_bool_t recog_request_dispatch(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message)
 {
 	state_machine->active_request = message;
-	return state_machine->base.dispatcher(&state_machine->base,message);
+	return state_machine->base.on_dispatch(&state_machine->base,message);
 }
 
 static APR_INLINE apt_bool_t recog_response_dispatch(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message)
 {
 	state_machine->active_request = NULL;
-	return state_machine->base.dispatcher(&state_machine->base,message);
+	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 recog_event_dispatch(mrcp_recog_state_machine_t *state_machine, mrcp_message_t *message)
 {
-	return state_machine->base.dispatcher(&state_machine->base,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 recog_state_change(mrcp_recog_state_machine_t *state_machine, mrcp_recog_state_e state)
@@ -286,10 +294,10 @@
 	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);
+	pending_request = apt_list_pop_front(state_machine->queue);
 	recog_response_dispatch(state_machine,message);
 
 	/* process pending RECOGNIZE requests / if any */
-	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);
 		state_machine->is_pending = TRUE;
@@ -432,19 +440,19 @@
 }
 
 /** Update state according to request received from MRCP client or response/event received from recognition engine */
-static apt_bool_t recog_state_update(mrcp_state_machine_t *state_machine, mrcp_message_t *message)
+static apt_bool_t recog_state_update(mrcp_state_machine_t *base, mrcp_message_t *message)
 {
-	mrcp_recog_state_machine_t *recog_state_machine = (mrcp_recog_state_machine_t*)state_machine;
+	mrcp_recog_state_machine_t *state_machine = (mrcp_recog_state_machine_t*)base;
 	apt_bool_t status = TRUE;
 	switch(message->start_line.message_type) {
 		case MRCP_MESSAGE_TYPE_REQUEST:
-			status = recog_request_state_update(recog_state_machine,message);
+			status = recog_request_state_update(state_machine,message);
 			break;
 		case MRCP_MESSAGE_TYPE_RESPONSE:
-			status = recog_response_state_update(recog_state_machine,message);
+			status = recog_response_state_update(state_machine,message);
 			break;
 		case MRCP_MESSAGE_TYPE_EVENT:
-			status = recog_event_state_update(recog_state_machine,message);
+			status = recog_event_state_update(state_machine,message);
 			break;
 		default:
 			status = FALSE;
@@ -453,13 +461,42 @@
 	return status;
 }
 
+/** Deactivate state machine */
+static apt_bool_t recog_state_deactivate(mrcp_state_machine_t *base)
+{
+	mrcp_recog_state_machine_t *state_machine = (mrcp_recog_state_machine_t*)base;
+	mrcp_message_t *message;
+	mrcp_message_t *source;
+	if(state_machine->state != RECOGNIZER_STATE_RECOGNIZING) {
+		/* no in-progress RECOGNIZE request to deactivate */
+		return FALSE;
+	}
+	source = state_machine->recog;
+	if(!source) {
+		return FALSE;
+	}
+
+	/* create internal STOP request */
+	message = mrcp_request_create(
+						source->channel_id.resource_id,
+						RECOGNIZER_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 [%d]",message->start_line.request_id);
+	return recog_request_dispatch(state_machine,message);
+}
+
 /** Create MRCP recognizer server state machine */
-mrcp_state_machine_t* mrcp_recog_server_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool)
+mrcp_state_machine_t* mrcp_recog_server_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,dispatcher);
+	mrcp_state_machine_init(&state_machine->base,obj);
 	state_machine->base.update = recog_state_update;
+	state_machine->base.deactivate = recog_state_deactivate;
 	state_machine->state = RECOGNIZER_STATE_IDLE;
 	state_machine->is_pending = FALSE;
 	state_machine->active_request = NULL;

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_client_state_machine.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_client_state_machine.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_client_state_machine.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -23,14 +23,14 @@
 static apt_bool_t synth_state_update(mrcp_state_machine_t *state_machine, mrcp_message_t *message)
 {
 	/* no actual state machine processing yet, dispatch whatever received */
-	return state_machine->dispatcher(state_machine,message);
+	return state_machine->on_dispatch(state_machine,message);
 }
 
 /** Create MRCP synthesizer client state machine */
-mrcp_state_machine_t* mrcp_synth_client_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool)
+mrcp_state_machine_t* mrcp_synth_client_state_machine_create(void *obj, mrcp_version_e version, apr_pool_t *pool)
 {
 	mrcp_state_machine_t *state_machine = apr_palloc(pool,sizeof(mrcp_state_machine_t));
-	mrcp_state_machine_init(state_machine,obj,dispatcher);
+	mrcp_state_machine_init(state_machine,obj);
 	state_machine->update = synth_state_update;
 	return state_machine;
 }

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_header.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_header.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_header.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <stdio.h>
 #include "mrcp_synth_header.h"
 
 /** String table of MRCP synthesizer headers (mrcp_synthesizer_header_id) */

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_server_state_machine.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_server_state_machine.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp/resources/src/mrcp_synth_server_state_machine.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -61,18 +61,26 @@
 static APR_INLINE apt_bool_t synth_request_dispatch(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message)
 {
 	state_machine->active_request = message;
-	return state_machine->base.dispatcher(&state_machine->base,message);
+	return state_machine->base.on_dispatch(&state_machine->base,message);
 }
 
 static APR_INLINE apt_bool_t synth_response_dispatch(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message)
 {
 	state_machine->active_request = NULL;
-	return state_machine->base.dispatcher(&state_machine->base,message);
+	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 synth_event_dispatch(mrcp_synth_state_machine_t *state_machine, mrcp_message_t *message)
 {
-	return state_machine->base.dispatcher(&state_machine->base,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 synth_state_change(mrcp_synth_state_machine_t *state_machine, mrcp_synth_state_e state)
@@ -220,10 +228,10 @@
 	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);
+	pending_request = apt_list_pop_front(state_machine->queue);
 	synth_response_dispatch(state_machine,message);
 
 	/* process pending SPEAK requests / if any */
-	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);
 		state_machine->is_pending = TRUE;
@@ -522,9 +530,9 @@
 }
 
 /** Update state according to request received from MRCP client or response/event received from synthesizer engine */
-static apt_bool_t synth_state_update(mrcp_state_machine_t *state_machine, mrcp_message_t *message)
+static apt_bool_t synth_state_update(mrcp_state_machine_t *base, mrcp_message_t *message)
 {
-	mrcp_synth_state_machine_t *synth_state_machine = (mrcp_synth_state_machine_t*)state_machine;
+	mrcp_synth_state_machine_t *synth_state_machine = (mrcp_synth_state_machine_t*)base;
 	apt_bool_t status = TRUE;
 	switch(message->start_line.message_type) {
 		case MRCP_MESSAGE_TYPE_REQUEST:
@@ -543,13 +551,39 @@
 	return status;
 }
 
+/** Deactivate state machine */
+static apt_bool_t synth_state_deactivate(mrcp_state_machine_t *base)
+{
+	mrcp_synth_state_machine_t *state_machine = (mrcp_synth_state_machine_t*)base;
+	mrcp_message_t *message;
+	mrcp_message_t *source;
+	if(!state_machine->speaker) {
+		/* no in-progress SPEAK request to deactivate */
+		return FALSE;
+	}
+	source = state_machine->speaker;
+
+	/* create internal STOP request */
+	message = mrcp_request_create(
+						source->channel_id.resource_id,
+						SYNTHESIZER_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 [%d]",message->start_line.request_id);
+	return synth_request_dispatch(state_machine,message);
+}
+
 /** Create MRCP synthesizer server state machine */
-mrcp_state_machine_t* mrcp_synth_server_state_machine_create(void *obj, mrcp_message_dispatcher_f dispatcher, mrcp_version_e version, apr_pool_t *pool)
+mrcp_state_machine_t* mrcp_synth_server_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,dispatcher);
+	mrcp_state_machine_init(&state_machine->base,obj);
 	state_machine->base.update = synth_state_update;
+	state_machine->base.deactivate = synth_state_deactivate;
 	state_machine->state = SYNTHESIZER_STATE_IDLE;
 	state_machine->is_pending = FALSE;
 	state_machine->active_request = NULL;

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp-server/include/mrcp_server_session.h (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp-server/include/mrcp_server_session.h	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp-server/include/mrcp_server_session.h	2009-07-15 20:30:39 UTC (rev 14260)
@@ -93,6 +93,8 @@
 	apr_size_t                 answer_flag_count;
 	/** Number of in-progress terminate requests (flags) */
 	apr_size_t                 terminate_flag_count;
+	/** Number of in-progress deactivare requests (flags) */
+	apr_size_t                 deactivate_flag_count;
 };
 
 /** MRCP profile */

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp-server/src/mrcp_server.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp-server/src/mrcp_server.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp-server/src/mrcp_server.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -595,7 +595,7 @@
 void mrcp_server_session_add(mrcp_server_session_t *session)
 {
 	if(session->base.id.buf) {
-		apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Add Session "APT_SID_FMT,session->base.id.buf);
+		apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Add Session "APT_SID_FMT,MRCP_SESSION_SID(&session->base));
 		apr_hash_set(session->server->session_table,session->base.id.buf,session->base.id.length,session);
 	}
 }
@@ -603,7 +603,7 @@
 void mrcp_server_session_remove(mrcp_server_session_t *session)
 {
 	if(session->base.id.buf) {
-		apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Remove Session "APT_SID_FMT,session->base.id.buf);
+		apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Remove Session "APT_SID_FMT,MRCP_SESSION_SID(&session->base));
 		apr_hash_set(session->server->session_table,session->base.id.buf,session->base.id.length,NULL);
 	}
 }
@@ -820,7 +820,7 @@
 			return profile;
 		}
 	}
-	apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Find Profile by Agent "APT_SID_FMT,session->base.id.buf);
+	apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Find Profile by Agent "APT_SID_FMT,MRCP_SESSION_SID(&session->base));
 	return NULL;
 }
 

Modified: freeswitch/trunk/libs/unimrcp/libs/mrcp-server/src/mrcp_server_session.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/libs/mrcp-server/src/mrcp_server_session.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/libs/mrcp-server/src/mrcp_server_session.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -93,7 +93,10 @@
 						mpf_termination_t *termination, 
 						void *descriptor);
 
+static apt_bool_t state_machine_on_message_dispatch(mrcp_state_machine_t *state_machine, mrcp_message_t *message);
+static apt_bool_t state_machine_on_deactivate(mrcp_state_machine_t *state_machine);
 
+
 mrcp_server_session_t* mrcp_server_session_create()
 {
 	mrcp_server_session_t *session = (mrcp_server_session_t*) mrcp_session_create(sizeof(mrcp_server_session_t)-sizeof(mrcp_session_t));
@@ -106,6 +109,7 @@
 	session->answer = NULL;
 	session->answer_flag_count = 0;
 	session->terminate_flag_count = 0;
+	session->deactivate_flag_count = 0;
 	return session;
 }
 
@@ -123,47 +127,6 @@
 	return resource_engine->method_vtable->create_channel(resource_engine,session->base.pool);
 }
 
-static apt_bool_t mrcp_server_message_dispatch(mrcp_state_machine_t *state_machine, mrcp_message_t *message)
-{
-	mrcp_channel_t *channel = state_machine->obj;
-
-	if(message->start_line.message_type == MRCP_MESSAGE_TYPE_REQUEST) {
-		/* send request message to resource engine for actual processing */
-		if(channel->engine_channel) {
-			mrcp_engine_channel_request_process(channel->engine_channel,message);
-		}
-	}
-	else if(message->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE) {
-		mrcp_server_session_t *session = (mrcp_server_session_t*)channel->session;
-		/* send response message to client */
-		if(channel->control_channel) {
-			/* MRCPv2 */
-			mrcp_server_control_message_send(channel->control_channel,message);
-		}
-		else {
-			/* MRCPv1 */
-			mrcp_session_control_response(channel->session,message);
-		}
-
-		session->active_request = apt_list_pop_front(session->request_queue);
-		if(session->active_request) {
-			mrcp_server_signaling_message_dispatch(session,session->active_request);
-		}
-	}
-	else { 
-		/* send event message to client */
-		if(channel->control_channel) {
-			/* MRCPv2 */
-			mrcp_server_control_message_send(channel->control_channel,message);
-		}
-		else {
-			/* MRCPv1 */
-			mrcp_session_control_response(channel->session,message);
-		}
-	}
-	return TRUE;
-}
-
 static mrcp_channel_t* mrcp_server_channel_create(mrcp_server_session_t *session, const apt_str_t *resource_name, apr_size_t id)
 {
 	mrcp_channel_t *channel;
@@ -200,9 +163,12 @@
 			}
 			channel->state_machine = resource->create_server_state_machine(
 								channel,
-								mrcp_server_message_dispatch,
 								session->base.signaling_agent->mrcp_version,
 								pool);
+			if(channel->state_machine) {
+				channel->state_machine->on_dispatch = state_machine_on_message_dispatch;
+				channel->state_machine->on_deactivate = state_machine_on_deactivate;
+			}
 
 			engine_channel = mrcp_server_engine_channel_create(session,resource_name);
 			if(engine_channel) {
@@ -413,7 +379,7 @@
 		session->context = mpf_context_create(session,5,session->base.pool);
 	}
 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Offer "APT_SID_FMT" [c:%d a:%d v:%d]",
-		session->base.id.buf,
+		MRCP_SESSION_SID(&session->base),
 		descriptor->control_media_arr->nelts,
 		descriptor->audio_media_arr->nelts,
 		descriptor->video_media_arr->nelts);
@@ -447,7 +413,7 @@
 	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,session->base.id.buf);
+	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Terminate Request "APT_SID_FMT,MRCP_SESSION_SID(&session->base));
 	for(i=0; i<session->channels->nelts; i++) {
 		channel = ((mrcp_channel_t**)session->channels->elts)[i];
 		if(!channel) continue;
@@ -499,6 +465,27 @@
 	return TRUE;
 }
 
+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));
+	for(i=0; i<session->channels->nelts; i++) {
+		channel = ((mrcp_channel_t**)session->channels->elts)[i];
+		if(!channel || !channel->state_machine) continue;
+
+		if(mrcp_state_machine_deactivate(channel->state_machine) == TRUE) {
+			session->deactivate_flag_count++;
+		}
+	}
+	
+	if(!session->deactivate_flag_count) {
+		mrcp_server_session_terminate_process(session);
+	}
+
+	return TRUE;
+}
+
 static apt_bool_t mrcp_server_on_message_receive(mrcp_server_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message)
 {
 	if(!channel) {
@@ -528,7 +515,7 @@
 			mrcp_server_on_message_receive(signaling_message->session,signaling_message->channel,signaling_message->message);
 			break;
 		case SIGNALING_MESSAGE_TERMINATE:
-			mrcp_server_session_terminate_process(signaling_message->session);
+			mrcp_server_session_deactivate(signaling_message->session);
 			break;
 		default:
 			break;
@@ -749,7 +736,7 @@
 	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",
-		session->base.id.buf,
+		MRCP_SESSION_SID(&session->base),
 		descriptor->control_media_arr->nelts,
 		descriptor->audio_media_arr->nelts,
 		descriptor->video_media_arr->nelts,
@@ -782,7 +769,7 @@
 			channel->engine_channel = NULL;
 		}
 	}
-	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Terminate Response "APT_SID_FMT,session->base.id.buf);
+	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Terminate Response "APT_SID_FMT,MRCP_SESSION_SID(&session->base));
 	mrcp_session_terminate_response(&session->base);
 	return TRUE;
 }
@@ -912,6 +899,60 @@
 	return TRUE;
 }
 
+static apt_bool_t state_machine_on_message_dispatch(mrcp_state_machine_t *state_machine, mrcp_message_t *message)
+{
+	mrcp_channel_t *channel = state_machine->obj;
+
+	if(message->start_line.message_type == MRCP_MESSAGE_TYPE_REQUEST) {
+		/* send request message to resource engine for actual processing */
+		if(channel->engine_channel) {
+			mrcp_engine_channel_request_process(channel->engine_channel,message);
+		}
+	}
+	else if(message->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE) {
+		mrcp_server_session_t *session = (mrcp_server_session_t*)channel->session;
+		/* send response message to client */
+		if(channel->control_channel) {
+			/* MRCPv2 */
+			mrcp_server_control_message_send(channel->control_channel,message);
+		}
+		else {
+			/* MRCPv1 */
+			mrcp_session_control_response(channel->session,message);
+		}
+
+		session->active_request = apt_list_pop_front(session->request_queue);
+		if(session->active_request) {
+			mrcp_server_signaling_message_dispatch(session,session->active_request);
+		}
+	}
+	else { 
+		/* send event message to client */
+		if(channel->control_channel) {
+			/* MRCPv2 */
+			mrcp_server_control_message_send(channel->control_channel,message);
+		}
+		else {
+			/* MRCPv1 */
+			mrcp_session_control_response(channel->session,message);
+		}
+	}
+	return TRUE;
+}
+
+static apt_bool_t state_machine_on_deactivate(mrcp_state_machine_t *state_machine)
+{
+	mrcp_channel_t *channel = state_machine->obj;
+	mrcp_server_session_t *session = (mrcp_server_session_t*)channel->session;
+	if(session->deactivate_flag_count) {
+		session->deactivate_flag_count --;
+		if(!session->deactivate_flag_count) {
+			mrcp_server_session_terminate_process(session);
+		}
+	}
+	return TRUE;
+}
+
 static apt_bool_t mrcp_server_mpf_request_send(
 						mrcp_server_session_t *session, 
 						mpf_command_type_e command_id, 

Modified: freeswitch/trunk/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sdp.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sdp.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/modules/mrcp-sofiasip/src/mrcp_sdp.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-
+#include <stdlib.h>
 #include <apr_general.h>
 #include <sofia-sip/sdp.h>
 #include "mrcp_sdp.h"

Modified: freeswitch/trunk/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_sdp.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_sdp.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/modules/mrcp-unirtsp/src/mrcp_unirtsp_sdp.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <stdlib.h>
 #include <apr_general.h>
 #include <sofia-sip/sdp.h>
 #include "rtsp_message.h"

Modified: freeswitch/trunk/libs/unimrcp/platforms/libunimrcp-client/src/unimrcp_client.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/platforms/libunimrcp-client/src/unimrcp_client.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/platforms/libunimrcp-client/src/unimrcp_client.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <stdlib.h>
 #include <apr_xml.h>
 #include "unimrcp_client.h"
 #include "uni_version.h"

Modified: freeswitch/trunk/libs/unimrcp/platforms/libunimrcp-server/src/unimrcp_server.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/platforms/libunimrcp-server/src/unimrcp_server.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/platforms/libunimrcp-server/src/unimrcp_server.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <stdlib.h>
 #include <apr_xml.h>
 #include "unimrcp_server.h"
 #include "uni_version.h"

Modified: freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/include/demo_util.h (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/include/demo_util.h	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/include/demo_util.h	2009-07-15 20:30:39 UTC (rev 14260)
@@ -34,6 +34,8 @@
 /** Create demo MRCP message (RECOGNIZE request) */
 mrcp_message_t* demo_recognize_message_create(mrcp_session_t *session, mrcp_channel_t *channel, const apt_dir_layout_t *dir_layout);
 
+/** Parse NLSML result */
+apt_bool_t demo_nlsml_result_parse(mrcp_message_t *message);
 
 /** Create demo RTP termination descriptor */
 mpf_rtp_termination_descriptor_t* demo_rtp_descriptor_create(apr_pool_t *pool);

Modified: freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/src/demo_recog_application.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/src/demo_recog_application.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/src/demo_recog_application.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -291,6 +291,7 @@
 	}
 	else if(message->start_line.message_type == MRCP_MESSAGE_TYPE_EVENT) {
 		if(message->start_line.method_id == RECOGNIZER_RECOGNITION_COMPLETE) {
+			demo_nlsml_result_parse(message);
 			if(recog_channel) {
 				recog_channel->streaming = FALSE;
 			}

Modified: freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/src/demo_util.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/src/demo_util.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/platforms/unimrcp-client/src/demo_util.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -25,6 +25,10 @@
 /* recognizer includes */
 #include "mrcp_recog_header.h"
 #include "mrcp_recog_resource.h"
+/* NLSML doc include */
+#include "apt_nlsml_doc.h"
+/* logger include */
+#include "apt_log.h"
 
 static void demo_message_body_set(mrcp_message_t *mrcp_message, const apt_dir_layout_t *dir_layout, const char *file_name)
 {
@@ -127,6 +131,8 @@
 			mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_RECOGNITION_TIMEOUT);
 			recog_header->start_input_timers = TRUE;
 			mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_START_INPUT_TIMERS);
+			recog_header->confidence_threshold = 0.87f;
+			mrcp_resource_header_property_add(mrcp_message,RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD);
 		}
 		/* set message body */
 		apt_string_assign(&mrcp_message->body,text,mrcp_message->pool);
@@ -134,6 +140,37 @@
 	return mrcp_message;
 }
 
+/** Parse NLSML result */
+apt_bool_t demo_nlsml_result_parse(mrcp_message_t *message)
+{
+	apr_xml_elem *interpret;
+	apr_xml_elem *instance;
+	apr_xml_elem *input;
+	apr_xml_doc *doc = nlsml_doc_load(&message->body,message->pool);
+	if(!doc) {
+		return FALSE;
+	}
+	
+	/* walk through interpreted results */
+	interpret = nlsml_first_interpret_get(doc);
+	for(; interpret; interpret = nlsml_next_interpret_get(interpret)) {
+		/* get instance and input */
+		nlsml_interpret_results_get(interpret,&instance,&input);
+		if(instance) {
+			/* process instance */
+			if(instance->first_cdata.first) {
+				apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Interpreted Instance [%s]",instance->first_cdata.first->text);
+			}
+		}
+		if(input) {
+			/* process input */
+			if(input->first_cdata.first) {
+				apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Interpreted Input [%s]",input->first_cdata.first->text);
+			}
+		}
+	}
+	return TRUE;
+}
 
 /** Create demo RTP termination descriptor */
 mpf_rtp_termination_descriptor_t* demo_rtp_descriptor_create(apr_pool_t *pool)

Modified: freeswitch/trunk/libs/unimrcp/plugins/mrcp-flite/src/mrcp_flite.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/plugins/mrcp-flite/src/mrcp_flite.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/plugins/mrcp-flite/src/mrcp_flite.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -119,6 +119,8 @@
 /* we have a special task for the actual synthesis - 
    the task is created when a mrcp speak message is received */
 static apt_bool_t flite_speak(apt_task_t *task, apt_task_msg_t *msg);
+static apt_bool_t flite_on_start(apt_task_t *task);
+static apt_bool_t flite_on_terminate(apt_task_t *task);
 
 /** Declare this macro to use log routine of the server where the plugin is loaded from */
 MRCP_PLUGIN_LOGGER_IMPLEMENT
@@ -184,14 +186,16 @@
 	}
 
 	task_vtable = apt_consumer_task_vtable_get(consumer_task);
-	if(!task_vtable) {
-		apt_log(APT_LOG_MARK,APT_PRIO_ERROR, "flite_synth_channel_speak cannot use flite speak task vtable - channel:%d", synth_channel->iId);
-		return FALSE;
+	if(task_vtable) {
+		task_vtable->process_msg = flite_speak;
+		task_vtable->on_pre_run = flite_on_start;
+		task_vtable->on_post_run = flite_on_terminate;
 	}
-
-	task_vtable->process_msg = flite_speak;
 	synth_channel->msg_pool = msg_pool;
 	synth_channel->task = apt_consumer_task_base_get(consumer_task);
+	if(synth_channel->task) {
+		apt_task_name_set(synth_channel->task,"Flite Task");
+	}
 	return TRUE;
 }
 
@@ -199,19 +203,10 @@
 static mrcp_engine_channel_t* flite_synth_engine_channel_create(mrcp_resource_engine_t *engine, apr_pool_t *pool)
 {
 	/* create flite synth channel */
+	mpf_codec_descriptor_t *codec_descriptor = NULL;
 	flite_synth_channel_t *synth_channel = (flite_synth_channel_t *) apr_palloc(pool,sizeof(flite_synth_channel_t));
-	mpf_codec_descriptor_t *codec_descriptor = NULL;
 
 	apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "flite_synth_engine_channel_create");
-#if 0
-	codec_descriptor = (mpf_codec_descriptor_t *) apr_palloc(pool,sizeof(mpf_codec_descriptor_t));
-	mpf_codec_descriptor_init(codec_descriptor);
-	codec_descriptor->channel_count = 1;
-	codec_descriptor->payload_type = 96;
-	apt_string_set(&codec_descriptor->name,"LPCM");
-	codec_descriptor->sampling_rate = 16000;
-#endif
-
 	synth_channel->flite_engine = (flite_synth_engine_t *) engine->obj;
 	synth_channel->speak_request = NULL; // no active speak request in progress
 	synth_channel->speak_response = NULL;
@@ -228,6 +223,15 @@
 		return NULL;
 	}
 
+#if 0
+	codec_descriptor = (mpf_codec_descriptor_t *) apr_palloc(pool,sizeof(mpf_codec_descriptor_t));
+	mpf_codec_descriptor_init(codec_descriptor);
+	codec_descriptor->channel_count = 1;
+	codec_descriptor->payload_type = 96;
+	apt_string_set(&codec_descriptor->name,"LPCM");
+	codec_descriptor->sampling_rate = 16000;
+#endif
+
 	/* create engine channel base */
 	synth_channel->channel = mrcp_engine_source_channel_create(
 			engine,               /* resource engine */
@@ -272,14 +276,15 @@
 
 	if(synth_channel->task) {
 		if(apt_task_start(synth_channel->task) == TRUE) {
-			apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "Speak task started - channel %d", synth_channel->iId);
+			/* async response will be sent */
+			return TRUE;
 		}
 		else {
 			apt_log(APT_LOG_MARK, APT_PRIO_WARNING, "Speak task start failed - channel %d", synth_channel->iId);
 		}
 	}
 
-	return mrcp_engine_channel_open_respond(channel,TRUE);
+	return mrcp_engine_channel_open_respond(channel,FALSE);
 }
 
 /** Close engine channel (asynchronous response MUST be sent)*/
@@ -289,15 +294,15 @@
 	apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "flite_synth_channel_close - channel %d", synth_channel->iId);
 
 	if(synth_channel->task) {
-		if(apt_task_terminate(synth_channel->task,TRUE) == TRUE) {
-			apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "Speak task terminated - channel %d", synth_channel->iId);
+		if(apt_task_terminate(synth_channel->task,FALSE) == TRUE) {
+			/* async response will be sent */
+			return TRUE;
 		}
 		else {
 			apt_log(APT_LOG_MARK, APT_PRIO_WARNING, "Speak task terminate failed - channel %d", synth_channel->iId);
 		}
 	}
-	mrcp_engine_channel_close_respond(channel);
-	return TRUE; 
+	return mrcp_engine_channel_close_respond(channel);
 }
 
 /** Process MRCP channel request (asynchronous response MUST be sent)*/
@@ -428,7 +433,7 @@
 	apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "< flite_speak_msg_process speak - channel %d", synth_channel->iId);
 	
 	/* just sequential stuff */
-	start = apr_time_now();	// in microsec
+	start = apr_time_now();	/* in microsec */
 	if(!body->length) {
 		synth_channel->speak_request = NULL;
 		synth_response_construct(response,MRCP_STATUS_CODE_MISSING_PARAM,SYNTHESIZER_COMPLETION_CAUSE_ERROR);
@@ -479,7 +484,7 @@
 		delete_wave(wave);
 	}
 
-	// this will notify the callback that feeds the client that synthesis is complete
+	/* this will notify the callback that feeds the client that synthesis is complete */
 	mpf_buffer_event_write(synth_channel->audio_buffer, MEDIA_FRAME_TYPE_EVENT);
 	synth_channel->synthesizing = FALSE;
 
@@ -487,6 +492,26 @@
 	return TRUE;
 }
 
+static APR_INLINE flite_synth_channel_t* flite_synth_channel_get(apt_task_t *task)
+{
+	apt_consumer_task_t *consumer_task = apt_task_object_get(task);
+	return apt_consumer_task_object_get(consumer_task);
+}
+
+static apt_bool_t flite_on_start(apt_task_t *task)
+{
+	flite_synth_channel_t *synth_channel = flite_synth_channel_get(task);
+	apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "Speak task started - channel %d", synth_channel->iId);
+	return mrcp_engine_channel_open_respond(synth_channel->channel,TRUE);
+}
+
+static apt_bool_t flite_on_terminate(apt_task_t *task)
+{
+	flite_synth_channel_t *synth_channel = flite_synth_channel_get(task);
+	apt_log(APT_LOG_MARK, APT_PRIO_DEBUG, "Speak task terminated - channel %d", synth_channel->iId);
+	return mrcp_engine_channel_close_respond(synth_channel->channel);
+}
+
 /** Process STOP request */
 static apt_bool_t flite_synth_channel_stop(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response)
 {

Modified: freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/src/mrcp_pocketsphinx.c (14259 => 14260)


--- freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/src/mrcp_pocketsphinx.c	2009-07-15 16:54:20 UTC (rev 14259)
+++ freeswitch/trunk/libs/unimrcp/plugins/mrcp-pocketsphinx/src/mrcp_pocketsphinx.c	2009-07-15 20:30:39 UTC (rev 14260)
@@ -237,7 +237,10 @@
 			recognizer,           /* object to associate */
 			NULL,                 /* codec descriptor might be NULL by default */
 			pool);                /* pool to allocate memory from */
-	
+
+	apr_thread_mutex_create(&recognizer->mutex,APR_THREAD_MUTEX_DEFAULT,channel->pool);
+	apr_thread_cond_create(&recognizer->wait_object,channel->pool);
+
 	recognizer->channel = channel;
 	return channel;
 }
@@ -245,6 +248,15 @@
 /** Destroy pocketsphinx recognizer */
 static apt_bool_t pocketsphinx_recognizer_destroy(mrcp_engine_channel_t *channel)
 {
+	pocketsphinx_recognizer_t *recognizer = channel->method_obj;
+	if(recognizer->mutex) {
+		apr_thread_mutex_destroy(recognizer->mutex);
+		recognizer->mutex = NULL;
+	}
+	if(recognizer->wait_object) {
+		apr_thread_cond_destroy(recognizer->wait_object);
+		recognizer->wait_object = NULL;
+	}
 	return TRUE;
 }
 
@@ -256,17 +268,10 @@
 
 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open Channel "APT_SIDRES_FMT,RECOGNIZER_SIDRES(recognizer));
 
-	apr_thread_mutex_create(&recognizer->mutex,APR_THREAD_MUTEX_DEFAULT,channel->pool);
-	apr_thread_cond_create(&recognizer->wait_object,channel->pool);
-
 	/* Launch a thread to run recognition in */
 	rv = apr_thread_create(&recognizer->thread,NULL,pocketsphinx_recognizer_run,recognizer,channel->pool);
 	if(rv != APR_SUCCESS) {
 		apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Failed to Launch Thread "APT_SIDRES_FMT,RECOGNIZER_SIDRES(recognizer));
-		apr_thread_mutex_destroy(recognizer->mutex);
-		recognizer->mutex = NULL;
-		apr_thread_cond_destroy(recognizer->wait_object);
-		recognizer->wait_object = NULL;
 		return mrcp_engine_channel_open_respond(channel,FALSE);
 	}
 
@@ -278,25 +283,16 @@
 {
 	pocketsphinx_recognizer_t *recognizer = channel->method_obj;
 	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Close Channel "APT_SIDRES_FMT,RECOGNIZER_SIDRES(recognizer));
-	if(recognizer->thread) {
-		apr_status_t rv;
-		
-		/* Signal recognition thread to terminate */
-		apr_thread_mutex_lock(recognizer->mutex);
-		recognizer->close_requested = TRUE;
-		apr_thread_cond_signal(recognizer->wait_object);
-		apr_thread_mutex_unlock(recognizer->mutex);
-
-		apr_thread_join(&rv,recognizer->thread);
-		recognizer->thread = NULL;
-
-		apr_thread_mutex_destroy(recognizer->mutex);
-		recognizer->mutex = NULL;
-		apr_thread_cond_destroy(recognizer->wait_object);
-		recognizer->wait_object = NULL;
+	if(!recognizer->thread) {
+		return mrcp_engine_channel_close_respond(channel);
 	}
 
-	return mrcp_engine_channel_close_respond(channel);
+	/* Signal recognition thread to terminate */
+	apr_thread_mutex_lock(recognizer->mutex);
+	recognizer->close_requested = TRUE;
+	apr_thread_cond_signal(recognizer->wait_object);
+	apr_thread_mutex_unlock(recognizer->mutex);
+	return TRUE;
 }
 
 /** Process MRCP request (asynchronous response MUST be sent)*/
@@ -533,12 +529,10 @@
 		return FALSE;
 	}
 
-	response_recog_header->completion_cause = RECOGNIZER_COMPLETION_CAUSE_SUCCESS;
-	mrcp_resource_header_property_add(response,RECOGNIZER_HEADER_COMPLETION_CAUSE);
-
 	if(!recognizer->decoder || ps_start_utt(recognizer->decoder, NULL) < 0) {
 		response->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED;
 		response_recog_header->completion_cause = RECOGNIZER_COMPLETION_CAUSE_ERROR;
+		mrcp_resource_header_property_add(response,RECOGNIZER_HEADER_COMPLETION_CAUSE);
 		return FALSE;
 	}
 
@@ -755,17 +749,6 @@
 	}
 	while(recognizer->close_requested == FALSE);
 
-	/* check if recognition is still active */
-	if(recognizer->inprogress_recog) {
-		apr_thread_mutex_lock(recognizer->mutex);
-		recognizer->stop_response = recognizer->inprogress_recog;
-		apr_thread_cond_wait(recognizer->wait_object,recognizer->mutex);
-		apr_thread_mutex_unlock(recognizer->mutex);
-		if(recognizer->complete_event) {
-			pocketsphinx_recognition_complete(recognizer,recognizer->complete_event);
-		}
-	}
-
 	/** Clear all the defined grammars */
 	pocketsphinx_grammars_clear(recognizer);
 	
@@ -776,6 +759,10 @@
 		recognizer->decoder = NULL;
 	}
 
+	recognizer->thread = NULL;
+	/** Finally send response to channel_close request */
+	mrcp_engine_channel_close_respond(recognizer->channel);
+
 	/** Exit thread */
 	apr_thread_exit(thread,APR_SUCCESS);
 	return NULL;