[Freeswitch-svn] [commit] r1846 - in freeswitch/trunk/src: . include mod/applications/mod_ivrtest mod/applications/mod_playback mod/applications/mod_rss mod/endpoints/mod_dingaling mod/event_handlers/mod_xmpp_event mod/languages/mod_spidermonkey

Freeswitch SVN anthm at freeswitch.org
Wed Jul 12 14:39:19 EDT 2006


Author: anthm
Date: Wed Jul 12 14:39:19 2006
New Revision: 1846

Modified:
   freeswitch/trunk/src/include/switch_core.h
   freeswitch/trunk/src/include/switch_ivr.h
   freeswitch/trunk/src/include/switch_module_interfaces.h
   freeswitch/trunk/src/include/switch_types.h
   freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c
   freeswitch/trunk/src/mod/applications/mod_playback/mod_playback.c
   freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c
   freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
   freeswitch/trunk/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c
   freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
   freeswitch/trunk/src/switch_core.c
   freeswitch/trunk/src/switch_ivr.c

Log:
rearrange the furnature

Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h	(original)
+++ freeswitch/trunk/src/include/switch_core.h	Wed Jul 12 14:39:19 2006
@@ -335,9 +335,17 @@
   \param event the event to send
   \return the status returned by the message handler
 */
-SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, switch_event_t *event);
+SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, switch_event_t **event);
 
 /*! 
+  \brief Send an event to a session translating it to it's native message format
+  \param session the session to receive the event
+  \param event the event to receive
+  \return the status returned by the handler
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_session_receive_event(switch_core_session_t *session, switch_event_t **event);
+
+/*! 
   \brief Retrieve private user data from a session
   \param session the session to retrieve from
   \return a pointer to the private data
@@ -433,7 +441,16 @@
   \param event the event to queue
   \return the status returned by the message handler
 */
-SWITCH_DECLARE(switch_status_t) switch_core_session_queue_event(switch_core_session_t *session, switch_event_t *event);
+SWITCH_DECLARE(switch_status_t) switch_core_session_queue_event(switch_core_session_t *session, switch_event_t **event);
+
+/*! 
+  \brief DE-Queue an event on a given session
+  \param session the session to de-queue the message on
+  \param event the de-queued event
+  \return the  SWITCH_STATUS_SUCCESS if the event was de-queued
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_event(switch_core_session_t *session, switch_event_t **event);
+
 
 /*! 
   \brief Read a frame from a session

Modified: freeswitch/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_ivr.h	(original)
+++ freeswitch/trunk/src/include/switch_ivr.h	Wed Jul 12 14:39:19 2006
@@ -59,7 +59,7 @@
   \return SWITCH_STATUS_SUCCESS to keep the collection moving.
 */
 SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_session_t *session,
-																 switch_dtmf_callback_function_t dtmf_callback,
+																 switch_input_callback_function_t dtmf_callback,
 																 void *buf,
 																 unsigned int buflen);
 
@@ -98,7 +98,7 @@
 												   switch_file_handle_t *fh,
 												   char *file,
 												   char *timer_name,
-												   switch_dtmf_callback_function_t dtmf_callback,
+												   switch_input_callback_function_t dtmf_callback,
 												   void *buf,
 												   unsigned int buflen);
 
@@ -118,7 +118,7 @@
 SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *session,
 													 switch_file_handle_t *fh,
 													 char *file,
-													 switch_dtmf_callback_function_t dtmf_callback,
+													 switch_input_callback_function_t dtmf_callback,
 													 void *buf,
 													 unsigned int buflen);
 
@@ -127,7 +127,7 @@
                                                              switch_speech_handle_t *sh,
                                                              switch_codec_t *codec,
                                                              switch_timer_t *timer,
-                                                             switch_dtmf_callback_function_t dtmf_callback,
+                                                             switch_input_callback_function_t dtmf_callback,
                                                              char *text,
                                                              void *buf,
                                                              unsigned int buflen);
@@ -150,7 +150,7 @@
 													  char *voice_name,
 													  char *timer_name,
 													  uint32_t rate,
-													  switch_dtmf_callback_function_t dtmf_callback,
+													  switch_input_callback_function_t dtmf_callback,
 													  char *text,
 													  void *buf,
 													  unsigned int buflen);
@@ -169,7 +169,7 @@
 SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_session_t *session, 
 															   switch_core_session_t *peer_session,
 															   unsigned int timelimit,
-															   switch_dtmf_callback_function_t dtmf_callback,
+															   switch_input_callback_function_t dtmf_callback,
 															   void *session_data,
 															   void *peer_session_data);
 

Modified: freeswitch/trunk/src/include/switch_module_interfaces.h
==============================================================================
--- freeswitch/trunk/src/include/switch_module_interfaces.h	(original)
+++ freeswitch/trunk/src/include/switch_module_interfaces.h	Wed Jul 12 14:39:19 2006
@@ -93,10 +93,10 @@
 };
 
 /*! \brief Node in which to store custom receive message callback hooks */
