]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
rearrange the furnature
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 12 Jul 2006 18:39:19 +0000 (18:39 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 12 Jul 2006 18:39:19 +0000 (18:39 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1846 d0543943-73ff-0310-b7d9-9358b9ac24b2

12 files changed:
src/include/switch_core.h
src/include/switch_ivr.h
src/include/switch_module_interfaces.h
src/include/switch_types.h
src/mod/applications/mod_ivrtest/mod_ivrtest.c
src/mod/applications/mod_playback/mod_playback.c
src/mod/applications/mod_rss/mod_rss.c
src/mod/endpoints/mod_dingaling/mod_dingaling.c
src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c
src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
src/switch_core.c
src/switch_ivr.c

index e4c6b79ca703188156ecf8fdebe48ca590eb6bb0..1ff6263798743024dd696adc0304d2ee3192f11e 100644 (file)
@@ -335,7 +335,15 @@ SWITCH_DECLARE (switch_status_t) switch_core_session_message_send(char *uuid_str
   \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
@@ -433,7 +441,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_
   \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
index 15f13bb07b0db7086251e954cb19fa105e67f734..d663ebb9ba4122faaa4d8aa5dd95265c8daef766 100644 (file)
@@ -59,7 +59,7 @@ BEGIN_EXTERN_C
   \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_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                                                                                                   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_play_file(switch_core_session_t *sess
 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_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
                                                              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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
                                                                                                          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_speak_text(switch_core_session_t *ses
 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);
 
index f9fd792ff65da831036b56aa85d202ba02c540ea..10f88e45c82ded2b8a0e7dff67c6af0d5552cd0e 100644 (file)
@@ -93,10 +93,10 @@ struct switch_io_event_hook_receive_message {
 };
 
 /*! \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 @@ struct switch_io_event_hooks {
        /*! 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 @@ struct switch_io_routines {
        /*! 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
index 0db6c0fd4141485c3578fdc6306a7c3a6e15e5e5..b120b0a2477bf24a5b416561525916227fcb34ad 100644 (file)
@@ -573,6 +573,10 @@ typedef enum {
        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_config switch_config_t;
 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_state_handler_t)(switch_core_session_t *);
 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 switch_status_t (*switch_send_dtmf_hook_t)(switch_core_session_t *, char
 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);
index aad96294acea9b949f5040fef97cd62855b0981e..1ea827bd901d77d49540f2764c7c1169d2dcfcbc 100644 (file)
@@ -39,16 +39,23 @@ static const char modname[] = "mod_ivrtest";
   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 void dirtest_function(switch_core_session_t *session, char *data)
 
 }
 
-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)
index 78898bff972bdf5d2c0ab36d1d0ec4c35ed6c5fc..2baeed83060d7a152765131dfc17cb7a830b44ab 100644 (file)
@@ -37,12 +37,22 @@ static const char modname[] = "mod_playback";
   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;
index 25fc52fd2606d7916c33d7d663e05717feb79c19..1ea236ddd51e92dcd1fa2df55ad1c2728cf3f16f 100644 (file)
@@ -85,69 +85,75 @@ static uint32_t match_count(char *str, uint32_t max)
   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;
+       default:
                break;
-       case '0':
-               switch_set_flag(dtb, SFLAG_INSTRUCT);
-               return SWITCH_STATUS_BREAK;
        }
-
        return SWITCH_STATUS_SUCCESS;
 }
 
-
 static void rss_function(switch_core_session_t *session, char *data)
 {
        switch_channel_t *channel;
index e11c4a13f8f19b54cc44713b60c5a7247b2405be..2b4cf01906a33ea0cd4cad584ae2acacfbc0626c 100644 (file)
@@ -1509,7 +1509,9 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                        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;
 
index f89d341d8ae2736bf1e69befbb2a0f2508f1b482..954d2630bc68fb3e6bc04acf22a0afd41ffd3749 100644 (file)
@@ -239,6 +239,7 @@ static int on_msg(void *user_data, ikspak * pak)
        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;
index be31afda529ca0e80bd63e3851fa0538ceab5454..ce1c6db27abd79ae01827d7de4ce26c89df5c4af 100644 (file)
@@ -175,218 +175,247 @@ static switch_status_t init_js(void)
        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 (!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;
+               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 (!strncasecmp(ret, "speed", 4)) {
-                       char *p;
+                       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 (!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);
-
-                       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 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);               
+                                               } 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 (!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;
+               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 (!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;
+               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 @@ static JSBool session_recordfile(JSContext *cx, JSObject *obj, uintN argc, jsval
        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 @@ static JSBool session_streamfile(JSContext *cx, JSObject *obj, uintN argc, jsval
        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 @@ static JSBool session_speak(JSContext *cx, JSObject *obj, uintN argc, jsval *arg
        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 @@ static JSBool js_api_execute(JSContext *cx, JSObject *obj, uintN argc, jsval *ar
                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, ""));
index d0fd81ee39c00df6258709a400bf01b5401f2d4e..6c579ad7d9d537f552c40cfca2253a97f5b04fde 100644 (file)
@@ -307,7 +307,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_message_send(char *uuid_str,
        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 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_
        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;
+                       }
+
+                       if (status == SWITCH_STATUS_SUCCESS) {
+                               switch_event_destroy(event);
                        }
-                       switch_queue_push(session->event_queue, 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;
                }
        }
 
index f46b52499874aed99b080dc77a4d285d24b5f78e..7eac7403d50571d4cd4842574e884cafb12a22cc 100644 (file)
@@ -36,7 +36,7 @@ static const switch_state_handler_table_t audio_bridge_peer_state_handlers;
 
 
 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,17 +46,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s
        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) {
@@ -156,7 +163,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_count(switch_core_sess
 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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 
        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_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                                                                                                   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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                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_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
                                                                                                                         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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
 
        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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
                                        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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
                                                                                                          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_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
                }
        }
 
-       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 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
        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 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
        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 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
        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 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
                                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 @@ static const switch_state_handler_table_t audio_bridge_peer_state_handlers = {
 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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
        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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
        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;