[commit] r8065 - in freeswitch/trunk/src: . include mod/applications/mod_dptools mod/applications/mod_fifo
Author: anthm Date: Wed Apr 9 14:15:15 2008 New Revision: 8065 Modified: freeswitch/trunk/src/include/switch_ivr.h freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c freeswitch/trunk/src/switch_ivr_async.c freeswitch/trunk/src/switch_ivr_bridge.c freeswitch/trunk/src/switch_ivr_play_say.c Log: add soft_hold Modified: freeswitch/trunk/src/include/switch_ivr.h ============================================================================== --- freeswitch/trunk/src/include/switch_ivr.h (original) +++ freeswitch/trunk/src/include/switch_ivr.h Wed Apr 9 14:15:15 2008 @@ -750,6 +750,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_bind_dtmf_meta_session(switch_core_session_t *session, uint32_t key, switch_bool_t dial_b, switch_bool_t exec_b, const char *app); SWITCH_DECLARE(switch_status_t) switch_ivr_unbind_dtmf_meta_session(switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *session, const char *unhold_key, const char *moh_a, const char *moh_b); /** @} */ Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original) +++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Wed Apr 9 14:15:15 2008 @@ -79,6 +79,21 @@ } } +#define SOFT_HOLD_SYNTAX "<unhold key> [<moh_a>] [<moh_b>]" +SWITCH_STANDARD_APP(soft_hold_function) +{ + char *argv[3] = { 0 }; + int argc; + char *lbuf = NULL; + + if (!switch_strlen_zero(data) && (lbuf = switch_core_session_strdup(session, data)) + && (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) { + switch_ivr_soft_hold(session, argv[0], argv[1], argv[2]); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Usage: %s\n", SOFT_HOLD_SYNTAX); + } +} + #define BIND_SYNTAX "<key> [a|b] [a|b] <app>" SWITCH_STANDARD_APP(dtmf_bind_function) { @@ -1816,6 +1831,7 @@ SWITCH_ADD_APP(app_interface, "sched_broadcast", SCHED_BROADCAST_DESCR, SCHED_BROADCAST_DESCR, sched_broadcast_function, "[+]<time> <path> [aleg|bleg|both]", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "sched_transfer", SCHED_TRANSF_DESCR, SCHED_TRANSF_DESCR, sched_transfer_function, "[+]<time> <extension> <dialplan> <context>", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "execute_extension", "Execute an extension", "Execute an extension", exe_function, EXE_SYNTAX, SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "soft_hold", "Put a bridged channel on hold", "Put a bridged channel on hold", soft_hold_function, SOFT_HOLD_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "bind_meta_app", "Bind a key to an application", "Bind a key to an application", dtmf_bind_function, BIND_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "intercept", "intercept", "intercept", intercept_function, INTERCEPT_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_NONE); Modified: freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c (original) +++ freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c Wed Apr 9 14:15:15 2008 @@ -53,6 +53,8 @@ typedef struct fifo_node fifo_node_t; + + static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) { switch_core_session_t *bleg = (switch_core_session_t *) buf; @@ -61,13 +63,31 @@ case SWITCH_INPUT_TYPE_DTMF: { switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + switch_channel_t *bchan = switch_core_session_get_channel(bleg); + switch_channel_t *channel = switch_core_session_get_channel(session); + if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_ORIGINATOR)) { + if (dtmf->digit == '*') { + switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING); + return SWITCH_STATUS_BREAK; + } else if (dtmf->digit == '0') { + const char *moh_a = NULL, *moh_b = NULL; + + if (!(moh_b = switch_channel_get_variable(bchan, "fifo_music"))) { + moh_b = switch_channel_get_variable(bchan, "hold_music"); + } + + if (!(moh_a = switch_channel_get_variable(channel, "fifo_hold_music"))) { + if (!(moh_a = switch_channel_get_variable(channel, "fifo_music"))) { + moh_a = switch_channel_get_variable(channel, "hold_music"); + } + } + + switch_ivr_soft_hold(session, "0", moh_a, moh_b); - if (dtmf->digit == '*') { - if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_ORIGINATOR)) { - switch_channel_hangup(switch_core_session_get_channel(bleg), SWITCH_CAUSE_NORMAL_CLEARING); - return SWITCH_STATUS_BREAK; - } - } + + return SWITCH_STATUS_IGNORE; + } + } } break; default: Modified: freeswitch/trunk/src/switch_ivr_async.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_async.c (original) +++ freeswitch/trunk/src/switch_ivr_async.c Wed Apr 9 14:15:15 2008 @@ -1802,8 +1802,8 @@ channel = switch_core_session_get_channel(session); if ((switch_channel_test_flag(channel, CF_EVENT_PARSE))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Channel [%s] already broadcasting...broadcast aborted\n", - switch_channel_get_name(channel)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Channel [%s][%s] already broadcasting...broadcast aborted\n", + switch_channel_get_name(channel), path); switch_core_session_rwunlock(session); return SWITCH_STATUS_FALSE; } Modified: freeswitch/trunk/src/switch_ivr_bridge.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_bridge.c (original) +++ freeswitch/trunk/src/switch_ivr_bridge.c Wed Apr 9 14:15:15 2008 @@ -189,7 +189,7 @@ if (cb_status == SWITCH_STATUS_IGNORE) { send_dtmf = 0; - } if (cb_status != SWITCH_STATUS_SUCCESS) { + } else if (cb_status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a)); switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK); goto end_of_bridge_loop; Modified: freeswitch/trunk/src/switch_ivr_play_say.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_play_say.c (original) +++ freeswitch/trunk/src/switch_ivr_play_say.c Wed Apr 9 14:15:15 2008 @@ -1746,6 +1746,88 @@ return status; } + +static switch_status_t hold_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) +{ + char *stop_key = (char *) buf; + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + if (dtmf->digit == *stop_key) { + return SWITCH_STATUS_BREAK; + } + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *session, const char *unhold_key, const char *moh_a, const char *moh_b) +{ + switch_channel_t *channel, *other_channel; + switch_core_session_t *other_session; + const char *other_uuid, *moh = NULL; + int moh_br = 0; + switch_input_args_t args = { 0 }; + args.input_callback = hold_on_dtmf; + args.buf = (void *) unhold_key; + args.buflen = strlen(unhold_key); + + switch_assert(session != NULL); + channel = switch_core_session_get_channel(session); + switch_assert(channel != NULL); + + + if ((other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { + if ((other_session = switch_core_session_locate(other_uuid))) { + other_channel = switch_core_session_get_channel(other_session); + + if (moh_b) { + moh = moh_b; + } else { + moh = switch_channel_get_variable(other_channel, "hold_music"); + } + + if (!switch_strlen_zero(moh) && strcasecmp(moh, "silence") && !switch_channel_test_flag(other_channel, CF_BROADCAST)) { + switch_ivr_broadcast(other_uuid, moh, SMF_ECHO_ALEG | SMF_LOOP); + moh_br++; + } + + if (moh_a) { + moh = moh_a; + } else { + moh = switch_channel_get_variable(channel, "hold_music"); + } + + if (!switch_strlen_zero(moh) && strcasecmp(moh, "silence")) { + switch_ivr_play_file(session, NULL, moh, &args); + } else { + switch_ivr_collect_digits_callback(session, &args, 0); + } + + if (moh_br) { + switch_channel_stop_broadcast(other_channel); + } + + switch_core_session_rwunlock(other_session); + + + return SWITCH_STATUS_SUCCESS; + } + + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Channel %s is not in a bridge\n", switch_channel_get_name(channel)); + return SWITCH_STATUS_FALSE; + +} + + /* For Emacs: * Local Variables: * mode:c
participants (1)
-
Freeswitch SVN