-struct switch_io_event_hook_queue_event {
+struct switch_io_event_hook_receive_event {
 	/*! the answer channel callback hook*/
-	switch_queue_event_hook_t queue_event;
-	struct switch_io_event_hook_queue_event *next;
+	switch_receive_event_hook_t receive_event;
+	struct switch_io_event_hook_receive_event *next;
 };
 
 /*! \brief Node in which to store custom read frame channel callback hooks */
@@ -150,7 +150,7 @@
 	/*! a list of receive message hooks */
 	switch_io_event_hook_receive_message_t *receive_message;
 	/*! a list of queue message hooks */
-	switch_io_event_hook_queue_event_t *queue_event;
+	switch_io_event_hook_receive_event_t *receive_event;
 	/*! a list of read frame hooks */
 	switch_io_event_hook_read_frame_t *read_frame;
 	/*! a list of write frame hooks */
@@ -186,7 +186,7 @@
 	/*! receive a message from another session*/
 	switch_status_t (*receive_message)(switch_core_session_t *, switch_core_session_message_t *);
 	/*! queue a message for another session*/
-	switch_status_t (*queue_event)(switch_core_session_t *, switch_event_t *);
+	switch_status_t (*receive_event)(switch_core_session_t *, switch_event_t *);
 };
 
 /*! \brief Abstraction of an module endpoint interface

Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h	(original)
+++ freeswitch/trunk/src/include/switch_types.h	Wed Jul 12 14:39:19 2006
@@ -573,6 +573,10 @@
 	SWITCH_EVENT_ALL
 } switch_event_types_t;
 
+typedef enum {
+	SWITCH_INPUT_TYPE_DTMF,
+	SWITCH_INPUT_TYPE_EVENT
+} switch_input_type_t;
 
 typedef enum {
 	SWITCH_CAUSE_UNALLOCATED = 1,
@@ -651,7 +655,7 @@
 typedef struct switch_io_event_hook_outgoing_channel switch_io_event_hook_outgoing_channel_t;
 typedef struct switch_io_event_hook_answer_channel switch_io_event_hook_answer_channel_t;
 typedef struct switch_io_event_hook_receive_message switch_io_event_hook_receive_message_t;
-typedef struct switch_io_event_hook_queue_event switch_io_event_hook_queue_event_t;
+typedef struct switch_io_event_hook_receive_event switch_io_event_hook_receive_event_t;
 typedef struct switch_io_event_hook_read_frame switch_io_event_hook_read_frame_t;
 typedef struct switch_io_event_hook_write_frame switch_io_event_hook_write_frame_t;
 typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_channel_t;
@@ -682,7 +686,7 @@
 typedef switch_status_t (*switch_outgoing_channel_hook_t)(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t *);
 typedef switch_status_t (*switch_answer_channel_hook_t)(switch_core_session_t *);
 typedef switch_status_t (*switch_receive_message_hook_t)(switch_core_session_t *, switch_core_session_message_t *);
-typedef switch_status_t (*switch_queue_event_hook_t)(switch_core_session_t *, switch_event_t *);
+typedef switch_status_t (*switch_receive_event_hook_t)(switch_core_session_t *, switch_event_t *);
 typedef switch_status_t (*switch_read_frame_hook_t)(switch_core_session_t *, switch_frame_t **, int, switch_io_flag_t, int);
 typedef switch_status_t (*switch_write_frame_hook_t)(switch_core_session_t *, switch_frame_t *, int, switch_io_flag_t, int);
 typedef switch_status_t (*switch_kill_channel_hook_t)(switch_core_session_t *, int);
@@ -692,7 +696,11 @@
 typedef struct switch_stream_handle switch_stream_handle_t;
 typedef switch_status_t (*switch_stream_handle_write_function_t)(switch_stream_handle_t *handle, char *fmt, ...);
 typedef switch_status_t (*switch_api_function_t)(char *in, switch_stream_handle_t *stream);
-typedef switch_status_t (*switch_dtmf_callback_function_t)(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen);
+typedef switch_status_t (*switch_input_callback_function_t)(switch_core_session_t *session,
+															void *input,
+															switch_input_type_t input_type,
+															void *buf,
+															unsigned int buflen);
 typedef int (*switch_core_db_callback_func_t)(void *pArg, int argc, char **argv, char **columnNames);
 typedef switch_status_t (*switch_module_load_t) (switch_loadable_module_interface_t **, char *);
 typedef switch_status_t (*switch_module_reload_t) (void);

Modified: freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c	Wed Jul 12 14:39:19 2006
@@ -39,16 +39,23 @@
   dtmf handler function you can hook up to be executed when a digit is dialed during playback 
    if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 */
-static switch_status_t on_dtmf(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
+static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 {
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digits %s\n", dtmf);
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF: {
+		char *dtmf = (char *) input;
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digits %s\n", dtmf);
 	
-	switch_copy_string((char *)buf, dtmf, buflen);
-	return SWITCH_STATUS_BREAK;
-
+		switch_copy_string((char *)buf, dtmf, buflen);
+		return SWITCH_STATUS_BREAK;
+	}
+		break;
+	default:
+		break;
+	}
+	return SWITCH_STATUS_SUCCESS;
 }
 
-
 static void disast_function(switch_core_session_t *session, char *data)
 {
 	void *x = NULL;
@@ -107,13 +114,22 @@
 
 }
 
-static switch_status_t show_dtmf(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
+static switch_status_t show_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 {
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digits %s\n", dtmf);
-	
-	switch_copy_string((char *)buf, dtmf, buflen);
-	return SWITCH_STATUS_SUCCESS;
 
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF: {
+		char *dtmf = (char *) input;
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digits %s\n", dtmf);
+
+		switch_copy_string((char *)buf, dtmf, buflen);
+	}
+		break;
+	default:
+		break;
+	}
+
+	return SWITCH_STATUS_SUCCESS;
 }
 
 static void tts_function(switch_core_session_t *session, char *data)

Modified: freeswitch/trunk/src/mod/applications/mod_playback/mod_playback.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_playback/mod_playback.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_playback/mod_playback.c	Wed Jul 12 14:39:19 2006
@@ -37,12 +37,22 @@
   dtmf handler function you can hook up to be executed when a digit is dialed during playback 
    if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 */
