diff --git a/src/include/switch_core.h b/src/include/switch_core.h index e4c6b79ca7..1ff6263798 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -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 diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 15f13bb07b..d663ebb9ba 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -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); diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index f9fd792ff6..10f88e45c8 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -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 diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 0db6c0fd41..b120b0a247 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -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); diff --git a/src/mod/applications/mod_ivrtest/mod_ivrtest.c b/src/mod/applications/mod_ivrtest/mod_ivrtest.c index aad96294ac..1ea827bd90 100644 --- a/src/mod/applications/mod_ivrtest/mod_ivrtest.c +++ b/src/mod/applications/mod_ivrtest/mod_ivrtest.c @@ -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) diff --git a/src/mod/applications/mod_playback/mod_playback.c b/src/mod/applications/mod_playback/mod_playback.c index 78898bff97..2baeed8306 100644 --- a/src/mod/applications/mod_playback/mod_playback.c +++ b/src/mod/applications/mod_playback/mod_playback.c @@ -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; diff --git a/src/mod/applications/mod_rss/mod_rss.c b/src/mod/applications/mod_rss/mod_rss.c index 25fc52fd26..1ea236ddd5 100644 --- a/src/mod/applications/mod_rss/mod_rss.c +++ b/src/mod/applications/mod_rss/mod_rss.c @@ -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(*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_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; - } - 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); + 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; } - + break; + default: + break; + } return SWITCH_STATUS_SUCCESS; } - static void rss_function(switch_core_session_t *session, char *data) { switch_channel_t *channel; diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index e11c4a13f8..2b4cf01906 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -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; diff --git a/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c b/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c index f89d341d8a..954d2630bc 100644 --- a/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c +++ b/src/mod/event_handlers/mod_xmpp_event/mod_xmpp_event.c @@ -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; diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index be31afda52..ce1c6db27a 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -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 (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 (!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); + } 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; + } + + 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)); + } + } + + return SWITCH_STATUS_FALSE; + } + break; + default: + break; + } + return SWITCH_STATUS_SUCCESS; + +} + +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) +{ + 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); + } + + 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 (!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_record_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; - 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; + jsval rval; + char *ret; - if (!jss) { + 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; + } + } + 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)); + } + } + 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; - } - } - 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); - } - 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)); - } + break; + default: + break; } - return SWITCH_STATUS_FALSE; -} - - -static switch_status_t js_speak_dtmf_callback(switch_core_session_t *session, char *dtmf, 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; + return SWITCH_STATUS_SUCCESS; - 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; - } - } - 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)); - } - } - - return SWITCH_STATUS_FALSE; } 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, "")); diff --git a/src/switch_core.c b/src/switch_core.c index d0fd81ee39..6c579ad7d9 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -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; } - 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; } } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index f46b524998..7eac7403d5 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -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;