-static switch_status_t on_dtmf(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
+static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 {
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digits %s\n", dtmf);
 
-	if (*dtmf == '*') {
-		return SWITCH_STATUS_FALSE;
+	
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF: {
+		char *dtmf = (char *) input;
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digits %s\n", dtmf);
+		
+		if (*dtmf == '*') {
+			return SWITCH_STATUS_FALSE;
+		}
+	}
+		break;
+	default:
+		break;
 	}
 	
 	return SWITCH_STATUS_SUCCESS;

Modified: freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_rss/mod_rss.c	Wed Jul 12 14:39:19 2006
@@ -85,68 +85,74 @@
   dtmf handler function you can hook up to be executed when a digit is dialed during playback 
   if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 */
-static switch_status_t on_dtmf(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
-{
+static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 
-	struct dtmf_buffer *dtb;
-	dtb = (struct dtmf_buffer *) buf;
+{
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF: {
+		char *dtmf = (char *) input;
+		struct dtmf_buffer *dtb;
+		dtb = (struct dtmf_buffer *) buf;
 	
-	switch(*dtmf) {
-	case '#':
-		switch_set_flag(dtb, SFLAG_MAIN);
-		return SWITCH_STATUS_BREAK;
-	case '6':
-		dtb->index++;
-		return SWITCH_STATUS_BREAK;
-	case '4':
-		dtb->index--;
-		return SWITCH_STATUS_BREAK;
-	case '*':
-		if (switch_test_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE)) {
-			switch_clear_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE);
-		} else {
-			switch_set_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE);
-		}
-		break;
-	case '5':
-		switch_core_speech_text_param_tts(dtb->sh, "voice", "next");
-		switch_set_flag(dtb, SFLAG_INFO);
-		return SWITCH_STATUS_BREAK;
-		break;
-	case '9':
-		switch_core_speech_text_param_tts(dtb->sh, "voice", dtb->voice);
-		switch_set_flag(dtb, SFLAG_INFO);
-		return SWITCH_STATUS_BREAK;
-		break;
-	case '2':
-		if (dtb->speed < 260) {
-			dtb->speed += 30;
-			switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed);
+		switch(*dtmf) {
+		case '#':
+			switch_set_flag(dtb, SFLAG_MAIN);
+			return SWITCH_STATUS_BREAK;
+		case '6':
+			dtb->index++;
+			return SWITCH_STATUS_BREAK;
+		case '4':
+			dtb->index--;
+			return SWITCH_STATUS_BREAK;
+		case '*':
+			if (switch_test_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE)) {
+				switch_clear_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE);
+			} else {
+				switch_set_flag(dtb->sh, SWITCH_SPEECH_FLAG_PAUSE);
+			}
+			break;
+		case '5':
+			switch_core_speech_text_param_tts(dtb->sh, "voice", "next");
 			switch_set_flag(dtb, SFLAG_INFO);
 			return SWITCH_STATUS_BREAK;
-		}
-		break;
-	case '7':
-		dtb->speed = TTS_MEAN_SPEED;
-		switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed);
-		switch_set_flag(dtb, SFLAG_INFO);
-		return SWITCH_STATUS_BREAK;
-	case '8':
-		if (dtb->speed > 80) {
-			dtb->speed -= 30;
+			break;
+		case '9':
+			switch_core_speech_text_param_tts(dtb->sh, "voice", dtb->voice);
+			switch_set_flag(dtb, SFLAG_INFO);
+			return SWITCH_STATUS_BREAK;
+			break;
+		case '2':
+			if (dtb->speed < 260) {
+				dtb->speed += 30;
+				switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed);
+				switch_set_flag(dtb, SFLAG_INFO);
+				return SWITCH_STATUS_BREAK;
+			}
+			break;
+		case '7':
+			dtb->speed = TTS_MEAN_SPEED;
 			switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed);
 			switch_set_flag(dtb, SFLAG_INFO);
 			return SWITCH_STATUS_BREAK;
+		case '8':
+			if (dtb->speed > 80) {
+				dtb->speed -= 30;
+				switch_core_speech_numeric_param_tts(dtb->sh, "speech/rate", dtb->speed);
+				switch_set_flag(dtb, SFLAG_INFO);
+				return SWITCH_STATUS_BREAK;
+			}
+			break;
+		case '0':
+			switch_set_flag(dtb, SFLAG_INSTRUCT);
+			return SWITCH_STATUS_BREAK;
 		}
+	}
 		break;
-	case '0':
-		switch_set_flag(dtb, SFLAG_INSTRUCT);
-		return SWITCH_STATUS_BREAK;
+	default:
+		break;
 	}
-
 	return SWITCH_STATUS_SUCCESS;
 }
-
 
 static void rss_function(switch_core_session_t *session, char *data)
 {

Modified: freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c	Wed Jul 12 14:39:19 2006
@@ -1509,7 +1509,9 @@
 			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
 			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", subject);
 			switch_event_add_body(event, msg);
-			switch_event_fire(&event);
+			if (switch_core_session_queue_event(tech_pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
+				switch_event_fire(&event);
+			}
 		}
 		break;
 

Modified: freeswitch/trunk/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c	(original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c	Wed Jul 12 14:39:19 2006
@@ -239,6 +239,7 @@
 	stream.data = retbuf;
 	stream.end = stream.data;
 	stream.data_size = sizeof(retbuf);
+	stream.write_function = switch_console_stream_write;
 	switch_api_execute(cmd, arg, &stream);
 
 	return 0;

Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c	(original)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c	Wed Jul 12 14:39:19 2006
@@ -175,218 +175,247 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static switch_status_t js_stream_dtmf_callback(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
+static switch_status_t js_stream_dtmf_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 {
-	char code[2048];
-	struct dtmf_callback_state *cb_state = buf;
-	struct js_session *jss = cb_state->session_state;
-	switch_file_handle_t *fh = cb_state->extra;
-	jsval rval;
-	char *ret;
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF: {
+		char *dtmf = (char *) input;
+		char code[2048];
+		struct dtmf_callback_state *cb_state = buf;
+		struct js_session *jss = cb_state->session_state;
+		switch_file_handle_t *fh = cb_state->extra;
+		jsval rval;
+		char *ret;
 	
-	if (!jss) {
-		return SWITCH_STATUS_FALSE;
-	}
-	
-	if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) {
-		char *d;
-		if (!cb_state->digit_count) {
-			cb_state->digit_count = atoi(cb_state->code_buffer);
+		if (!jss) {
+			return SWITCH_STATUS_FALSE;
 		}
+	
+		if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) {
+			char *d;
+			if (!cb_state->digit_count) {
+				cb_state->digit_count = atoi(cb_state->code_buffer);
+			}
 
-		for(d = dtmf; *d; d++) {
-			cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d;
-			if ((cb_state->ret_buffer_len > cb_state->digit_count)||
-				(cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))||
-				(cb_state->ret_buffer_len >= cb_state->digit_count)
-				) {
-				return SWITCH_STATUS_FALSE;
+			for(d = dtmf; *d; d++) {
+				cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d;
+				if ((cb_state->ret_buffer_len > cb_state->digit_count)||
+					(cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))||
+					(cb_state->ret_buffer_len >= cb_state->digit_count)
+					) {
+					return SWITCH_STATUS_FALSE;
+				}
 			}
-		}
-		return SWITCH_STATUS_SUCCESS;
-	} else {
-		snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf);
-		eval_some_js(code, jss->cx, jss->obj, &rval);
-		ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval));
+			return SWITCH_STATUS_SUCCESS;
+		} else {
+			snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf);
+			eval_some_js(code, jss->cx, jss->obj, &rval);
+			ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval));
 
-		if (!strncasecmp(ret, "speed", 4)) {
-			char *p;
+			if (!strncasecmp(ret, "speed", 4)) {
+				char *p;
 			
-			if ((p = strchr(ret, ':'))) {
-				p++;
-				if (*p == '+' || *p == '-') {
-					int step;
-					if (!(step = atoi(p))) {
-						step = 1;
+				if ((p = strchr(ret, ':'))) {
+					p++;
+					if (*p == '+' || *p == '-') {
+						int step;
+						if (!(step = atoi(p))) {
+							step = 1;
+						}
+						fh->speed += step;
+					} else {
+						int speed = atoi(p);
+						fh->speed = speed;
 					}
-					fh->speed += step;
+					return SWITCH_STATUS_SUCCESS;
+				}
+			
+				return SWITCH_STATUS_FALSE;
+			} else if (!strcasecmp(ret, "pause")) {
+				if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
+					switch_clear_flag(fh, SWITCH_FILE_PAUSE);
 				} else {
-					int speed = atoi(p);
-					fh->speed = speed;
+					switch_set_flag(fh, SWITCH_FILE_PAUSE);
 				}
 				return SWITCH_STATUS_SUCCESS;
-			}
-			
-			return SWITCH_STATUS_FALSE;
-		} else if (!strcasecmp(ret, "pause")) {
-			if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
-				switch_clear_flag(fh, SWITCH_FILE_PAUSE);
-			} else {
-				switch_set_flag(fh, SWITCH_FILE_PAUSE);
-			}
-			return SWITCH_STATUS_SUCCESS;
-		} else if (!strcasecmp(ret, "restart")) {
-			unsigned int pos = 0;
-			fh->speed = 0;
-			switch_core_file_seek(fh, &pos, 0, SEEK_SET);
-			return SWITCH_STATUS_SUCCESS;
-		} else if (!strncasecmp(ret, "seek", 4)) {
-			switch_codec_t *codec;
-			unsigned int samps = 0;
-			unsigned int pos = 0;
-			char *p;
-			codec = switch_core_session_get_read_codec(jss->session);
+			} else if (!strcasecmp(ret, "restart")) {
+				unsigned int pos = 0;
+				fh->speed = 0;
+				switch_core_file_seek(fh, &pos, 0, SEEK_SET);
+				return SWITCH_STATUS_SUCCESS;
+			} else if (!strncasecmp(ret, "seek", 4)) {
+				switch_codec_t *codec;
+				unsigned int samps = 0;
+				unsigned int pos = 0;
+				char *p;
+				codec = switch_core_session_get_read_codec(jss->session);
 
-			if ((p = strchr(ret, ':'))) {
-				p++;
-				if (*p == '+' || *p == '-') {
-					int step;
-					if (!(step = atoi(p))) {
-						step = 1000;
-					}
-					if (step > 0) {
-						samps = step * (codec->implementation->samples_per_second / 1000);
-						switch_core_file_seek(fh, &pos, samps, SEEK_CUR);		
+				if ((p = strchr(ret, ':'))) {
+					p++;
+					if (*p == '+' || *p == '-') {
+						int step;
+						if (!(step = atoi(p))) {
+							step = 1000;
+						}
+						if (step > 0) {
+							samps = step * (codec->implementation->samples_per_second / 1000);
+							switch_core_file_seek(fh, &pos, samps, SEEK_CUR);		
+						} else {
+							samps = step * (codec->implementation->samples_per_second / 1000);
+							switch_core_file_seek(fh, &pos, fh->pos - samps, SEEK_SET);
+						}
 					} else {
-						samps = step * (codec->implementation->samples_per_second / 1000);
-						switch_core_file_seek(fh, &pos, fh->pos - samps, SEEK_SET);
+						samps = atoi(p) * (codec->implementation->samples_per_second / 1000);
+						switch_core_file_seek(fh, &pos, samps, SEEK_SET);
 					}
-				} else {
-					samps = atoi(p) * (codec->implementation->samples_per_second / 1000);
-					switch_core_file_seek(fh, &pos, samps, SEEK_SET);
 				}
+
+				return SWITCH_STATUS_SUCCESS;
 			}
 
-			return SWITCH_STATUS_SUCCESS;
-		}
-
-		if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
-			return SWITCH_STATUS_SUCCESS;
-		}
+			if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
+				return SWITCH_STATUS_SUCCESS;
+			}
 	
-		if (ret) {
-			switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer));
+			if (ret) {
+				switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer));
+			}
 		}
+
+		return SWITCH_STATUS_FALSE;
 	}
+		break;
+	default:
+		break;
+	}
+	return SWITCH_STATUS_SUCCESS;
 
-	return SWITCH_STATUS_FALSE;
 }
 
-
-static switch_status_t js_record_dtmf_callback(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
+static switch_status_t js_record_dtmf_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 {
-	char code[2048];
-	struct dtmf_callback_state *cb_state = buf;
-	struct js_session *jss = cb_state->session_state;
-	switch_file_handle_t *fh = cb_state->extra;
-	jsval rval;
-	char *ret;
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF: {
+		char *dtmf = (char *) input;
+		char code[2048];
+		struct dtmf_callback_state *cb_state = buf;
+		struct js_session *jss = cb_state->session_state;
+		switch_file_handle_t *fh = cb_state->extra;
+		jsval rval;
+		char *ret;
 	
-	if (!jss) {
-		return SWITCH_STATUS_FALSE;
-	}
-	
-	if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) {
-		char *d;
-		if (!cb_state->digit_count) {
-			cb_state->digit_count = atoi(cb_state->code_buffer);
+		if (!jss) {
+			return SWITCH_STATUS_FALSE;
 		}
-
-		for(d = dtmf; *d; d++) {
-			cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d;
-			if ((cb_state->ret_buffer_len > cb_state->digit_count)||
-				(cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))||
-				(cb_state->ret_buffer_len >= cb_state->digit_count)
-				) {
-				return SWITCH_STATUS_FALSE;
+	
+		if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) {
+			char *d;
+			if (!cb_state->digit_count) {
+				cb_state->digit_count = atoi(cb_state->code_buffer);
 			}
-		}
-		return SWITCH_STATUS_SUCCESS;
-	} else {
-		snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf);
-		eval_some_js(code, jss->cx, jss->obj, &rval);
-		ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval));
 
-		if (!strcasecmp(ret, "pause")) {
-			if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
-				switch_clear_flag(fh, SWITCH_FILE_PAUSE);
-			} else {
-				switch_set_flag(fh, SWITCH_FILE_PAUSE);
+			for(d = dtmf; *d; d++) {
+				cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d;
+				if ((cb_state->ret_buffer_len > cb_state->digit_count)||
+					(cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))||
+					(cb_state->ret_buffer_len >= cb_state->digit_count)
+					) {
+					return SWITCH_STATUS_FALSE;
+				}
 			}
 			return SWITCH_STATUS_SUCCESS;
-		} else if (!strcasecmp(ret, "restart")) {
-			unsigned int pos = 0;
-			fh->speed = 0;
-			switch_core_file_seek(fh, &pos, 0, SEEK_SET);
-			return SWITCH_STATUS_SUCCESS;
-		}
+		} else {
+			snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf);
+			eval_some_js(code, jss->cx, jss->obj, &rval);
+			ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval));
 
-		if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
-			return SWITCH_STATUS_SUCCESS;
-		}
+			if (!strcasecmp(ret, "pause")) {
+				if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
+					switch_clear_flag(fh, SWITCH_FILE_PAUSE);
+				} else {
+					switch_set_flag(fh, SWITCH_FILE_PAUSE);
+				}
+				return SWITCH_STATUS_SUCCESS;
+			} else if (!strcasecmp(ret, "restart")) {
+				unsigned int pos = 0;
+				fh->speed = 0;
+				switch_core_file_seek(fh, &pos, 0, SEEK_SET);
+				return SWITCH_STATUS_SUCCESS;
+			}
+
+			if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
+				return SWITCH_STATUS_SUCCESS;
+			}
 	
-		if (ret) {
-			switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer));
+			if (ret) {
+				switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer));
+			}
 		}
+		return SWITCH_STATUS_FALSE;
 	}
+		break;
+	default:
+		break;
+	}
 
-	return SWITCH_STATUS_FALSE;
+	return SWITCH_STATUS_SUCCESS;
 }
 
 
-static switch_status_t js_speak_dtmf_callback(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
+static switch_status_t js_speak_dtmf_callback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 {
-	char code[2048];
-	struct dtmf_callback_state *cb_state = buf;
-	struct js_session *jss = cb_state->session_state;
-	jsval rval;
-	char *ret;
+	switch (itype) {
+	case SWITCH_INPUT_TYPE_DTMF: {
+		char *dtmf = (char *) input;
+		char code[2048];
+		struct dtmf_callback_state *cb_state = buf;
+		struct js_session *jss = cb_state->session_state;
+		jsval rval;
+		char *ret;
 	
-	if (!jss) {
-		return SWITCH_STATUS_FALSE;
-	}
-	
-	if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) {
-		char *d;
-		if (!cb_state->digit_count) {
-			cb_state->digit_count = atoi(cb_state->code_buffer);
+		if (!jss) {
+			return SWITCH_STATUS_FALSE;
 		}
-
-		for(d = dtmf; *d; d++) {
-			cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d;
-			if ((cb_state->ret_buffer_len > cb_state->digit_count)||
-				(cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))||
-				(cb_state->ret_buffer_len >= cb_state->digit_count)
-				) {
-				return SWITCH_STATUS_FALSE;
+	
+		if (cb_state->digit_count || (cb_state->code_buffer[0] > 47 && cb_state->code_buffer[0] < 58)) {
+			char *d;
+			if (!cb_state->digit_count) {
+				cb_state->digit_count = atoi(cb_state->code_buffer);
 			}
-		}
-		return SWITCH_STATUS_SUCCESS;
-	} else {
-		snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf);
-		eval_some_js(code, jss->cx, jss->obj, &rval);
-		ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval));
 
-		if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
+			for(d = dtmf; *d; d++) {
+				cb_state->ret_buffer[cb_state->ret_buffer_len++] = *d;
+				if ((cb_state->ret_buffer_len > cb_state->digit_count)||
+					(cb_state->ret_buffer_len > sizeof(cb_state->ret_buffer))||
+					(cb_state->ret_buffer_len >= cb_state->digit_count)
+					) {
+					return SWITCH_STATUS_FALSE;
+				}
+			}
 			return SWITCH_STATUS_SUCCESS;
-		}
+		} else {
+			snprintf(code, sizeof(code), "~%s(\"%s\")", cb_state->code_buffer, dtmf);
+			eval_some_js(code, jss->cx, jss->obj, &rval);
+			ret = JS_GetStringBytes(JS_ValueToString(jss->cx, rval));
+
+			if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
+				return SWITCH_STATUS_SUCCESS;
+			}
 	
-		if (ret) {
-			switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer));
+			if (ret) {
+				switch_copy_string(cb_state->ret_buffer, ret, sizeof(cb_state->ret_buffer));
+			}
 		}
+
+		return SWITCH_STATUS_FALSE;
 	}
+		break;
+	default:
+		break;
+	}
 
-	return SWITCH_STATUS_FALSE;
+	return SWITCH_STATUS_SUCCESS;
+	
 }
 
 static JSBool session_recordfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
@@ -397,7 +426,7 @@
 	char *dtmf_callback = NULL;
 	void *bp = NULL;
 	int len = 0;
-	switch_dtmf_callback_function_t dtmf_func = NULL;
+	switch_input_callback_function_t dtmf_func = NULL;
 	struct dtmf_callback_state cb_state = {0};
 	switch_file_handle_t fh;
 
@@ -443,7 +472,7 @@
 	char *dtmf_callback = NULL;
 	void *bp = NULL;
 	int len = 0;
-	switch_dtmf_callback_function_t dtmf_func = NULL;
+	switch_input_callback_function_t dtmf_func = NULL;
 	struct dtmf_callback_state cb_state = {0};
 	switch_file_handle_t fh;
 
@@ -499,7 +528,7 @@
 	void *bp = NULL;
 	int len = 0;
 	struct dtmf_callback_state cb_state = {0};
-	switch_dtmf_callback_function_t dtmf_func = NULL;
+	switch_input_callback_function_t dtmf_func = NULL;
 
 	channel = switch_core_session_get_channel(jss->session);
 	assert(channel != NULL);
@@ -1804,6 +1833,8 @@
 		stream.end = stream.data;
 		stream.data_size = sizeof(retbuf);
 		switch_api_execute(cmd, arg, &stream);
+		stream.write_function = switch_console_stream_write;
+
 		*rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, retbuf));
 	} else {
 		*rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, ""));

Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c	(original)
+++ freeswitch/trunk/src/switch_core.c	Wed Jul 12 14:39:19 2006
@@ -307,7 +307,7 @@
 	return status;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, switch_event_t *event)
+SWITCH_DECLARE(switch_status_t) switch_core_session_event_send(char *uuid_str, switch_event_t **event)
 {
 	switch_core_session_t *session = NULL;
 	switch_status_t status = SWITCH_STATUS_FALSE;
@@ -1057,29 +1057,73 @@
 	return status;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_core_session_queue_event(switch_core_session_t *session, switch_event_t *event)
+
+SWITCH_DECLARE(switch_status_t) switch_core_session_receive_event(switch_core_session_t *session, switch_event_t **event)
 	 
 {
-	switch_io_event_hook_queue_event_t *ptr;
-	switch_status_t status = SWITCH_STATUS_FALSE, istatus = SWITCH_STATUS_FALSE;;
+	switch_io_event_hook_receive_event_t *ptr;
+	switch_status_t status = SWITCH_STATUS_FALSE;
 
 	assert(session != NULL);
-	if (session->endpoint_interface->io_routines->queue_event) {
-		status = session->endpoint_interface->io_routines->queue_event(session, event);
 
-		if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
-			for (ptr = session->event_hooks.queue_event; ptr; ptr = ptr->next) {
-				if ((istatus = ptr->queue_event(session, event)) != SWITCH_STATUS_SUCCESS) {
-					break;
+	/* Acquire a read lock on the session or forget it the channel is dead */
+	if (switch_thread_rwlock_tryrdlock(session->rwlock) == SWITCH_STATUS_SUCCESS) {
+		if (switch_channel_get_state(session->channel) < CS_HANGUP) {
+			if (session->endpoint_interface->io_routines->receive_event) {
+				status = session->endpoint_interface->io_routines->receive_event(session, *event);
+			} 
+	
+			if (status == SWITCH_STATUS_SUCCESS) {
+				for (ptr = session->event_hooks.receive_event; ptr; ptr = ptr->next) {
+					if ((status = ptr->receive_event(session, *event)) != SWITCH_STATUS_SUCCESS) {
+						break;
+					}
 				}
 			}
-		}
-		
-		if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) {
-			if (!session->event_queue) {
-				switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
+
+			if (status == SWITCH_STATUS_BREAK) {
+				status = SWITCH_STATUS_SUCCESS;
 			}
-			switch_queue_push(session->event_queue, event);
+
+			if (status == SWITCH_STATUS_SUCCESS) {
+				switch_event_destroy(event);
+			}
+		}
+		switch_thread_rwlock_unlock(session->rwlock);
+	}
+	
+	return status;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_session_queue_event(switch_core_session_t *session, switch_event_t **event)
+	 
+{
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+	assert(session != NULL);
+
+	if (!session->event_queue) {
+		switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
+	}
+
+	if ((status = (switch_status_t) switch_queue_push(session->event_queue, *event) == SWITCH_STATUS_SUCCESS)) {
+		*event = NULL;
+	}	
+	
+	return status;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_event(switch_core_session_t *session, switch_event_t **event)
+	 
+{
+	switch_status_t status = SWITCH_STATUS_FALSE;
+	void *pop;
+
+	assert(session != NULL);
+	
+	if (session->event_queue) {
+		if ((status = (switch_status_t) switch_queue_trypop(session->event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
+			*event = (switch_event_t *) pop;
 		}
 	}
 

Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c	(original)
+++ freeswitch/trunk/src/switch_ivr.c	Wed Jul 12 14:39:19 2006
@@ -36,7 +36,7 @@
 
 
 SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_session_t *session,
-																 switch_dtmf_callback_function_t dtmf_callback,
+																 switch_input_callback_function_t input_callback,
 																 void *buf,
 																 unsigned int buflen)
 {
@@ -46,19 +46,26 @@
 	channel = switch_core_session_get_channel(session);
     assert(channel != NULL);
 
-	if (!dtmf_callback) {
+	if (!input_callback) {
 		return SWITCH_STATUS_GENERR;
 	}
 
 	while(switch_channel_ready(channel)) {
 		switch_frame_t *read_frame;
+		switch_event_t *event;
+
 		char dtmf[128];
 
 		if (switch_channel_has_dtmf(channel)) {
 			switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
-			status = dtmf_callback(session, dtmf, buf, buflen);
+			status = input_callback(session, dtmf, SWITCH_INPUT_TYPE_DTMF, buf, buflen);
 		}
 
+		if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
+			status = input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, buf, buflen);			
+			switch_event_destroy(&event);
+		}
+
 		if (status != SWITCH_STATUS_SUCCESS) {
 			break;
 		}
@@ -156,7 +163,7 @@
 SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *session, 
 													 switch_file_handle_t *fh,
 													 char *file,
-													 switch_dtmf_callback_function_t dtmf_callback,
+													 switch_input_callback_function_t input_callback,
 													 void *buf,
 													 unsigned int buflen)
 {
@@ -216,22 +223,31 @@
 
 	while(switch_channel_ready(channel)) {
 		switch_size_t len;
+		switch_event_t *event;
 
-		if (dtmf_callback || buf) {
+		if (input_callback || buf) {
 			/*
 			  dtmf handler function you can hook up to be executed when a digit is dialed during playback 
 			  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 			*/
 			if (switch_channel_has_dtmf(channel)) {
 				switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
-				if (dtmf_callback) {
-					status = dtmf_callback(session, dtmf, buf, buflen);
+				if (input_callback) {
+					status = input_callback(session, dtmf, SWITCH_INPUT_TYPE_DTMF, buf, buflen);
 				} else {
 					switch_copy_string((char *)buf, dtmf, buflen);
 					status = SWITCH_STATUS_BREAK;
 				}
 			}
 
+			if (input_callback) {
+				if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
+					status = input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, buf, buflen);			
+					switch_event_destroy(&event);
+				}
+			}
+
+
 			if (status != SWITCH_STATUS_SUCCESS) {
 				break;
 			}
@@ -257,7 +273,7 @@
 												   switch_file_handle_t *fh,
 												   char *file,
 												   char *timer_name,
-												   switch_dtmf_callback_function_t dtmf_callback,
+												   switch_input_callback_function_t input_callback,
 												   void *buf,
 												   unsigned int buflen)
 {
@@ -352,21 +368,29 @@
 		int done = 0;
 		int do_speed = 1;
 		int last_speed = -1;
+		switch_event_t *event;
 
-		if (dtmf_callback || buf) {
+		if (input_callback || buf) {
 			/*
 			  dtmf handler function you can hook up to be executed when a digit is dialed during playback 
 			  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
 			*/
 			if (switch_channel_has_dtmf(channel)) {
 				switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
-				if (dtmf_callback) {
-					status = dtmf_callback(session, dtmf, buf, buflen);
+				if (input_callback) {
+					status = input_callback(session, dtmf, SWITCH_INPUT_TYPE_DTMF, buf, buflen);
 				} else {
 					switch_copy_string((char *)buf, dtmf, buflen);
 					status = SWITCH_STATUS_BREAK;
 				}
 			}
+
+			if (input_callback) {
+				if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
+					status = input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, buf, buflen);			
+					switch_event_destroy(&event);
+				}
+			}
 			
 			if (status != SWITCH_STATUS_SUCCESS) {
 				done = 1;
@@ -501,7 +525,7 @@
 															 switch_speech_handle_t *sh,
 															 switch_codec_t *codec,
 															 switch_timer_t *timer,
-															 switch_dtmf_callback_function_t dtmf_callback,
+															 switch_input_callback_function_t input_callback,
 															 char *text,
 															 void *buf,
 															 unsigned int buflen)
@@ -559,8 +583,9 @@
 
 	ilen = len;
 	while(switch_channel_ready(channel)) {
+		switch_event_t *event;
 
-		if (dtmf_callback || buf) {
+		if (input_callback || buf) {
 			/*
 			  dtmf handler function you can hook up to be executed when a digit is dialed during playback 
 			  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
@@ -570,15 +595,22 @@
 					status = SWITCH_STATUS_BREAK;
 				} else {
 					switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
-					if (dtmf_callback) {
-						status = dtmf_callback(session, dtmf, buf, buflen);
+					if (input_callback) {
+						status = input_callback(session, dtmf, SWITCH_INPUT_TYPE_DTMF, buf, buflen);
 					} else {
 						switch_copy_string((char *)buf, dtmf, buflen);
 						status = SWITCH_STATUS_BREAK;
 					}
 				}
 			}
-			
+
+			if (input_callback) {
+				if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
+					status = input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, buf, buflen);			
+					switch_event_destroy(&event);
+				}
+			}
+
 			if (status != SWITCH_STATUS_SUCCESS) {
 				done = 1;
 				break;
@@ -679,7 +711,7 @@
 													  char *voice_name,
 													  char *timer_name,
 													  uint32_t rate,
-													  switch_dtmf_callback_function_t dtmf_callback,
+													  switch_input_callback_function_t input_callback,
 													  char *text,
 													  void *buf,
 													  unsigned int buflen)
@@ -761,7 +793,7 @@
 		}
 	}
 
-	switch_ivr_speak_text_handle(session, &sh, &codec, timer_name ? &timer : NULL, dtmf_callback, text, buf, buflen);
+	switch_ivr_speak_text_handle(session, &sh, &codec, timer_name ? &timer : NULL, input_callback, text, buf, buflen);
 	flags = 0;	
 	switch_core_speech_close(&sh, &flags);
 	switch_core_codec_destroy(&codec);
@@ -790,7 +822,7 @@
 	switch_core_thread_session_t *his_thread, *data = obj;
 	int *stream_id_p;
 	int stream_id = 0, ans_a = 0, ans_b = 0;
-	switch_dtmf_callback_function_t dtmf_callback;
+	switch_input_callback_function_t input_callback;
 	switch_core_session_message_t msg = {0};
 	void *user_data;
 
@@ -804,7 +836,7 @@
 	session_b = data->objs[1];
 
 	stream_id_p = data->objs[2];
-	dtmf_callback = (switch_dtmf_callback_function_t) data->objs[3];
+	input_callback = (switch_input_callback_function_t) data->objs[3];
 	user_data = data->objs[4];
 	his_thread = data->objs[5];
 
@@ -824,6 +856,7 @@
 	while (data->running > 0 && his_thread->running > 0) {
 		switch_channel_state_t b_state = switch_channel_get_state(chan_b);
 		switch_status_t status;
+		switch_event_t *event;
 
 		switch (b_state) {
 		case CS_HANGUP:
@@ -862,14 +895,26 @@
 				switch_channel_dequeue_dtmf(chan_a, dtmf, sizeof(dtmf));
 				switch_core_session_send_dtmf(session_b, dtmf);
 
-				if (dtmf_callback) {
-					if (dtmf_callback(session_a, dtmf, user_data, 0) != SWITCH_STATUS_SUCCESS) {
+				if (input_callback) {
+					if (input_callback(session_a, dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0) != SWITCH_STATUS_SUCCESS) {
 						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
 						data->running = -1;
 						break;
 					}
 				}
-			} 
+			}
+
+			if (switch_core_session_dequeue_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
+				if (input_callback) {
+					status = input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
+				}
+
+				if (switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
+					switch_event_destroy(&event);
+				}
+
+			}
+ 
 		}
 
 		/* read audio from 1 channel and write it to the other */
@@ -973,7 +1018,7 @@
 SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_session_t *session, 
 															   switch_core_session_t *peer_session,
 															   unsigned int timelimit,
-															   switch_dtmf_callback_function_t dtmf_callback,
+															   switch_input_callback_function_t input_callback,
 															   void *session_data,
 															   void *peer_session_data)
 															   
@@ -1002,7 +1047,7 @@
 	other_audio_thread->objs[0] = session;
 	other_audio_thread->objs[1] = peer_session;
 	other_audio_thread->objs[2] = &stream_id;
-	other_audio_thread->objs[3] = (void *) dtmf_callback;
+	other_audio_thread->objs[3] = (void *) input_callback;
 	other_audio_thread->objs[4] = session_data;
 	other_audio_thread->objs[5] = this_audio_thread;
 	other_audio_thread->running = 5;
@@ -1010,7 +1055,7 @@
 	this_audio_thread->objs[0] = peer_session;
 	this_audio_thread->objs[1] = session;
 	this_audio_thread->objs[2] = &stream_id;
-	this_audio_thread->objs[3] = (void *) dtmf_callback;
+	this_audio_thread->objs[3] = (void *) input_callback;
 	this_audio_thread->objs[4] = peer_session_data;
 	this_audio_thread->objs[5] = other_audio_thread;
 	this_audio_thread->running = 2;



More information about the Freeswitch-svn mailing list